Merge "rust: set ANDROID_RUST_VERSION based on prebuilts"
diff --git a/android/Android.bp b/android/Android.bp
index c072ac2..49d5b91 100644
--- a/android/Android.bp
+++ b/android/Android.bp
@@ -36,6 +36,7 @@
"bazel_handler.go",
"bazel_paths.go",
"config.go",
+ "config_bp2build.go",
"csuite_config.go",
"deapexer.go",
"defaults.go",
@@ -96,6 +97,7 @@
"bazel_handler_test.go",
"bazel_test.go",
"config_test.go",
+ "config_bp2build_test.go",
"csuite_config_test.go",
"defaults_test.go",
"depset_test.go",
diff --git a/android/apex.go b/android/apex.go
index cf1bcfe..b127f74 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -113,9 +113,6 @@
for _, sdk := range i.RequiredSdks {
name += "_" + sdk.Name + "_" + sdk.Version
}
- if i.UsePlatformApis {
- name += "_private"
- }
return name
}
@@ -546,10 +543,9 @@
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
+ // Platform APIs is allowed for this module only when all APEXes containing
+ // the module are with `use_platform_apis: true`.
+ merged[index].UsePlatformApis = 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 60a639b..1e2f3bd 100644
--- a/android/apex_test.go
+++ b/android/apex_test.go
@@ -118,17 +118,30 @@
},
},
{
- name: "don't merge different UsePlatformApis",
+ name: "merge different UsePlatformApis but don't allow using platform api",
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},
+ {"apex10000", FutureApiLevel, false, false, nil, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
},
wantAliases: [][2]string{
- {"bar", "apex10000_private"},
+ {"bar", "apex10000"},
+ {"foo", "apex10000"},
+ },
+ },
+ {
+ name: "merge same UsePlatformApis and allow using platform api",
+ in: []ApexInfo{
+ {"foo", FutureApiLevel, false, true, nil, []string{"foo"}, []string{"foo"}, nil, NotForPrebuiltApex},
+ {"bar", FutureApiLevel, false, true, nil, []string{"bar"}, []string{"bar"}, nil, NotForPrebuiltApex},
+ },
+ wantMerged: []ApexInfo{
+ {"apex10000", FutureApiLevel, false, true, nil, []string{"bar", "foo"}, []string{"bar", "foo"}, nil, NotForPrebuiltApex},
+ },
+ wantAliases: [][2]string{
+ {"bar", "apex10000"},
{"foo", "apex10000"},
},
},
diff --git a/android/api_levels.go b/android/api_levels.go
index 27a3b7f..8163894 100644
--- a/android/api_levels.go
+++ b/android/api_levels.go
@@ -19,6 +19,7 @@
"fmt"
"strconv"
+ "android/soong/bazel"
"android/soong/starlark_fmt"
)
@@ -393,10 +394,10 @@
}
func StarlarkApiLevelConfigs(config Config) string {
- return fmt.Sprintf(`# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.
+ return fmt.Sprintf(bazel.GeneratedBazelFileWarning+`
_api_levels = %s
api_levels = _api_levels
`, printApiLevelsStarlarkDict(config),
)
-}
\ No newline at end of file
+}
diff --git a/android/bazel.go b/android/bazel.go
index af5de12..edf67d4 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -435,146 +435,103 @@
// Per-module denylist to always opt modules out of both bp2build and mixed builds.
bp2buildModuleDoNotConvertList = []string{
- "libnativehelper_compat_libc", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99
+ // cc bugs
+ "libsepol", // TODO(b/207408632): Unsupported case of .l sources in cc library rules
+ "libactivitymanager_aidl", // TODO(b/207426160): Unsupported use of aidl sources (via Dactivity_manager_procstate_aidl) in a cc_library
+ "gen-kotlin-build-file.py", // TODO(b/198619163) module has same name as source
+ "libgtest_ndk_c++", "libgtest_main_ndk_c++", // TODO(b/201816222): Requires sdk_version support.
+ "linkerconfig", "mdnsd", // TODO(b/202876379): has arch-variant static_executable
+ "linker", // TODO(b/228316882): cc_binary uses link_crt
+ "libdebuggerd", // TODO(b/228314770): support product variable-specific header_libs
+ "versioner", // TODO(b/228313961): depends on prebuilt shared library libclang-cpp_host as a shared library, which does not supply expected providers for a shared library
- "libart", // depends on unconverted modules: art_operator_srcs, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libcpu_features, libdexfile, libartpalette, libbacktrace, libnativebridge, libnativeloader, libsigchain, libunwindstack, libartbase, libprofile, cpp-define-generator-asm-support, apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, libstatssocket, heapprofd_client_api
- "libart-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libart-compiler, libdexfile, libprofile, libartbase, libbacktrace, libartbase-art-gtest
- "libart_headers", // depends on unconverted modules: art_libartbase_headers
- "libartd", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, libstatssocket, heapprofd_client_api, art_operator_srcs, libodrstatslog, libelffiled, art_cmdlineparser_headers, cpp-define-generator-definitions, libcpu_features, libdexfiled, libartpalette, libbacktrace, libnativebridge, libnativeloader, libsigchain, libunwindstack, libartbased, libprofiled, cpp-define-generator-asm-support
- "libartd-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libartd-compiler, libdexfiled, libprofiled, libartbased, libbacktrace, libartbased-art-gtest
- "libstatslog_art", // depends on unconverted modules: statslog_art.cpp, statslog_art.h
- "statslog_art.h", "statslog_art.cpp", // depends on unconverted modules: stats-log-api-gen
-
- "libandroid_runtime_lazy", // depends on unconverted modules: libbinder_headers
- "libcmd", // depends on unconverted modules: libbinder
-
- "libdexfile_support_static", // Depends on unconverted module: libdexfile_external_headers
- "libunwindstack_local", "libunwindstack_utils", "libc_malloc_debug", "libfdtrack", // Depends on unconverted module: libunwindstack
-
- "libdexfile_support", // TODO(b/210546943): Enabled based on product variables.
- "libdexfile_external_headers", // TODO(b/210546943): Enabled based on product variables.
-
- "libunwindstack", // Depends on unconverted module libdexfile_support.
- "libnativehelper_compat_libc++", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99
-
- "chkcon", "sefcontext_compile", // depends on unconverted modules: libsepol
-
- "libsepol", // TODO(b/207408632): Unsupported case of .l sources in cc library rules
-
- "gen-kotlin-build-file.py", // module has same name as source
-
- "libactivitymanager_aidl", // TODO(b/207426160): Depends on activity_manager_procstate_aidl, which is an aidl filegroup.
-
- "libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libgmock_ndk
- "libnativetesthelper_jni", "libgmock_main_ndk", "libgmock_ndk", // depends on unconverted module: libgtest_ndk_c++
-
- "statslog-framework-java-gen", "statslog.cpp", "statslog.h", "statslog.rs", "statslog_header.rs", // depends on unconverted modules: stats-log-api-gen
-
- "stats-log-api-gen", // depends on unconverted modules: libstats_proto_host, libprotobuf-cpp-full
-
- "libstatslog", // depends on unconverted modules: statslog.cpp, statslog.h, ...
-
- "cmd", // depends on unconverted module packagemanager_aidl-cpp, of unsupported type aidl_interface
- "servicedispatcher", // depends on unconverted module android.debug_aidl, of unsupported type aidl_interface
- "libutilscallstack", // depends on unconverted module libbacktrace
- "libbacktrace", // depends on unconverted module libunwindstack
- "libdebuggerd_handler", // depends on unconverted module libdebuggerd_handler_core
- "libdebuggerd_handler_core", "libdebuggerd_handler_fallback", // depends on unconverted module libdebuggerd
- "unwind_for_offline", // depends on unconverted module libunwindstack_utils
- "libdebuggerd", // depends on unconverted modules libdexfile_support, libunwindstack, gwp_asan_crash_handler, libtombstone_proto, libprotobuf-cpp-lite
- "libdexfile_static", // depends on libartpalette, libartbase, libdexfile, which are of unsupported type: art_cc_library.
-
- "static_crasher", // depends on unconverted modules: libdebuggerd_handler
-
- "pbtombstone", "crash_dump", // depends on libdebuggerd, libunwindstack
-
- "libbase_ndk", // http://b/186826477, fails to link libctscamera2_jni for device (required for CtsCameraTestCases)
-
- "libprotobuf-internal-protos", // b/210751803, we don't handle path property for filegroups
- "libprotobuf-internal-python-srcs", // b/210751803, we don't handle path property for filegroups
- "libprotobuf-java-full", // b/210751803, we don't handle path property for filegroups
- "host-libprotobuf-java-full", // b/210751803, we don't handle path property for filegroups
- "libprotobuf-java-util-full", // b/210751803, we don't handle path property for filegroups
- "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full
- "conscrypt", // b/210751803, we don't handle path property for filegroups
- "conscrypt-for-host", // b/210751803, we don't handle path property for filegroups
-
- "libprotobuf-java-nano", // b/220869005, depends on non-public_current SDK
- "host-libprotobuf-java-nano", // b/220869005, depends on libprotobuf-java-nano
-
- "libc_musl_sysroot_bionic_arch_headers", // b/218405924, depends on soong_zip
- "libc_musl_sysroot_bionic_headers", // b/218405924, depends on soong_zip and generates duplicate srcs
+ // java bugs
+ "libbase_ndk", // TODO(b/186826477): fails to link libctscamera2_jni for device (required for CtsCameraTestCases)
// python protos
- "libprotobuf-python", // contains .proto sources
- "conv_linker_config", // depends on linker_config_proto, a python lib with proto sources
- "apex_build_info_proto", "apex_manifest_proto", // a python lib with proto sources
- "linker_config_proto", // contains .proto sources
+ "libprotobuf-python", // TODO(b/196084681): contains .proto sources
+ "apex_build_info_proto", "apex_manifest_proto", // TODO(b/196084681): a python lib with proto sources
+ "linker_config_proto", // TODO(b/196084681): contains .proto sources
- "brotli-fuzzer-corpus", // b/202015218: outputs are in location incompatible with bazel genrule handling.
+ // genrule incompatibilities
+ "brotli-fuzzer-corpus", // TODO(b/202015218): outputs are in location incompatible with bazel genrule handling.
+ "platform_tools_properties", "build_tools_source_properties", // TODO(b/203369847): multiple genrules in the same package creating the same file
- // python modules
- "analyze_bcpf", // depends on bpmodify a blueprint_go_binary.
+ // aar support
+ "prebuilt_car-ui-androidx-core-common", // TODO(b/224773339), genrule dependency creates an .aar, not a .jar
+ "prebuilt_platform-robolectric-4.4-prebuilt", // aosp/1999250, needs .aar support in Jars
+ "prebuilt_platform-robolectric-4.5.1-prebuilt", // aosp/1999250, needs .aar support in Jars
- // b/203369847: multiple genrules in the same package creating the same file
- // //development/sdk/...
- "platform_tools_properties",
- "build_tools_source_properties",
-
- // APEX support
- "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig
-
- "libgtest_ndk_c++", // b/201816222: Requires sdk_version support.
- "libgtest_main_ndk_c++", // b/201816222: Requires sdk_version support.
-
- "abb", // depends on unconverted modules: libcmd, libbinder
- "adb", // depends on unconverted modules: AdbWinApi, libadb_host, libandroidfw, libapp_processes_protos_full, libfastdeploy_host, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi
- "libadb_host", // depends on unconverted modules: libopenscreen-discovery, libopenscreen-platform-impl, libusb, AdbWinApi
- "libfastdeploy_host", // depends on unconverted modules: libandroidfw, libusb, AdbWinApi
- "linker", // depends on unconverted modules: libdebuggerd_handler_fallback
- "linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_*
- "versioner", // depends on unconverted modules: libclang_cxx_host, libLLVM_host, of unsupported type llvm_host_prebuilt_library_shared
-
- "linkerconfig", // http://b/202876379 has arch-variant static_executable
- "mdnsd", // http://b/202876379 has arch-variant static_executable
-
- "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
-
- "libdexfile", // depends on unconverted modules: dexfile_operator_srcs, libartbase, libartpalette,
- "libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette
+ // path property for filegroups
+ "conscrypt", // TODO(b/210751803), we don't handle path property for filegroups
+ "conscrypt-for-host", // TODO(b/210751803), we don't handle path property for filegroups
+ "host-libprotobuf-java-full", // TODO(b/210751803), we don't handle path property for filegroups
+ "libprotobuf-internal-protos", // TODO(b/210751803), we don't handle path property for filegroups
+ "libprotobuf-internal-python-srcs", // TODO(b/210751803), we don't handle path property for filegroups
+ "libprotobuf-java-full", // TODO(b/210751803), we don't handle path property for filegroups
+ "libprotobuf-java-util-full", // TODO(b/210751803), we don't handle path property for filegroups
// go deps:
+ "analyze_bcpf", // depends on bpmodify a blueprint_go_binary.
"apex-protos", // depends on soong_zip, a go binary
"generated_android_icu4j_src_files", "generated_android_icu4j_test_files", "icu4c_test_data", // depends on unconverted modules: soong_zip
"host_bionic_linker_asm", // depends on extract_linker, a go binary.
"host_bionic_linker_script", // depends on extract_linker, a go binary.
- "robolectric-sqlite4java-native", // depends on soong_zip, a go binary
- "robolectric_tzdata", // depends on soong_zip, a go binary
+ "libc_musl_sysroot_bionic_arch_headers", // depends on soong_zip
+ "libc_musl_sysroot_bionic_headers", // 218405924, depends on soong_zip and generates duplicate srcs
"libc_musl_sysroot_libc++_headers", "libc_musl_sysroot_libc++abi_headers", // depends on soong_zip, zip2zip
+ "robolectric-sqlite4java-native", // depends on soong_zip, a go binary
+ "robolectric_tzdata", // depends on soong_zip, a go binary
- "android_icu4j_srcgen_binary", // Bazel build error: deps not allowed without srcs; move to runtime_deps
- "core-icu4j-for-host", // Bazel build error: deps not allowed without srcs; move to runtime_deps
-
- // java deps
- "android_icu4j_srcgen", // depends on unconverted modules: currysrc
- "bin2c_fastdeployagent", // depends on deployagent, a java binary
- "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9
- "robolectric-sqlite4java-0.282", // depends on unconverted modules: robolectric-sqlite4java-import, robolectric-sqlite4java-native
- "timezone-host", // depends on unconverted modules: art.module.api.annotations
- "truth-host-prebuilt", // depends on unconverted modules: truth-prebuilt
- "truth-prebuilt", // depends on unconverted modules: asm-7.0, guava
-
- "generated_android_icu4j_resources", // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
- "generated_android_icu4j_test_resources", // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
-
- "art-script", // depends on unconverted modules: dalvikvm, dex2oat
- "dex2oat-script", // depends on unconverted modules: dex2oat
-
- "prebuilt_car-ui-androidx-core-common", // b/224773339, genrule dependency creates an .aar, not a .jar
- "prebuilt_platform-robolectric-4.4-prebuilt", // aosp/1999250, needs .aar support in Jars
- "prebuilt_platform-robolectric-4.5.1-prebuilt", // aosp/1999250, needs .aar support in Jars
-
+ // rust support
"libtombstoned_client_rust_bridge_code", "libtombstoned_client_wrapper", // rust conversions are not supported
+
+ // unconverted deps
+ "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
+ "abb", // depends on unconverted modules: libcmd, libbinder
+ "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi
+ "android_icu4j_srcgen", // depends on unconverted modules: currysrc
+ "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc
+ "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full
+ "art-script", // depends on unconverted modules: dalvikvm, dex2oat
+ "bin2c_fastdeployagent", // depends on unconverted modules: deployagent
+ "chkcon", "sefcontext_compile", // depends on unconverted modules: libsepol
+ "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig
+ "conv_linker_config", // depends on unconverted modules: linker_config_proto
+ "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9
+ "dex2oat-script", // depends on unconverted modules: dex2oat
+ "generated_android_icu4j_resources", // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
+ "generated_android_icu4j_test_resources", // depends on unconverted modules: android_icu4j_srcgen_binary, soong_zip
+ "host-libprotobuf-java-nano", // b/220869005, depends on libprotobuf-java-nano
+ "libadb_host", // depends on unconverted modules: AdbWinApi, libopenscreen-discovery, libopenscreen-platform-impl, libusb
+ "libart", // depends on unconverted modules: apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api, art_operator_srcs, libcpu_features, libodrstatslog, libelffile, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfile, libnativebridge, libnativeloader, libsigchain, libartbase, libprofile, cpp-define-generator-asm-support
+ "libart-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libart-compiler, libdexfile, libprofile, libartbase, libartbase-art-gtest
+ "libart_headers", // depends on unconverted modules: art_libartbase_headers
+ "libartd", // depends on unconverted modules: art_operator_srcs, libcpu_features, libodrstatslog, libelffiled, art_cmdlineparser_headers, cpp-define-generator-definitions, libdexfiled, libnativebridge, libnativeloader, libsigchain, libartbased, libprofiled, cpp-define-generator-asm-support, apex-info-list-tinyxml, libtinyxml2, libnativeloader-headers, heapprofd_client_api
+ "libartd-runtime-gtest", // depends on unconverted modules: libgtest_isolated, libartd-compiler, libdexfiled, libprofiled, libartbased, libartbased-art-gtest
+ "libdebuggerd_handler", // depends on unconverted module libdebuggerd_handler_core
+ "libdebuggerd_handler_core", "libdebuggerd_handler_fallback", // depends on unconverted module libdebuggerd
+ "libdexfile", // depends on unconverted modules: dexfile_operator_srcs, libartbase, libartpalette,
+ "libdexfile_static", // depends on unconverted modules: libartbase, libdexfile
+ "libdexfiled", // depends on unconverted modules: dexfile_operator_srcs, libartbased, libartpalette
+ "libfastdeploy_host", // depends on unconverted modules: libandroidfw, libusb, AdbWinApi
+ "libgmock_main_ndk", // depends on unconverted modules: libgtest_ndk_c++
+ "libgmock_ndk", // depends on unconverted modules: libgtest_ndk_c++
+ "libnativehelper_lazy_mts_jni", "libnativehelper_mts_jni", // depends on unconverted modules: libnativetesthelper_jni, libgmock_ndk
+ "libnativetesthelper_jni", // depends on unconverted modules: libgtest_ndk_c++
+ "libprotobuf-java-nano", // b/220869005, depends on non-public_current SDK
+ "libstatslog", // depends on unconverted modules: libstatspull, statsd-aidl-ndk, libbinder_ndk
+ "libstatslog_art", // depends on unconverted modules: statslog_art.cpp, statslog_art.h
+ "linker_reloc_bench_main", // depends on unconverted modules: liblinker_reloc_bench_*
+ "pbtombstone", "crash_dump", // depends on libdebuggerd, libunwindstack
+ "robolectric-sqlite4java-0.282", // depends on unconverted modules: robolectric-sqlite4java-import, robolectric-sqlite4java-native
+ "static_crasher", // depends on unconverted modules: libdebuggerd_handler
+ "stats-log-api-gen", // depends on unconverted modules: libstats_proto_host
+ "statslog.cpp", "statslog.h", "statslog.rs", // depends on unconverted modules: stats-log-api-gen
+ "statslog_art.cpp", "statslog_art.h", "statslog_header.rs", // depends on unconverted modules: stats-log-api-gen
+ "timezone-host", // depends on unconverted modules: art.module.api.annotations
+ "truth-host-prebuilt", // depends on unconverted modules: truth-prebuilt
+ "truth-prebuilt", // depends on unconverted modules: asm-7.0, guava
}
// Per-module denylist of cc_library modules to only generate the static
diff --git a/android/config.go b/android/config.go
index 5c41ee8..5dcb959 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1360,6 +1360,10 @@
return "", false
}
+func (c *deviceConfig) ApexGlobalMinSdkVersionOverride() string {
+ return String(c.config.productVariables.ApexGlobalMinSdkVersionOverride)
+}
+
func (c *config) IntegerOverflowDisabledForPath(path string) bool {
if len(c.productVariables.IntegerOverflowExcludePaths) == 0 {
return false
diff --git a/android/config_bp2build.go b/android/config_bp2build.go
new file mode 100644
index 0000000..748be62
--- /dev/null
+++ b/android/config_bp2build.go
@@ -0,0 +1,487 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "fmt"
+ "reflect"
+ "regexp"
+ "sort"
+ "strings"
+
+ "android/soong/bazel"
+ "android/soong/starlark_fmt"
+
+ "github.com/google/blueprint"
+)
+
+// BazelVarExporter is a collection of configuration variables that can be exported for use in Bazel rules
+type BazelVarExporter interface {
+ // asBazel expands strings of configuration variables into their concrete values
+ asBazel(Config, ExportedStringVariables, ExportedStringListVariables, ExportedConfigDependingVariables) []bazelConstant
+}
+
+// ExportedVariables is a collection of interdependent configuration variables
+type ExportedVariables struct {
+ // Maps containing toolchain variables that are independent of the
+ // environment variables of the build.
+ exportedStringVars ExportedStringVariables
+ exportedStringListVars ExportedStringListVariables
+ exportedStringListDictVars ExportedStringListDictVariables
+
+ exportedVariableReferenceDictVars ExportedVariableReferenceDictVariables
+
+ /// Maps containing variables that are dependent on the build config.
+ exportedConfigDependingVars ExportedConfigDependingVariables
+
+ pctx PackageContext
+}
+
+// NewExportedVariables creats an empty ExportedVariables struct with non-nil maps
+func NewExportedVariables(pctx PackageContext) ExportedVariables {
+ return ExportedVariables{
+ exportedStringVars: ExportedStringVariables{},
+ exportedStringListVars: ExportedStringListVariables{},
+ exportedStringListDictVars: ExportedStringListDictVariables{},
+ exportedVariableReferenceDictVars: ExportedVariableReferenceDictVariables{},
+ exportedConfigDependingVars: ExportedConfigDependingVariables{},
+ pctx: pctx,
+ }
+}
+
+func (ev ExportedVariables) asBazel(config Config,
+ stringVars ExportedStringVariables, stringListVars ExportedStringListVariables, cfgDepVars ExportedConfigDependingVariables) []bazelConstant {
+ ret := []bazelConstant{}
+ ret = append(ret, ev.exportedStringVars.asBazel(config, stringVars, stringListVars, cfgDepVars)...)
+ ret = append(ret, ev.exportedStringListVars.asBazel(config, stringVars, stringListVars, cfgDepVars)...)
+ ret = append(ret, ev.exportedStringListDictVars.asBazel(config, stringVars, stringListVars, cfgDepVars)...)
+ // Note: ExportedVariableReferenceDictVars collections can only contain references to other variables and must be printed last
+ ret = append(ret, ev.exportedVariableReferenceDictVars.asBazel(config, stringVars, stringListVars, cfgDepVars)...)
+ return ret
+}
+
+// ExportStringStaticVariable declares a static string variable and exports it to
+// Bazel's toolchain.
+func (ev ExportedVariables) ExportStringStaticVariable(name string, value string) {
+ ev.pctx.StaticVariable(name, value)
+ ev.exportedStringVars.set(name, value)
+}
+
+// ExportStringListStaticVariable declares a static variable and exports it to
+// Bazel's toolchain.
+func (ev ExportedVariables) ExportStringListStaticVariable(name string, value []string) {
+ ev.pctx.StaticVariable(name, strings.Join(value, " "))
+ ev.exportedStringListVars.set(name, value)
+}
+
+// ExportVariableConfigMethod declares a variable whose value is evaluated at
+// runtime via a function with access to the Config and exports it to Bazel's
+// toolchain.
+func (ev ExportedVariables) ExportVariableConfigMethod(name string, method interface{}) blueprint.Variable {
+ ev.exportedConfigDependingVars.set(name, method)
+ return ev.pctx.VariableConfigMethod(name, method)
+}
+
+// ExportSourcePathVariable declares a static "source path" variable and exports
+// it to Bazel's toolchain.
+func (ev ExportedVariables) ExportSourcePathVariable(name string, value string) {
+ ev.pctx.SourcePathVariable(name, value)
+ ev.exportedStringVars.set(name, value)
+}
+
+// ExportVariableFuncVariable declares a variable whose value is evaluated at
+// runtime via a function and exports it to Bazel's toolchain.
+func (ev ExportedVariables) ExportVariableFuncVariable(name string, f func() string) {
+ ev.exportedConfigDependingVars.set(name, func(config Config) string {
+ return f()
+ })
+ ev.pctx.VariableFunc(name, func(PackageVarContext) string {
+ return f()
+ })
+}
+
+// ExportString only exports a variable to Bazel, but does not declare it in Soong
+func (ev ExportedVariables) ExportString(name string, value string) {
+ ev.exportedStringVars.set(name, value)
+}
+
+// ExportStringList only exports a variable to Bazel, but does not declare it in Soong
+func (ev ExportedVariables) ExportStringList(name string, value []string) {
+ ev.exportedStringListVars.set(name, value)
+}
+
+// ExportStringListDict only exports a variable to Bazel, but does not declare it in Soong
+func (ev ExportedVariables) ExportStringListDict(name string, value map[string][]string) {
+ ev.exportedStringListDictVars.set(name, value)
+}
+
+// ExportVariableReferenceDict only exports a variable to Bazel, but does not declare it in Soong
+func (ev ExportedVariables) ExportVariableReferenceDict(name string, value map[string]string) {
+ ev.exportedVariableReferenceDictVars.set(name, value)
+}
+
+// ExportedConfigDependingVariables is a mapping of variable names to functions
+// of type func(config Config) string which return the runtime-evaluated string
+// value of a particular variable
+type ExportedConfigDependingVariables map[string]interface{}
+
+func (m ExportedConfigDependingVariables) set(k string, v interface{}) {
+ m[k] = v
+}
+
+// Ensure that string s has no invalid characters to be generated into the bzl file.
+func validateCharacters(s string) string {
+ for _, c := range []string{`\n`, `"`, `\`} {
+ if strings.Contains(s, c) {
+ panic(fmt.Errorf("%s contains illegal character %s", s, c))
+ }
+ }
+ return s
+}
+
+type bazelConstant struct {
+ variableName string
+ internalDefinition string
+ sortLast bool
+}
+
+// ExportedStringVariables is a mapping of variable names to string values
+type ExportedStringVariables map[string]string
+
+func (m ExportedStringVariables) set(k string, v string) {
+ m[k] = v
+}
+
+func (m ExportedStringVariables) asBazel(config Config,
+ stringVars ExportedStringVariables, stringListVars ExportedStringListVariables, cfgDepVars ExportedConfigDependingVariables) []bazelConstant {
+ ret := make([]bazelConstant, 0, len(m))
+ for k, variableValue := range m {
+ expandedVar, err := expandVar(config, variableValue, stringVars, stringListVars, cfgDepVars)
+ if err != nil {
+ panic(fmt.Errorf("error expanding config variable %s: %s", k, err))
+ }
+ if len(expandedVar) > 1 {
+ panic(fmt.Errorf("%s expands to more than one string value: %s", variableValue, expandedVar))
+ }
+ ret = append(ret, bazelConstant{
+ variableName: k,
+ internalDefinition: fmt.Sprintf(`"%s"`, validateCharacters(expandedVar[0])),
+ })
+ }
+ return ret
+}
+
+// ExportedStringListVariables is a mapping of variable names to a list of strings
+type ExportedStringListVariables map[string][]string
+
+func (m ExportedStringListVariables) set(k string, v []string) {
+ m[k] = v
+}
+
+func (m ExportedStringListVariables) asBazel(config Config,
+ stringScope ExportedStringVariables, stringListScope ExportedStringListVariables,
+ exportedVars ExportedConfigDependingVariables) []bazelConstant {
+ ret := make([]bazelConstant, 0, len(m))
+ // For each exported variable, recursively expand elements in the variableValue
+ // list to ensure that interpolated variables are expanded according to their values
+ // in the variable scope.
+ for k, variableValue := range m {
+ var expandedVars []string
+ for _, v := range variableValue {
+ expandedVar, err := expandVar(config, v, stringScope, stringListScope, exportedVars)
+ if err != nil {
+ panic(fmt.Errorf("Error expanding config variable %s=%s: %s", k, v, err))
+ }
+ expandedVars = append(expandedVars, expandedVar...)
+ }
+ // Assign the list as a bzl-private variable; this variable will be exported
+ // out through a constants struct later.
+ ret = append(ret, bazelConstant{
+ variableName: k,
+ internalDefinition: starlark_fmt.PrintStringList(expandedVars, 0),
+ })
+ }
+ return ret
+}
+
+// ExportedStringListDictVariables is a mapping from variable names to a
+// dictionary which maps keys to lists of strings
+type ExportedStringListDictVariables map[string]map[string][]string
+
+func (m ExportedStringListDictVariables) set(k string, v map[string][]string) {
+ m[k] = v
+}
+
+// Since dictionaries are not supported in Ninja, we do not expand variables for dictionaries
+func (m ExportedStringListDictVariables) asBazel(_ Config, _ ExportedStringVariables,
+ _ ExportedStringListVariables, _ ExportedConfigDependingVariables) []bazelConstant {
+ ret := make([]bazelConstant, 0, len(m))
+ for k, dict := range m {
+ ret = append(ret, bazelConstant{
+ variableName: k,
+ internalDefinition: starlark_fmt.PrintStringListDict(dict, 0),
+ })
+ }
+ return ret
+}
+
+// ExportedVariableReferenceDictVariables is a mapping from variable names to a
+// dictionary which references previously defined variables. This is used to
+// create a Starlark output such as:
+// string_var1 = "string1
+// var_ref_dict_var1 = {
+// "key1": string_var1
+// }
+// This type of variable collection must be expanded last so that it recognizes
+// previously defined variables.
+type ExportedVariableReferenceDictVariables map[string]map[string]string
+
+func (m ExportedVariableReferenceDictVariables) set(k string, v map[string]string) {
+ m[k] = v
+}
+
+func (m ExportedVariableReferenceDictVariables) asBazel(_ Config, _ ExportedStringVariables,
+ _ ExportedStringListVariables, _ ExportedConfigDependingVariables) []bazelConstant {
+ ret := make([]bazelConstant, 0, len(m))
+ for n, dict := range m {
+ for k, v := range dict {
+ matches, err := variableReference(v)
+ if err != nil {
+ panic(err)
+ } else if !matches.matches {
+ panic(fmt.Errorf("Expected a variable reference, got %q", v))
+ } else if len(matches.fullVariableReference) != len(v) {
+ panic(fmt.Errorf("Expected only a variable reference, got %q", v))
+ }
+ dict[k] = "_" + matches.variable
+ }
+ ret = append(ret, bazelConstant{
+ variableName: n,
+ internalDefinition: starlark_fmt.PrintDict(dict, 0),
+ sortLast: true,
+ })
+ }
+ return ret
+}
+
+// BazelToolchainVars expands an ExportedVariables collection and returns a string
+// of formatted Starlark variable definitions
+func BazelToolchainVars(config Config, exportedVars ExportedVariables) string {
+ results := exportedVars.asBazel(
+ config,
+ exportedVars.exportedStringVars,
+ exportedVars.exportedStringListVars,
+ exportedVars.exportedConfigDependingVars,
+ )
+
+ sort.Slice(results, func(i, j int) bool {
+ if results[i].sortLast != results[j].sortLast {
+ return !results[i].sortLast
+ }
+ return results[i].variableName < results[j].variableName
+ })
+
+ definitions := make([]string, 0, len(results))
+ constants := make([]string, 0, len(results))
+ for _, b := range results {
+ definitions = append(definitions,
+ fmt.Sprintf("_%s = %s", b.variableName, b.internalDefinition))
+ constants = append(constants,
+ fmt.Sprintf("%[1]s%[2]s = _%[2]s,", starlark_fmt.Indention(1), b.variableName))
+ }
+
+ // Build the exported constants struct.
+ ret := bazel.GeneratedBazelFileWarning
+ ret += "\n\n"
+ ret += strings.Join(definitions, "\n\n")
+ ret += "\n\n"
+ ret += "constants = struct(\n"
+ ret += strings.Join(constants, "\n")
+ ret += "\n)"
+
+ return ret
+}
+
+type match struct {
+ matches bool
+ fullVariableReference string
+ variable string
+}
+
+func variableReference(input string) (match, error) {
+ // e.g. "${ExternalCflags}"
+ r := regexp.MustCompile(`\${(?:config\.)?([a-zA-Z0-9_]+)}`)
+
+ matches := r.FindStringSubmatch(input)
+ if len(matches) == 0 {
+ return match{}, nil
+ }
+ if len(matches) != 2 {
+ return match{}, fmt.Errorf("Expected to only match 1 subexpression in %s, got %d", input, len(matches)-1)
+ }
+ return match{
+ matches: true,
+ fullVariableReference: matches[0],
+ // Index 1 of FindStringSubmatch contains the subexpression match
+ // (variable name) of the capture group.
+ variable: matches[1],
+ }, nil
+}
+
+// expandVar recursively expand interpolated variables in the exportedVars scope.
+//
+// We're using a string slice to track the seen variables to avoid
+// stackoverflow errors with infinite recursion. it's simpler to use a
+// 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(config Config, toExpand string, stringScope ExportedStringVariables,
+ stringListScope ExportedStringListVariables, exportedVars ExportedConfigDependingVariables) ([]string, error) {
+
+ // Internal recursive function.
+ var expandVarInternal func(string, map[string]bool) (string, error)
+ expandVarInternal = func(toExpand string, seenVars map[string]bool) (string, error) {
+ var ret string
+ remainingString := toExpand
+ for len(remainingString) > 0 {
+ matches, err := variableReference(remainingString)
+ if err != nil {
+ panic(err)
+ }
+ if !matches.matches {
+ return ret + remainingString, nil
+ }
+ matchIndex := strings.Index(remainingString, matches.fullVariableReference)
+ ret += remainingString[:matchIndex]
+ remainingString = remainingString[matchIndex+len(matches.fullVariableReference):]
+
+ variable := matches.variable
+ // toExpand contains a variable.
+ if _, ok := seenVars[variable]; ok {
+ return ret, fmt.Errorf(
+ "Unbounded recursive interpolation of variable: %s", variable)
+ }
+ // A map is passed-by-reference. Create a new map for
+ // this scope to prevent variables seen in one depth-first expansion
+ // to be also treated as "seen" in other depth-first traversals.
+ newSeenVars := map[string]bool{}
+ for k := range seenVars {
+ newSeenVars[k] = true
+ }
+ newSeenVars[variable] = true
+ if unexpandedVars, ok := stringListScope[variable]; ok {
+ expandedVars := []string{}
+ for _, unexpandedVar := range unexpandedVars {
+ expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ expandedVars = append(expandedVars, expandedVar)
+ }
+ ret += strings.Join(expandedVars, " ")
+ } else if unexpandedVar, ok := stringScope[variable]; ok {
+ expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ ret += expandedVar
+ } else if unevaluatedVar, ok := exportedVars[variable]; ok {
+ evalFunc := reflect.ValueOf(unevaluatedVar)
+ validateVariableMethod(variable, evalFunc)
+ evaluatedResult := evalFunc.Call([]reflect.Value{reflect.ValueOf(config)})
+ evaluatedValue := evaluatedResult[0].Interface().(string)
+ expandedVar, err := expandVarInternal(evaluatedValue, newSeenVars)
+ if err != nil {
+ return ret, err
+ }
+ ret += expandedVar
+ } else {
+ return "", fmt.Errorf("Unbound config variable %s", variable)
+ }
+ }
+ return ret, nil
+ }
+ var ret []string
+ stringFields := splitStringKeepingQuotedSubstring(toExpand, ' ')
+ for _, v := range stringFields {
+ val, err := expandVarInternal(v, map[string]bool{})
+ if err != nil {
+ return ret, err
+ }
+ ret = append(ret, val)
+ }
+
+ return ret, nil
+}
+
+// splitStringKeepingQuotedSubstring splits a string on a provided separator,
+// but it will not split substrings inside unescaped double quotes. If the double
+// quotes are escaped, then the returned string will only include the quote, and
+// not the escape.
+func splitStringKeepingQuotedSubstring(s string, delimiter byte) []string {
+ var ret []string
+ quote := byte('"')
+
+ var substring []byte
+ quoted := false
+ escaped := false
+
+ for i := range s {
+ if !quoted && s[i] == delimiter {
+ ret = append(ret, string(substring))
+ substring = []byte{}
+ continue
+ }
+
+ characterIsEscape := i < len(s)-1 && s[i] == '\\' && s[i+1] == quote
+ if characterIsEscape {
+ escaped = true
+ continue
+ }
+
+ if s[i] == quote {
+ if !escaped {
+ quoted = !quoted
+ }
+ escaped = false
+ }
+
+ substring = append(substring, s[i])
+ }
+
+ ret = append(ret, string(substring))
+
+ return ret
+}
+
+func validateVariableMethod(name string, methodValue reflect.Value) {
+ methodType := methodValue.Type()
+ if methodType.Kind() != reflect.Func {
+ panic(fmt.Errorf("method given for variable %s is not a function",
+ name))
+ }
+ if n := methodType.NumIn(); n != 1 {
+ panic(fmt.Errorf("method for variable %s has %d inputs (should be 1)",
+ name, n))
+ }
+ if n := methodType.NumOut(); n != 1 {
+ panic(fmt.Errorf("method for variable %s has %d outputs (should be 1)",
+ name, n))
+ }
+ if kind := methodType.Out(0).Kind(); kind != reflect.String {
+ panic(fmt.Errorf("method for variable %s does not return a string",
+ name))
+ }
+}
diff --git a/android/config_bp2build_test.go b/android/config_bp2build_test.go
new file mode 100644
index 0000000..1a0ba7b
--- /dev/null
+++ b/android/config_bp2build_test.go
@@ -0,0 +1,454 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package android
+
+import (
+ "android/soong/bazel"
+ "testing"
+)
+
+func TestExpandVars(t *testing.T) {
+ android_arm64_config := TestConfig("out", nil, "", nil)
+ android_arm64_config.BuildOS = Android
+ android_arm64_config.BuildArch = Arm64
+
+ testCases := []struct {
+ description string
+ config Config
+ stringScope ExportedStringVariables
+ stringListScope ExportedStringListVariables
+ configVars ExportedConfigDependingVariables
+ toExpand string
+ expectedValues []string
+ }{
+ {
+ 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 with short-name for string var",
+ stringScope: ExportedStringVariables{
+ "foo": "bar",
+ },
+ toExpand: "${config.foo}",
+ expectedValues: []string{"bar"},
+ },
+ {
+ description: "single level expansion string list var",
+ stringListScope: ExportedStringListVariables{
+ "foo": []string{"bar"},
+ },
+ 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",
+ stringListScope: ExportedStringListVariables{
+ "foo": []string{"${bar}"},
+ "bar": []string{"baz"},
+ },
+ toExpand: "${foo}",
+ expectedValues: []string{"baz"},
+ },
+ {
+ description: "double level expansion with a literal",
+ 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",
+ 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",
+ stringListScope: ExportedStringListVariables{
+ "a": []string{"${b} ${c}"},
+ "b": []string{"${c}", "${d}"},
+ "c": []string{"${d}"},
+ "d": []string{"foo"},
+ },
+ toExpand: "${a}",
+ expectedValues: []string{"foo foo foo"},
+ },
+ {
+ description: "expansion with config depending vars",
+ configVars: ExportedConfigDependingVariables{
+ "a": func(c Config) string { return c.BuildOS.String() },
+ "b": func(c Config) string { return c.BuildArch.String() },
+ },
+ config: android_arm64_config,
+ toExpand: "${a}-${b}",
+ expectedValues: []string{"android-arm64"},
+ },
+ {
+ description: "double level multi type expansion",
+ stringListScope: ExportedStringListVariables{
+ "platform": []string{"${os}-${arch}"},
+ "const": []string{"const"},
+ },
+ configVars: ExportedConfigDependingVariables{
+ "os": func(c Config) string { return c.BuildOS.String() },
+ "arch": func(c Config) string { return c.BuildArch.String() },
+ "foo": func(c Config) string { return "foo" },
+ },
+ config: android_arm64_config,
+ toExpand: "${const}/${platform}/${foo}",
+ expectedValues: []string{"const/android-arm64/foo"},
+ },
+ }
+
+ for _, testCase := range testCases {
+ t.Run(testCase.description, func(t *testing.T) {
+ output, _ := expandVar(testCase.config, testCase.toExpand, testCase.stringScope, testCase.stringListScope, testCase.configVars)
+ if len(output) != len(testCase.expectedValues) {
+ t.Errorf("Expected %d values, got %d", len(testCase.expectedValues), len(output))
+ }
+ for i, actual := range output {
+ expectedValue := testCase.expectedValues[i]
+ if actual != expectedValue {
+ t.Errorf("Actual value '%s' doesn't match expected value '%s'", actual, expectedValue)
+ }
+ }
+ })
+ }
+}
+
+func TestBazelToolchainVars(t *testing.T) {
+ testCases := []struct {
+ name string
+ config Config
+ vars ExportedVariables
+ expectedOut string
+ }{
+ {
+ name: "exports strings",
+ vars: ExportedVariables{
+ exportedStringVars: ExportedStringVariables{
+ "a": "b",
+ "c": "d",
+ },
+ },
+ expectedOut: bazel.GeneratedBazelFileWarning + `
+
+_a = "b"
+
+_c = "d"
+
+constants = struct(
+ a = _a,
+ c = _c,
+)`,
+ },
+ {
+ name: "exports string lists",
+ vars: ExportedVariables{
+ exportedStringListVars: ExportedStringListVariables{
+ "a": []string{"b1", "b2"},
+ "c": []string{"d1", "d2"},
+ },
+ },
+ expectedOut: bazel.GeneratedBazelFileWarning + `
+
+_a = [
+ "b1",
+ "b2",
+]
+
+_c = [
+ "d1",
+ "d2",
+]
+
+constants = struct(
+ a = _a,
+ c = _c,
+)`,
+ },
+ {
+ name: "exports string lists dicts",
+ vars: ExportedVariables{
+ exportedStringListDictVars: ExportedStringListDictVariables{
+ "a": map[string][]string{"b1": {"b2"}},
+ "c": map[string][]string{"d1": {"d2"}},
+ },
+ },
+ expectedOut: bazel.GeneratedBazelFileWarning + `
+
+_a = {
+ "b1": ["b2"],
+}
+
+_c = {
+ "d1": ["d2"],
+}
+
+constants = struct(
+ a = _a,
+ c = _c,
+)`,
+ },
+ {
+ name: "exports dict with var refs",
+ vars: ExportedVariables{
+ exportedVariableReferenceDictVars: ExportedVariableReferenceDictVariables{
+ "a": map[string]string{"b1": "${b2}"},
+ "c": map[string]string{"d1": "${config.d2}"},
+ },
+ },
+ expectedOut: bazel.GeneratedBazelFileWarning + `
+
+_a = {
+ "b1": _b2,
+}
+
+_c = {
+ "d1": _d2,
+}
+
+constants = struct(
+ a = _a,
+ c = _c,
+)`,
+ },
+ {
+ name: "sorts across types with variable references last",
+ vars: ExportedVariables{
+ exportedStringVars: ExportedStringVariables{
+ "b": "b-val",
+ "d": "d-val",
+ },
+ exportedStringListVars: ExportedStringListVariables{
+ "c": []string{"c-val"},
+ "e": []string{"e-val"},
+ },
+ exportedStringListDictVars: ExportedStringListDictVariables{
+ "a": map[string][]string{"a1": {"a2"}},
+ "f": map[string][]string{"f1": {"f2"}},
+ },
+ exportedVariableReferenceDictVars: ExportedVariableReferenceDictVariables{
+ "aa": map[string]string{"b1": "${b}"},
+ "cc": map[string]string{"d1": "${config.d}"},
+ },
+ },
+ expectedOut: bazel.GeneratedBazelFileWarning + `
+
+_a = {
+ "a1": ["a2"],
+}
+
+_b = "b-val"
+
+_c = ["c-val"]
+
+_d = "d-val"
+
+_e = ["e-val"]
+
+_f = {
+ "f1": ["f2"],
+}
+
+_aa = {
+ "b1": _b,
+}
+
+_cc = {
+ "d1": _d,
+}
+
+constants = struct(
+ a = _a,
+ b = _b,
+ c = _c,
+ d = _d,
+ e = _e,
+ f = _f,
+ aa = _aa,
+ cc = _cc,
+)`,
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.name, func(t *testing.T) {
+ out := BazelToolchainVars(tc.config, tc.vars)
+ if out != tc.expectedOut {
+ t.Errorf("Expected \n%s, got \n%s", tc.expectedOut, out)
+ }
+ })
+ }
+}
+
+func TestSplitStringKeepingQuotedSubstring(t *testing.T) {
+ testCases := []struct {
+ description string
+ s string
+ delimiter byte
+ split []string
+ }{
+ {
+ description: "empty string returns single empty string",
+ s: "",
+ delimiter: ' ',
+ split: []string{
+ "",
+ },
+ },
+ {
+ description: "string with single space returns two empty strings",
+ s: " ",
+ delimiter: ' ',
+ split: []string{
+ "",
+ "",
+ },
+ },
+ {
+ description: "string with two spaces returns three empty strings",
+ s: " ",
+ delimiter: ' ',
+ split: []string{
+ "",
+ "",
+ "",
+ },
+ },
+ {
+ description: "string with four words returns four word string",
+ s: "hello world with words",
+ delimiter: ' ',
+ split: []string{
+ "hello",
+ "world",
+ "with",
+ "words",
+ },
+ },
+ {
+ description: "string with words and nested quote returns word strings and quote string",
+ s: `hello "world with" words`,
+ delimiter: ' ',
+ split: []string{
+ "hello",
+ `"world with"`,
+ "words",
+ },
+ },
+ {
+ description: "string with escaped quote inside real quotes",
+ s: `hello \"world "with\" words"`,
+ delimiter: ' ',
+ split: []string{
+ "hello",
+ `"world`,
+ `"with" words"`,
+ },
+ },
+ {
+ description: "string with words and escaped quotes returns word strings",
+ s: `hello \"world with\" words`,
+ delimiter: ' ',
+ split: []string{
+ "hello",
+ `"world`,
+ `with"`,
+ "words",
+ },
+ },
+ {
+ description: "string which is single quoted substring returns only substring",
+ s: `"hello world with words"`,
+ delimiter: ' ',
+ split: []string{
+ `"hello world with words"`,
+ },
+ },
+ {
+ description: "string starting with quote returns quoted string",
+ s: `"hello world with" words`,
+ delimiter: ' ',
+ split: []string{
+ `"hello world with"`,
+ "words",
+ },
+ },
+ {
+ description: "string with starting quote and no ending quote returns quote to end of string",
+ s: `hello "world with words`,
+ delimiter: ' ',
+ split: []string{
+ "hello",
+ `"world with words`,
+ },
+ },
+ {
+ description: "quoted string is treated as a single \"word\" unless separated by delimiter",
+ s: `hello "world"with words`,
+ delimiter: ' ',
+ split: []string{
+ "hello",
+ `"world"with`,
+ "words",
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ t.Run(tc.description, func(t *testing.T) {
+ split := splitStringKeepingQuotedSubstring(tc.s, tc.delimiter)
+ if len(split) != len(tc.split) {
+ t.Fatalf("number of split string elements (%d) differs from expected (%d): split string (%v), expected (%v)",
+ len(split), len(tc.split), split, tc.split,
+ )
+ }
+ for i := range split {
+ if split[i] != tc.split[i] {
+ t.Errorf("split string element (%d), %v, differs from expected, %v", i, split[i], tc.split[i])
+ }
+ }
+ })
+ }
+}
diff --git a/android/variable.go b/android/variable.go
index 4ed0507..077b810 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -389,6 +389,8 @@
CertificateOverrides []string `json:",omitempty"`
PackageNameOverrides []string `json:",omitempty"`
+ ApexGlobalMinSdkVersionOverride *string `json:",omitempty"`
+
EnforceSystemCertificate *bool `json:",omitempty"`
EnforceSystemCertificateAllowList []string `json:",omitempty"`
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index 2176361..afde68b 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -1690,6 +1690,21 @@
}
`,
},
+ {
+ desc: "convert android_app to android_test when having test_suites",
+ in: `
+include $(CLEAR_VARS)
+LOCAL_MODULE := foo
+LOCAL_COMPATIBILITY_SUITE := bar
+include $(BUILD_PACKAGE)
+ `,
+ expected: `
+android_test {
+ name: "foo",
+ test_suites: ["bar"],
+}
+`,
+ },
}
func TestEndToEnd(t *testing.T) {
diff --git a/apex/apex.go b/apex/apex.go
index 2fe17da..a7b0a4f 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2450,20 +2450,43 @@
android.CheckMinSdkVersion(ctx, minSdkVersion, a.WalkPayloadDeps)
}
+// Returns apex's min_sdk_version string value, honoring overrides
+func (a *apexBundle) minSdkVersionValue(ctx android.EarlyModuleContext) string {
+ // Only override the minSdkVersion value on Apexes which already specify
+ // a min_sdk_version (it's optional for non-updatable apexes), and that its
+ // min_sdk_version value is lower than the one to override with.
+ overrideMinSdkValue := ctx.DeviceConfig().ApexGlobalMinSdkVersionOverride()
+ overrideApiLevel := minSdkVersionFromValue(ctx, overrideMinSdkValue)
+ originalMinApiLevel := minSdkVersionFromValue(ctx, proptools.String(a.properties.Min_sdk_version))
+ isMinSdkSet := a.properties.Min_sdk_version != nil
+ isOverrideValueHigher := overrideApiLevel.CompareTo(originalMinApiLevel) > 0
+ if overrideMinSdkValue != "" && isMinSdkSet && isOverrideValueHigher {
+ return overrideMinSdkValue
+ }
+
+ return proptools.String(a.properties.Min_sdk_version)
+}
+
+// Returns apex's min_sdk_version SdkSpec, honoring overrides
func (a *apexBundle) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec {
return android.SdkSpec{
Kind: android.SdkNone,
ApiLevel: a.minSdkVersion(ctx),
- Raw: String(a.properties.Min_sdk_version),
+ Raw: a.minSdkVersionValue(ctx),
}
}
+// Returns apex's min_sdk_version ApiLevel, honoring overrides
func (a *apexBundle) minSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
- ver := proptools.String(a.properties.Min_sdk_version)
- if ver == "" {
+ return minSdkVersionFromValue(ctx, a.minSdkVersionValue(ctx))
+}
+
+// Construct ApiLevel object from min_sdk_version string value
+func minSdkVersionFromValue(ctx android.EarlyModuleContext, value string) android.ApiLevel {
+ if value == "" {
return android.NoneApiLevel
}
- apiLevel, err := android.ApiLevelFromUser(ctx, ver)
+ apiLevel, err := android.ApiLevelFromUser(ctx, value)
if err != nil {
ctx.PropertyErrorf("min_sdk_version", "%s", err.Error())
return android.NoneApiLevel
@@ -2518,7 +2541,7 @@
// 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) == "" {
+ if a.minSdkVersionValue(ctx) == "" {
ctx.PropertyErrorf("updatable", "updatable APEXes should set min_sdk_version as well")
}
if a.UsePlatformApis() {
@@ -3398,6 +3421,8 @@
fileContextsLabelAttribute.SetValue(android.BazelLabelForModuleDepSingle(ctx, *a.properties.File_contexts))
}
+ // TODO(b/219503907) this would need to be set to a.MinSdkVersionValue(ctx) but
+ // given it's coming via config, we probably don't want to put it in here.
var minSdkVersion *string
if a.properties.Min_sdk_version != nil {
minSdkVersion = a.properties.Min_sdk_version
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 3e01f26..77cbb58 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -113,6 +113,12 @@
})
}
+func withApexGlobalMinSdkVersionOverride(minSdkOverride *string) android.FixturePreparer {
+ return android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.ApexGlobalMinSdkVersionOverride = minSdkOverride
+ })
+}
+
var withBinder32bit = android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
variables.Binder32bit = proptools.BoolPtr(true)
@@ -168,44 +174,42 @@
"system/sepolicy/apex/otherapex-file_contexts": nil,
"system/sepolicy/apex/com.android.vndk-file_contexts": nil,
"system/sepolicy/apex/com.android.vndk.current-file_contexts": nil,
- "mylib.cpp": nil,
- "mytest.cpp": nil,
- "mytest1.cpp": nil,
- "mytest2.cpp": nil,
- "mytest3.cpp": nil,
- "myprebuilt": nil,
- "my_include": nil,
- "foo/bar/MyClass.java": nil,
- "prebuilt.jar": nil,
- "prebuilt.so": nil,
- "vendor/foo/devkeys/test.x509.pem": nil,
- "vendor/foo/devkeys/test.pk8": nil,
- "testkey.x509.pem": nil,
- "testkey.pk8": nil,
- "testkey.override.x509.pem": nil,
- "testkey.override.pk8": nil,
- "vendor/foo/devkeys/testkey.avbpubkey": nil,
- "vendor/foo/devkeys/testkey.pem": nil,
- "NOTICE": nil,
- "custom_notice": nil,
- "custom_notice_for_static_lib": nil,
- "testkey2.avbpubkey": nil,
- "testkey2.pem": nil,
- "myapex-arm64.apex": nil,
- "myapex-arm.apex": nil,
- "myapex.apks": nil,
- "frameworks/base/api/current.txt": nil,
- "framework/aidl/a.aidl": nil,
- "build/make/core/proguard.flags": nil,
- "build/make/core/proguard_basic_keeps.flags": nil,
- "dummy.txt": nil,
- "baz": nil,
- "bar/baz": nil,
- "testdata/baz": nil,
- "AppSet.apks": nil,
- "foo.rs": nil,
- "libfoo.jar": nil,
- "libbar.jar": nil,
+ "mylib.cpp": nil,
+ "mytest.cpp": nil,
+ "mytest1.cpp": nil,
+ "mytest2.cpp": nil,
+ "mytest3.cpp": nil,
+ "myprebuilt": nil,
+ "my_include": nil,
+ "foo/bar/MyClass.java": nil,
+ "prebuilt.jar": nil,
+ "prebuilt.so": nil,
+ "vendor/foo/devkeys/test.x509.pem": nil,
+ "vendor/foo/devkeys/test.pk8": nil,
+ "testkey.x509.pem": nil,
+ "testkey.pk8": nil,
+ "testkey.override.x509.pem": nil,
+ "testkey.override.pk8": nil,
+ "vendor/foo/devkeys/testkey.avbpubkey": nil,
+ "vendor/foo/devkeys/testkey.pem": nil,
+ "NOTICE": nil,
+ "custom_notice": nil,
+ "custom_notice_for_static_lib": nil,
+ "testkey2.avbpubkey": nil,
+ "testkey2.pem": nil,
+ "myapex-arm64.apex": nil,
+ "myapex-arm.apex": nil,
+ "myapex.apks": nil,
+ "frameworks/base/api/current.txt": nil,
+ "framework/aidl/a.aidl": nil,
+ "dummy.txt": nil,
+ "baz": nil,
+ "bar/baz": nil,
+ "testdata/baz": nil,
+ "AppSet.apks": nil,
+ "foo.rs": nil,
+ "libfoo.jar": nil,
+ "libbar.jar": nil,
},
),
@@ -1032,10 +1036,10 @@
// 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"]
+ mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").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"]
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").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")
}
@@ -6314,6 +6318,124 @@
ensureNotContains(t, androidMk, "LOCAL_MODULE_STEM := myapex.apex")
}
+func TestMinSdkVersionOverride(t *testing.T) {
+ // Override from 29 to 31
+ minSdkOverride31 := "31"
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["mylib"],
+ updatable: true,
+ min_sdk_version: "29"
+ }
+
+ override_apex {
+ name: "override_myapex",
+ base: "myapex",
+ logging_parent: "com.foo.bar",
+ package_name: "test.overridden.package"
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ runtime_libs: ["libbar"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ min_sdk_version: "apex_inherit"
+ }
+
+ cc_library {
+ name: "libbar",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ min_sdk_version: "apex_inherit"
+ }
+
+ `, withApexGlobalMinSdkVersionOverride(&minSdkOverride31))
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+
+ // Ensure that direct non-stubs dep is always included
+ ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+
+ // Ensure that runtime_libs dep in included
+ ensureContains(t, copyCmds, "image.apex/lib64/libbar.so")
+
+ // Ensure libraries target overridden min_sdk_version value
+ ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_apex31")
+}
+
+func TestMinSdkVersionOverrideToLowerVersionNoOp(t *testing.T) {
+ // Attempt to override from 31 to 29, should be a NOOP
+ minSdkOverride29 := "29"
+ ctx := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ native_shared_libs: ["mylib"],
+ updatable: true,
+ min_sdk_version: "31"
+ }
+
+ override_apex {
+ name: "override_myapex",
+ base: "myapex",
+ logging_parent: "com.foo.bar",
+ package_name: "test.overridden.package"
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ cc_library {
+ name: "mylib",
+ srcs: ["mylib.cpp"],
+ runtime_libs: ["libbar"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ min_sdk_version: "apex_inherit"
+ }
+
+ cc_library {
+ name: "libbar",
+ srcs: ["mylib.cpp"],
+ system_shared_libs: [],
+ stl: "none",
+ apex_available: [ "myapex" ],
+ min_sdk_version: "apex_inherit"
+ }
+
+ `, withApexGlobalMinSdkVersionOverride(&minSdkOverride29))
+
+ apexRule := ctx.ModuleForTests("myapex", "android_common_myapex_image").Rule("apexRule")
+ copyCmds := apexRule.Args["copy_commands"]
+
+ // Ensure that direct non-stubs dep is always included
+ ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
+
+ // Ensure that runtime_libs dep in included
+ ensureContains(t, copyCmds, "image.apex/lib64/libbar.so")
+
+ // Ensure libraries target the original min_sdk_version value rather than the overridden
+ ensureListContains(t, ctx.ModuleVariantsForTests("libbar"), "android_arm64_armv8-a_shared_apex31")
+}
+
func TestLegacyAndroid10Support(t *testing.T) {
ctx := testApex(t, `
apex {
diff --git a/apex/builder.go b/apex/builder.go
index ea61e1a..293f388 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -994,7 +994,7 @@
return !externalDep
})
- a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, proptools.String(a.properties.Min_sdk_version), depInfos)
+ a.ApexBundleDepsInfo.BuildDepsInfoLists(ctx, a.MinSdkVersion(ctx).Raw, depInfos)
ctx.Build(pctx, android.BuildParams{
Rule: android.Phony,
diff --git a/bazel/constants.go b/bazel/constants.go
index 6beb496..b10f256 100644
--- a/bazel/constants.go
+++ b/bazel/constants.go
@@ -21,7 +21,7 @@
SoongInjectionDirName = "soong_injection"
- GeneratedBazelFileWarning = "# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT"
+ GeneratedBazelFileWarning = "# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT."
)
// String returns the name of the run.
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index 1d3b105..a96a3fc 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -580,7 +580,9 @@
elements = append(elements, val)
}
}
- return starlark_fmt.PrintList(elements, indent, "%s"), nil
+ return starlark_fmt.PrintList(elements, indent, func(s string) string {
+ return "%s"
+ }), nil
case reflect.Struct:
// Special cases where the bp2build sends additional information to the codegenerator
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 91e614d..1790dd7 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -7,7 +7,8 @@
"strings"
"android/soong/android"
- "android/soong/cc/config"
+ cc_config "android/soong/cc/config"
+ java_config "android/soong/java/config"
"github.com/google/blueprint/proptools"
)
@@ -22,7 +23,10 @@
var files []BazelFile
files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package.
- files = append(files, newFile("cc_toolchain", "constants.bzl", config.BazelCcToolchainVars(cfg)))
+ files = append(files, newFile("cc_toolchain", "constants.bzl", cc_config.BazelCcToolchainVars(cfg)))
+
+ files = append(files, newFile("java_toolchain", GeneratedBuildFileName, "")) // Creates a //java_toolchain package.
+ files = append(files, newFile("java_toolchain", "constants.bzl", java_config.BazelJavaToolchainVars(cfg)))
files = append(files, newFile("metrics", "converted_modules.txt", strings.Join(metrics.convertedModules, "\n")))
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index d65ece8..e49d855 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -95,6 +95,14 @@
basename: "constants.bzl",
},
{
+ dir: "java_toolchain",
+ basename: GeneratedBuildFileName,
+ },
+ {
+ dir: "java_toolchain",
+ basename: "constants.bzl",
+ },
+ {
dir: "metrics",
basename: "converted_modules.txt",
},
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index 4b75e3b..ccc52ef 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -219,3 +219,35 @@
},
})
}
+
+func TestJavaLibraryLogTags(t *testing.T) {
+ runJavaLibraryTestCase(t, bp2buildTestCase{
+ description: "Java library - logtags creates separate dependency",
+ moduleTypeUnderTest: "java_library",
+ moduleTypeUnderTestFactory: java.LibraryFactory,
+ blueprint: `java_library {
+ name: "example_lib",
+ srcs: [
+ "a.java",
+ "b.java",
+ "a.logtag",
+ "b.logtag",
+ ],
+ bazel_module: { bp2build_available: true },
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("event_log_tags", "example_lib_logtags", attrNameToString{
+ "srcs": `[
+ "a.logtag",
+ "b.logtag",
+ ]`,
+ }),
+ makeBazelTarget("java_library", "example_lib", attrNameToString{
+ "srcs": `[
+ "a.java",
+ "b.java",
+ ":example_lib_logtags",
+ ]`,
+ }),
+ }})
+}
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index 4f7d88c..94b28dc 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -449,6 +449,7 @@
}
hasInstrumentationFor := hasNonEmptyLiteralStringProperty(mod, "instrumentation_for")
+ hasTestSuites := hasNonEmptyLiteralListProperty(mod, "test_suites")
tags, _ := getLiteralListPropertyValue(mod, "tags")
var hasTestsTag bool
@@ -458,7 +459,7 @@
}
}
- isTest := hasInstrumentationFor || hasTestsTag
+ isTest := hasInstrumentationFor || hasTestsTag || hasTestSuites
if isTest {
switch mod.Type {
@@ -470,13 +471,7 @@
mod.Type = "java_test"
case "java_library_host":
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 {
+ case "cc_binary":
mod.Type = "cc_test"
}
}
diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go
index 17b3c24..672e852 100644
--- a/bpfix/bpfix/bpfix_test.go
+++ b/bpfix/bpfix/bpfix_test.go
@@ -1436,6 +1436,38 @@
}
`,
},
+ {
+ name: "android_app with android_test",
+ in: `
+ android_app {
+ name: "foo",
+ srcs: ["srcs"],
+ test_suites: ["test_suite1"],
+ }
+ `,
+ out: `
+ android_test {
+ name: "foo",
+ srcs: ["srcs"],
+ test_suites: ["test_suite1"],
+ }
+ `,
+ },
+ {
+ name: "android_app without test_suites",
+ in: `
+ android_app {
+ name: "foo",
+ srcs: ["srcs"],
+ }
+ `,
+ out: `
+ android_app {
+ name: "foo",
+ srcs: ["srcs"],
+ }
+ `,
+ },
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
diff --git a/cc/afdo.go b/cc/afdo.go
index c888213..66e9732 100644
--- a/cc/afdo.go
+++ b/cc/afdo.go
@@ -45,6 +45,8 @@
}
type AfdoProperties struct {
+ // Afdo allows developers self-service enroll for
+ // automatic feedback-directed optimization using profile data.
Afdo bool
AfdoTarget *string `blueprint:"mutated"`
diff --git a/cc/cc.go b/cc/cc.go
index ac6da05..00b82d5 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1218,6 +1218,17 @@
return c.VendorProperties.IsVendorPublicLibrary
}
+func (c *Module) IsVndkPrebuiltLibrary() bool {
+ if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok {
+ return true
+ }
+ return false
+}
+
+func (c *Module) SdkAndPlatformVariantVisibleToMake() bool {
+ return c.Properties.SdkAndPlatformVariantVisibleToMake
+}
+
func (c *Module) HasLlndkStubs() bool {
lib := moduleLibraryInterface(c)
return lib != nil && lib.hasLLNDKStubs()
@@ -1699,7 +1710,7 @@
return nil
}
-func (c *Module) getNameSuffixWithVndkVersion(ctx android.ModuleContext) string {
+func getNameSuffixWithVndkVersion(ctx android.ModuleContext, c LinkableInterface) string {
// Returns the name suffix for product and vendor variants. If the VNDK version is not
// "current", it will append the VNDK version to the name suffix.
var vndkVersion string
@@ -1719,19 +1730,19 @@
if vndkVersion == "current" {
vndkVersion = ctx.DeviceConfig().PlatformVndkVersion()
}
- if c.Properties.VndkVersion != vndkVersion && c.Properties.VndkVersion != "" {
+ if c.VndkVersion() != vndkVersion && c.VndkVersion() != "" {
// add version suffix only if the module is using different vndk version than the
// version in product or vendor partition.
- nameSuffix += "." + c.Properties.VndkVersion
+ nameSuffix += "." + c.VndkVersion()
}
return nameSuffix
}
-func (c *Module) setSubnameProperty(actx android.ModuleContext) {
- c.Properties.SubName = ""
+func GetSubnameProperty(actx android.ModuleContext, c LinkableInterface) string {
+ var subName = ""
if c.Target().NativeBridge == android.NativeBridgeEnabled {
- c.Properties.SubName += NativeBridgeSuffix
+ subName += NativeBridgeSuffix
}
llndk := c.IsLlndk()
@@ -1739,25 +1750,27 @@
// .vendor.{version} suffix is added for vendor variant or .product.{version} suffix is
// added for product variant only when we have vendor and product variants with core
// variant. The suffix is not added for vendor-only or product-only module.
- c.Properties.SubName += c.getNameSuffixWithVndkVersion(actx)
+ subName += getNameSuffixWithVndkVersion(actx, c)
} else if c.IsVendorPublicLibrary() {
- c.Properties.SubName += vendorPublicLibrarySuffix
- } else if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok {
+ subName += vendorPublicLibrarySuffix
+ } else if c.IsVndkPrebuiltLibrary() {
// .vendor suffix is added for backward compatibility with VNDK snapshot whose names with
// such suffixes are already hard-coded in prebuilts/vndk/.../Android.bp.
- c.Properties.SubName += VendorSuffix
+ subName += VendorSuffix
} else if c.InRamdisk() && !c.OnlyInRamdisk() {
- c.Properties.SubName += RamdiskSuffix
+ subName += RamdiskSuffix
} else if c.InVendorRamdisk() && !c.OnlyInVendorRamdisk() {
- c.Properties.SubName += VendorRamdiskSuffix
+ subName += VendorRamdiskSuffix
} else if c.InRecovery() && !c.OnlyInRecovery() {
- c.Properties.SubName += RecoverySuffix
- } else if c.IsSdkVariant() && (c.Properties.SdkAndPlatformVariantVisibleToMake || c.SplitPerApiLevel()) {
- c.Properties.SubName += sdkSuffix
+ subName += RecoverySuffix
+ } else if c.IsSdkVariant() && (c.SdkAndPlatformVariantVisibleToMake() || c.SplitPerApiLevel()) {
+ subName += sdkSuffix
if c.SplitPerApiLevel() {
- c.Properties.SubName += "." + c.SdkVersion()
+ subName += "." + c.SdkVersion()
}
}
+
+ return subName
}
// Returns true if Bazel was successfully used for the analysis of this module.
@@ -1795,7 +1808,7 @@
return
}
- c.setSubnameProperty(actx)
+ c.Properties.SubName = GetSubnameProperty(actx, c)
apexInfo := actx.Provider(android.ApexInfoProvider).(android.ApexInfo)
if !apexInfo.IsForPlatform() {
c.hideApexVariantFromMake = true
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
index e1b0605..1a21c13 100644
--- a/cc/config/Android.bp
+++ b/cc/config/Android.bp
@@ -11,7 +11,6 @@
"soong-starlark-format",
],
srcs: [
- "bp2build.go",
"clang.go",
"global.go",
"tidy.go",
@@ -33,7 +32,6 @@
"arm64_linux_host.go",
],
testSrcs: [
- "bp2build_test.go",
"tidy_test.go",
],
}
diff --git a/cc/config/arm64_device.go b/cc/config/arm64_device.go
index 4d0ae1a..dfe143f 100644
--- a/cc/config/arm64_device.go
+++ b/cc/config/arm64_device.go
@@ -98,28 +98,28 @@
pctx.SourcePathVariable("Arm64GccRoot",
"prebuilts/gcc/${HostPrebuiltTag}/aarch64/aarch64-linux-android-${arm64GccVersion}")
- exportStringListStaticVariable("Arm64Ldflags", arm64Ldflags)
- exportStringListStaticVariable("Arm64Lldflags", arm64Lldflags)
+ exportedVars.ExportStringListStaticVariable("Arm64Ldflags", arm64Ldflags)
+ exportedVars.ExportStringListStaticVariable("Arm64Lldflags", arm64Lldflags)
- exportStringListStaticVariable("Arm64Cflags", arm64Cflags)
- exportStringListStaticVariable("Arm64Cppflags", arm64Cppflags)
+ exportedVars.ExportStringListStaticVariable("Arm64Cflags", arm64Cflags)
+ exportedVars.ExportStringListStaticVariable("Arm64Cppflags", arm64Cppflags)
- exportedVariableReferenceDictVars.Set("Arm64ArchVariantCflags", arm64ArchVariantCflagsVar)
- exportedVariableReferenceDictVars.Set("Arm64CpuVariantCflags", arm64CpuVariantCflagsVar)
- exportedVariableReferenceDictVars.Set("Arm64CpuVariantLdflags", arm64CpuVariantLdflags)
+ exportedVars.ExportVariableReferenceDict("Arm64ArchVariantCflags", arm64ArchVariantCflagsVar)
+ exportedVars.ExportVariableReferenceDict("Arm64CpuVariantCflags", arm64CpuVariantCflagsVar)
+ exportedVars.ExportVariableReferenceDict("Arm64CpuVariantLdflags", arm64CpuVariantLdflags)
- exportStringListStaticVariable("Arm64Armv8ACflags", arm64ArchVariantCflags["armv8-a"])
- exportStringListStaticVariable("Arm64Armv8ABranchProtCflags", arm64ArchVariantCflags["armv8-a-branchprot"])
- exportStringListStaticVariable("Arm64Armv82ACflags", arm64ArchVariantCflags["armv8-2a"])
- exportStringListStaticVariable("Arm64Armv82ADotprodCflags", arm64ArchVariantCflags["armv8-2a-dotprod"])
+ exportedVars.ExportStringListStaticVariable("Arm64Armv8ACflags", arm64ArchVariantCflags["armv8-a"])
+ exportedVars.ExportStringListStaticVariable("Arm64Armv8ABranchProtCflags", arm64ArchVariantCflags["armv8-a-branchprot"])
+ exportedVars.ExportStringListStaticVariable("Arm64Armv82ACflags", arm64ArchVariantCflags["armv8-2a"])
+ exportedVars.ExportStringListStaticVariable("Arm64Armv82ADotprodCflags", arm64ArchVariantCflags["armv8-2a-dotprod"])
- exportStringListStaticVariable("Arm64CortexA53Cflags", arm64CpuVariantCflags["cortex-a53"])
- exportStringListStaticVariable("Arm64CortexA55Cflags", arm64CpuVariantCflags["cortex-a55"])
- exportStringListStaticVariable("Arm64KryoCflags", arm64CpuVariantCflags["kryo"])
- exportStringListStaticVariable("Arm64ExynosM1Cflags", arm64CpuVariantCflags["exynos-m1"])
- exportStringListStaticVariable("Arm64ExynosM2Cflags", arm64CpuVariantCflags["exynos-m2"])
+ exportedVars.ExportStringListStaticVariable("Arm64CortexA53Cflags", arm64CpuVariantCflags["cortex-a53"])
+ exportedVars.ExportStringListStaticVariable("Arm64CortexA55Cflags", arm64CpuVariantCflags["cortex-a55"])
+ exportedVars.ExportStringListStaticVariable("Arm64KryoCflags", arm64CpuVariantCflags["kryo"])
+ exportedVars.ExportStringListStaticVariable("Arm64ExynosM1Cflags", arm64CpuVariantCflags["exynos-m1"])
+ exportedVars.ExportStringListStaticVariable("Arm64ExynosM2Cflags", arm64CpuVariantCflags["exynos-m2"])
- exportStringListStaticVariable("Arm64FixCortexA53Ldflags", []string{"-Wl,--fix-cortex-a53-843419"})
+ exportedVars.ExportStringListStaticVariable("Arm64FixCortexA53Ldflags", []string{"-Wl,--fix-cortex-a53-843419"})
}
var (
diff --git a/cc/config/arm_device.go b/cc/config/arm_device.go
index 4466632..d702c61 100644
--- a/cc/config/arm_device.go
+++ b/cc/config/arm_device.go
@@ -178,41 +178,41 @@
pctx.SourcePathVariable("ArmGccRoot", "prebuilts/gcc/${HostPrebuiltTag}/arm/arm-linux-androideabi-${armGccVersion}")
// Just exported. Not created as a Ninja static variable.
- exportedStringVars.Set("ArmClangTriple", clangTriple)
+ exportedVars.ExportString("ArmClangTriple", clangTriple)
- exportStringListStaticVariable("ArmLdflags", armLdflags)
- exportStringListStaticVariable("ArmLldflags", armLldflags)
+ exportedVars.ExportStringListStaticVariable("ArmLdflags", armLdflags)
+ exportedVars.ExportStringListStaticVariable("ArmLldflags", armLldflags)
- exportStringListStaticVariable("ArmFixCortexA8LdFlags", armFixCortexA8LdFlags)
- exportStringListStaticVariable("ArmNoFixCortexA8LdFlags", armNoFixCortexA8LdFlags)
+ exportedVars.ExportStringListStaticVariable("ArmFixCortexA8LdFlags", armFixCortexA8LdFlags)
+ exportedVars.ExportStringListStaticVariable("ArmNoFixCortexA8LdFlags", armNoFixCortexA8LdFlags)
// Clang cflags
- exportStringListStaticVariable("ArmToolchainCflags", armToolchainCflags)
- exportStringListStaticVariable("ArmCflags", armCflags)
- exportStringListStaticVariable("ArmCppflags", armCppflags)
+ exportedVars.ExportStringListStaticVariable("ArmToolchainCflags", armToolchainCflags)
+ exportedVars.ExportStringListStaticVariable("ArmCflags", armCflags)
+ exportedVars.ExportStringListStaticVariable("ArmCppflags", armCppflags)
// Clang ARM vs. Thumb instruction set cflags
- exportStringListStaticVariable("ArmArmCflags", armArmCflags)
- exportStringListStaticVariable("ArmThumbCflags", armThumbCflags)
+ exportedVars.ExportStringListStaticVariable("ArmArmCflags", armArmCflags)
+ exportedVars.ExportStringListStaticVariable("ArmThumbCflags", armThumbCflags)
- exportedVariableReferenceDictVars.Set("ArmArchVariantCflags", armArchVariantCflagsVar)
- exportedVariableReferenceDictVars.Set("ArmCpuVariantCflags", armCpuVariantCflagsVar)
+ exportedVars.ExportVariableReferenceDict("ArmArchVariantCflags", armArchVariantCflagsVar)
+ exportedVars.ExportVariableReferenceDict("ArmCpuVariantCflags", armCpuVariantCflagsVar)
// Clang arch variant cflags
- exportStringListStaticVariable("ArmArmv7ACflags", armArchVariantCflags["armv7-a"])
- exportStringListStaticVariable("ArmArmv7ANeonCflags", armArchVariantCflags["armv7-a-neon"])
- exportStringListStaticVariable("ArmArmv8ACflags", armArchVariantCflags["armv8-a"])
- exportStringListStaticVariable("ArmArmv82ACflags", armArchVariantCflags["armv8-2a"])
+ exportedVars.ExportStringListStaticVariable("ArmArmv7ACflags", armArchVariantCflags["armv7-a"])
+ exportedVars.ExportStringListStaticVariable("ArmArmv7ANeonCflags", armArchVariantCflags["armv7-a-neon"])
+ exportedVars.ExportStringListStaticVariable("ArmArmv8ACflags", armArchVariantCflags["armv8-a"])
+ exportedVars.ExportStringListStaticVariable("ArmArmv82ACflags", armArchVariantCflags["armv8-2a"])
// Clang cpu variant cflags
- 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"])
+ exportedVars.ExportStringListStaticVariable("ArmGenericCflags", armCpuVariantCflags[""])
+ exportedVars.ExportStringListStaticVariable("ArmCortexA7Cflags", armCpuVariantCflags["cortex-a7"])
+ exportedVars.ExportStringListStaticVariable("ArmCortexA8Cflags", armCpuVariantCflags["cortex-a8"])
+ exportedVars.ExportStringListStaticVariable("ArmCortexA15Cflags", armCpuVariantCflags["cortex-a15"])
+ exportedVars.ExportStringListStaticVariable("ArmCortexA53Cflags", armCpuVariantCflags["cortex-a53"])
+ exportedVars.ExportStringListStaticVariable("ArmCortexA55Cflags", armCpuVariantCflags["cortex-a55"])
+ exportedVars.ExportStringListStaticVariable("ArmKraitCflags", armCpuVariantCflags["krait"])
+ exportedVars.ExportStringListStaticVariable("ArmKryoCflags", armCpuVariantCflags["kryo"])
}
var (
diff --git a/cc/config/bp2build.go b/cc/config/bp2build.go
deleted file mode 100644
index 73f65f5..0000000
--- a/cc/config/bp2build.go
+++ /dev/null
@@ -1,378 +0,0 @@
-// 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 config
-
-import (
- "fmt"
- "reflect"
- "regexp"
- "sort"
- "strings"
-
- "android/soong/android"
- "android/soong/starlark_fmt"
-
- "github.com/google/blueprint"
-)
-
-type bazelVarExporter interface {
- asBazel(android.Config, exportedStringVariables, exportedStringListVariables, exportedConfigDependingVariables) []bazelConstant
-}
-
-// Helpers for exporting cc configuration information to Bazel.
-var (
- // Maps containing toolchain variables that are independent of the
- // environment variables of the build.
- exportedStringListVars = exportedStringListVariables{}
- exportedStringVars = exportedStringVariables{}
- exportedStringListDictVars = exportedStringListDictVariables{}
- // Note: these can only contain references to other variables and must be printed last
- exportedVariableReferenceDictVars = exportedVariableReferenceDictVariables{}
-
- /// Maps containing variables that are dependent on the build config.
- exportedConfigDependingVars = exportedConfigDependingVariables{}
-)
-
-type exportedConfigDependingVariables map[string]interface{}
-
-func (m exportedConfigDependingVariables) Set(k string, v interface{}) {
- m[k] = v
-}
-
-// Ensure that string s has no invalid characters to be generated into the bzl file.
-func validateCharacters(s string) string {
- for _, c := range []string{`\n`, `"`, `\`} {
- if strings.Contains(s, c) {
- panic(fmt.Errorf("%s contains illegal character %s", s, c))
- }
- }
- return s
-}
-
-type bazelConstant struct {
- variableName string
- internalDefinition string
- sortLast bool
-}
-
-type exportedStringVariables map[string]string
-
-func (m exportedStringVariables) Set(k string, v string) {
- m[k] = v
-}
-
-func (m exportedStringVariables) asBazel(config android.Config,
- stringVars exportedStringVariables, stringListVars exportedStringListVariables, cfgDepVars exportedConfigDependingVariables) []bazelConstant {
- ret := make([]bazelConstant, 0, len(m))
- for k, variableValue := range m {
- expandedVar, err := expandVar(config, variableValue, stringVars, stringListVars, cfgDepVars)
- if err != nil {
- panic(fmt.Errorf("error expanding config variable %s: %s", k, err))
- }
- if len(expandedVar) > 1 {
- panic(fmt.Errorf("%s expands to more than one string value: %s", variableValue, expandedVar))
- }
- ret = append(ret, bazelConstant{
- variableName: k,
- internalDefinition: fmt.Sprintf(`"%s"`, validateCharacters(expandedVar[0])),
- })
- }
- return ret
-}
-
-// Convenience function to declare a static variable and export it to Bazel's cc_toolchain.
-func exportStringStaticVariable(name string, value string) {
- pctx.StaticVariable(name, value)
- exportedStringVars.Set(name, value)
-}
-
-type exportedStringListVariables map[string][]string
-
-func (m exportedStringListVariables) Set(k string, v []string) {
- m[k] = v
-}
-
-func (m exportedStringListVariables) asBazel(config android.Config,
- stringScope exportedStringVariables, stringListScope exportedStringListVariables,
- exportedVars exportedConfigDependingVariables) []bazelConstant {
- ret := make([]bazelConstant, 0, len(m))
- // For each exported variable, recursively expand elements in the variableValue
- // list to ensure that interpolated variables are expanded according to their values
- // in the variable scope.
- for k, variableValue := range m {
- var expandedVars []string
- for _, v := range variableValue {
- expandedVar, err := expandVar(config, v, stringScope, stringListScope, exportedVars)
- if err != nil {
- panic(fmt.Errorf("Error expanding config variable %s=%s: %s", k, v, err))
- }
- expandedVars = append(expandedVars, expandedVar...)
- }
- // Assign the list as a bzl-private variable; this variable will be exported
- // out through a constants struct later.
- ret = append(ret, bazelConstant{
- variableName: k,
- internalDefinition: starlark_fmt.PrintStringList(expandedVars, 0),
- })
- }
- return ret
-}
-
-// Convenience function to declare a static "source path" variable and export it to Bazel's cc_toolchain.
-func exportVariableConfigMethod(name string, method interface{}) blueprint.Variable {
- exportedConfigDependingVars.Set(name, method)
- return pctx.VariableConfigMethod(name, method)
-}
-
-// Convenience function to declare a static "source path" variable and export it to Bazel's cc_toolchain.
-func exportSourcePathVariable(name string, value string) {
- pctx.SourcePathVariable(name, value)
- exportedStringVars.Set(name, value)
-}
-
-// Convenience function to declare a static variable and export it to Bazel's cc_toolchain.
-func exportStringListStaticVariable(name string, value []string) {
- pctx.StaticVariable(name, strings.Join(value, " "))
- exportedStringListVars.Set(name, value)
-}
-
-func ExportStringList(name string, value []string) {
- exportedStringListVars.Set(name, value)
-}
-
-type exportedStringListDictVariables map[string]map[string][]string
-
-func (m exportedStringListDictVariables) Set(k string, v map[string][]string) {
- m[k] = v
-}
-
-// Since dictionaries are not supported in Ninja, we do not expand variables for dictionaries
-func (m exportedStringListDictVariables) asBazel(_ android.Config, _ exportedStringVariables,
- _ exportedStringListVariables, _ exportedConfigDependingVariables) []bazelConstant {
- ret := make([]bazelConstant, 0, len(m))
- for k, dict := range m {
- ret = append(ret, bazelConstant{
- variableName: k,
- internalDefinition: starlark_fmt.PrintStringListDict(dict, 0),
- })
- }
- return ret
-}
-
-type exportedVariableReferenceDictVariables map[string]map[string]string
-
-func (m exportedVariableReferenceDictVariables) Set(k string, v map[string]string) {
- m[k] = v
-}
-
-func (m exportedVariableReferenceDictVariables) asBazel(_ android.Config, _ exportedStringVariables,
- _ exportedStringListVariables, _ exportedConfigDependingVariables) []bazelConstant {
- ret := make([]bazelConstant, 0, len(m))
- for n, dict := range m {
- for k, v := range dict {
- matches, err := variableReference(v)
- if err != nil {
- panic(err)
- } else if !matches.matches {
- panic(fmt.Errorf("Expected a variable reference, got %q", v))
- } else if len(matches.fullVariableReference) != len(v) {
- panic(fmt.Errorf("Expected only a variable reference, got %q", v))
- }
- dict[k] = "_" + matches.variable
- }
- ret = append(ret, bazelConstant{
- variableName: n,
- internalDefinition: starlark_fmt.PrintDict(dict, 0),
- sortLast: true,
- })
- }
- return ret
-}
-
-// BazelCcToolchainVars generates bzl file content containing variables for
-// Bazel's cc_toolchain configuration.
-func BazelCcToolchainVars(config android.Config) string {
- return bazelToolchainVars(
- config,
- exportedStringListDictVars,
- exportedStringListVars,
- exportedStringVars,
- exportedVariableReferenceDictVars)
-}
-
-func bazelToolchainVars(config android.Config, vars ...bazelVarExporter) string {
- ret := "# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.\n\n"
-
- results := []bazelConstant{}
- for _, v := range vars {
- results = append(results, v.asBazel(config, exportedStringVars, exportedStringListVars, exportedConfigDependingVars)...)
- }
-
- sort.Slice(results, func(i, j int) bool {
- if results[i].sortLast != results[j].sortLast {
- return !results[i].sortLast
- }
- return results[i].variableName < results[j].variableName
- })
-
- definitions := make([]string, 0, len(results))
- constants := make([]string, 0, len(results))
- for _, b := range results {
- definitions = append(definitions,
- fmt.Sprintf("_%s = %s", b.variableName, b.internalDefinition))
- constants = append(constants,
- fmt.Sprintf("%[1]s%[2]s = _%[2]s,", starlark_fmt.Indention(1), b.variableName))
- }
-
- // Build the exported constants struct.
- ret += strings.Join(definitions, "\n\n")
- ret += "\n\n"
- ret += "constants = struct(\n"
- ret += strings.Join(constants, "\n")
- ret += "\n)"
-
- return ret
-}
-
-type match struct {
- matches bool
- fullVariableReference string
- variable string
-}
-
-func variableReference(input string) (match, error) {
- // e.g. "${ExternalCflags}"
- r := regexp.MustCompile(`\${(?:config\.)?([a-zA-Z0-9_]+)}`)
-
- matches := r.FindStringSubmatch(input)
- if len(matches) == 0 {
- return match{}, nil
- }
- if len(matches) != 2 {
- return match{}, fmt.Errorf("Expected to only match 1 subexpression in %s, got %d", input, len(matches)-1)
- }
- return match{
- matches: true,
- fullVariableReference: matches[0],
- // Index 1 of FindStringSubmatch contains the subexpression match
- // (variable name) of the capture group.
- variable: matches[1],
- }, nil
-}
-
-// expandVar recursively expand interpolated variables in the exportedVars scope.
-//
-// We're using a string slice to track the seen variables to avoid
-// stackoverflow errors with infinite recursion. it's simpler to use a
-// 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(config android.Config, toExpand string, stringScope exportedStringVariables,
- stringListScope exportedStringListVariables, exportedVars exportedConfigDependingVariables) ([]string, error) {
-
- // Internal recursive function.
- var expandVarInternal func(string, map[string]bool) (string, error)
- expandVarInternal = func(toExpand string, seenVars map[string]bool) (string, error) {
- var ret string
- remainingString := toExpand
- for len(remainingString) > 0 {
- matches, err := variableReference(remainingString)
- if err != nil {
- panic(err)
- }
- if !matches.matches {
- return ret + remainingString, nil
- }
- matchIndex := strings.Index(remainingString, matches.fullVariableReference)
- ret += remainingString[:matchIndex]
- remainingString = remainingString[matchIndex+len(matches.fullVariableReference):]
-
- variable := matches.variable
- // toExpand contains a variable.
- if _, ok := seenVars[variable]; ok {
- return ret, fmt.Errorf(
- "Unbounded recursive interpolation of variable: %s", variable)
- }
- // A map is passed-by-reference. Create a new map for
- // this scope to prevent variables seen in one depth-first expansion
- // to be also treated as "seen" in other depth-first traversals.
- newSeenVars := map[string]bool{}
- for k := range seenVars {
- newSeenVars[k] = true
- }
- newSeenVars[variable] = true
- if unexpandedVars, ok := stringListScope[variable]; ok {
- expandedVars := []string{}
- for _, unexpandedVar := range unexpandedVars {
- expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars)
- if err != nil {
- return ret, err
- }
- expandedVars = append(expandedVars, expandedVar)
- }
- ret += strings.Join(expandedVars, " ")
- } else if unexpandedVar, ok := stringScope[variable]; ok {
- expandedVar, err := expandVarInternal(unexpandedVar, newSeenVars)
- if err != nil {
- return ret, err
- }
- ret += expandedVar
- } else if unevaluatedVar, ok := exportedVars[variable]; ok {
- evalFunc := reflect.ValueOf(unevaluatedVar)
- validateVariableMethod(variable, evalFunc)
- evaluatedResult := evalFunc.Call([]reflect.Value{reflect.ValueOf(config)})
- evaluatedValue := evaluatedResult[0].Interface().(string)
- expandedVar, err := expandVarInternal(evaluatedValue, newSeenVars)
- if err != nil {
- return ret, err
- }
- ret += expandedVar
- } else {
- return "", fmt.Errorf("Unbound config variable %s", variable)
- }
- }
- return ret, nil
- }
- var ret []string
- for _, v := range strings.Split(toExpand, " ") {
- val, err := expandVarInternal(v, map[string]bool{})
- if err != nil {
- return ret, err
- }
- ret = append(ret, val)
- }
-
- return ret, nil
-}
-
-func validateVariableMethod(name string, methodValue reflect.Value) {
- methodType := methodValue.Type()
- if methodType.Kind() != reflect.Func {
- panic(fmt.Errorf("method given for variable %s is not a function",
- name))
- }
- if n := methodType.NumIn(); n != 1 {
- panic(fmt.Errorf("method for variable %s has %d inputs (should be 1)",
- name, n))
- }
- if n := methodType.NumOut(); n != 1 {
- panic(fmt.Errorf("method for variable %s has %d outputs (should be 1)",
- name, n))
- }
- if kind := methodType.Out(0).Kind(); kind != reflect.String {
- panic(fmt.Errorf("method for variable %s does not return a string",
- name))
- }
-}
diff --git a/cc/config/bp2build_test.go b/cc/config/bp2build_test.go
deleted file mode 100644
index 9a8178a..0000000
--- a/cc/config/bp2build_test.go
+++ /dev/null
@@ -1,324 +0,0 @@
-// 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 config
-
-import (
- "testing"
-
- "android/soong/android"
-)
-
-func TestExpandVars(t *testing.T) {
- android_arm64_config := android.TestConfig("out", nil, "", nil)
- android_arm64_config.BuildOS = android.Android
- android_arm64_config.BuildArch = android.Arm64
-
- testCases := []struct {
- description string
- config android.Config
- stringScope exportedStringVariables
- stringListScope exportedStringListVariables
- configVars exportedConfigDependingVariables
- toExpand string
- expectedValues []string
- }{
- {
- 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 with short-name for string var",
- stringScope: exportedStringVariables{
- "foo": "bar",
- },
- toExpand: "${config.foo}",
- expectedValues: []string{"bar"},
- },
- {
- description: "single level expansion string list var",
- stringListScope: exportedStringListVariables{
- "foo": []string{"bar"},
- },
- 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",
- stringListScope: exportedStringListVariables{
- "foo": []string{"${bar}"},
- "bar": []string{"baz"},
- },
- toExpand: "${foo}",
- expectedValues: []string{"baz"},
- },
- {
- description: "double level expansion with a literal",
- 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",
- 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",
- stringListScope: exportedStringListVariables{
- "a": []string{"${b} ${c}"},
- "b": []string{"${c}", "${d}"},
- "c": []string{"${d}"},
- "d": []string{"foo"},
- },
- toExpand: "${a}",
- expectedValues: []string{"foo foo foo"},
- },
- {
- description: "expansion with config depending vars",
- configVars: exportedConfigDependingVariables{
- "a": func(c android.Config) string { return c.BuildOS.String() },
- "b": func(c android.Config) string { return c.BuildArch.String() },
- },
- config: android_arm64_config,
- toExpand: "${a}-${b}",
- expectedValues: []string{"android-arm64"},
- },
- {
- description: "double level multi type expansion",
- stringListScope: exportedStringListVariables{
- "platform": []string{"${os}-${arch}"},
- "const": []string{"const"},
- },
- configVars: exportedConfigDependingVariables{
- "os": func(c android.Config) string { return c.BuildOS.String() },
- "arch": func(c android.Config) string { return c.BuildArch.String() },
- "foo": func(c android.Config) string { return "foo" },
- },
- config: android_arm64_config,
- toExpand: "${const}/${platform}/${foo}",
- expectedValues: []string{"const/android-arm64/foo"},
- },
- }
-
- for _, testCase := range testCases {
- t.Run(testCase.description, func(t *testing.T) {
- output, _ := expandVar(testCase.config, testCase.toExpand, testCase.stringScope, testCase.stringListScope, testCase.configVars)
- if len(output) != len(testCase.expectedValues) {
- t.Errorf("Expected %d values, got %d", len(testCase.expectedValues), len(output))
- }
- for i, actual := range output {
- expectedValue := testCase.expectedValues[i]
- if actual != expectedValue {
- t.Errorf("Actual value '%s' doesn't match expected value '%s'", actual, expectedValue)
- }
- }
- })
- }
-}
-
-func TestBazelToolchainVars(t *testing.T) {
- testCases := []struct {
- name string
- config android.Config
- vars []bazelVarExporter
- expectedOut string
- }{
- {
- name: "exports strings",
- vars: []bazelVarExporter{
- exportedStringVariables{
- "a": "b",
- "c": "d",
- },
- },
- expectedOut: `# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.
-
-_a = "b"
-
-_c = "d"
-
-constants = struct(
- a = _a,
- c = _c,
-)`,
- },
- {
- name: "exports string lists",
- vars: []bazelVarExporter{
- exportedStringListVariables{
- "a": []string{"b1", "b2"},
- "c": []string{"d1", "d2"},
- },
- },
- expectedOut: `# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.
-
-_a = [
- "b1",
- "b2",
-]
-
-_c = [
- "d1",
- "d2",
-]
-
-constants = struct(
- a = _a,
- c = _c,
-)`,
- },
- {
- name: "exports string lists dicts",
- vars: []bazelVarExporter{
- exportedStringListDictVariables{
- "a": map[string][]string{"b1": []string{"b2"}},
- "c": map[string][]string{"d1": []string{"d2"}},
- },
- },
- expectedOut: `# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.
-
-_a = {
- "b1": ["b2"],
-}
-
-_c = {
- "d1": ["d2"],
-}
-
-constants = struct(
- a = _a,
- c = _c,
-)`,
- },
- {
- name: "exports dict with var refs",
- vars: []bazelVarExporter{
- exportedVariableReferenceDictVariables{
- "a": map[string]string{"b1": "${b2}"},
- "c": map[string]string{"d1": "${config.d2}"},
- },
- },
- expectedOut: `# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.
-
-_a = {
- "b1": _b2,
-}
-
-_c = {
- "d1": _d2,
-}
-
-constants = struct(
- a = _a,
- c = _c,
-)`,
- },
- {
- name: "sorts across types with variable references last",
- vars: []bazelVarExporter{
- exportedStringVariables{
- "b": "b-val",
- "d": "d-val",
- },
- exportedStringListVariables{
- "c": []string{"c-val"},
- "e": []string{"e-val"},
- },
- exportedStringListDictVariables{
- "a": map[string][]string{"a1": []string{"a2"}},
- "f": map[string][]string{"f1": []string{"f2"}},
- },
- exportedVariableReferenceDictVariables{
- "aa": map[string]string{"b1": "${b}"},
- "cc": map[string]string{"d1": "${config.d}"},
- },
- },
- expectedOut: `# GENERATED FOR BAZEL FROM SOONG. DO NOT EDIT.
-
-_a = {
- "a1": ["a2"],
-}
-
-_b = "b-val"
-
-_c = ["c-val"]
-
-_d = "d-val"
-
-_e = ["e-val"]
-
-_f = {
- "f1": ["f2"],
-}
-
-_aa = {
- "b1": _b,
-}
-
-_cc = {
- "d1": _d,
-}
-
-constants = struct(
- a = _a,
- b = _b,
- c = _c,
- d = _d,
- e = _e,
- f = _f,
- aa = _aa,
- cc = _cc,
-)`,
- },
- }
-
- for _, tc := range testCases {
- t.Run(tc.name, func(t *testing.T) {
- out := bazelToolchainVars(tc.config, tc.vars...)
- if out != tc.expectedOut {
- t.Errorf("Expected \n%s, got \n%s", tc.expectedOut, out)
- }
- })
- }
-}
diff --git a/cc/config/global.go b/cc/config/global.go
index dfb9a66..9c71683 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -23,6 +23,9 @@
)
var (
+ pctx = android.NewPackageContext("android/soong/cc/config")
+ exportedVars = android.NewExportedVariables(pctx)
+
// Flags used by lots of devices. Putting them in package static variables
// will save bytes in build.ninja so they aren't repeated for every file
commonGlobalCflags = []string{
@@ -296,20 +299,28 @@
WarningAllowedOldProjects = []string{}
)
-var pctx = android.NewPackageContext("android/soong/cc/config")
+// BazelCcToolchainVars generates bzl file content containing variables for
+// Bazel's cc_toolchain configuration.
+func BazelCcToolchainVars(config android.Config) string {
+ return android.BazelToolchainVars(config, exportedVars)
+}
+
+func ExportStringList(name string, value []string) {
+ exportedVars.ExportStringList(name, value)
+}
func init() {
if runtime.GOOS == "linux" {
commonGlobalCflags = append(commonGlobalCflags, "-fdebug-prefix-map=/proc/self/cwd=")
}
- exportStringListStaticVariable("CommonGlobalConlyflags", commonGlobalConlyflags)
- exportStringListStaticVariable("DeviceGlobalCppflags", deviceGlobalCppflags)
- exportStringListStaticVariable("DeviceGlobalLdflags", deviceGlobalLdflags)
- exportStringListStaticVariable("DeviceGlobalLldflags", deviceGlobalLldflags)
- exportStringListStaticVariable("HostGlobalCppflags", hostGlobalCppflags)
- exportStringListStaticVariable("HostGlobalLdflags", hostGlobalLdflags)
- exportStringListStaticVariable("HostGlobalLldflags", hostGlobalLldflags)
+ exportedVars.ExportStringListStaticVariable("CommonGlobalConlyflags", commonGlobalConlyflags)
+ exportedVars.ExportStringListStaticVariable("DeviceGlobalCppflags", deviceGlobalCppflags)
+ exportedVars.ExportStringListStaticVariable("DeviceGlobalLdflags", deviceGlobalLdflags)
+ exportedVars.ExportStringListStaticVariable("DeviceGlobalLldflags", deviceGlobalLldflags)
+ exportedVars.ExportStringListStaticVariable("HostGlobalCppflags", hostGlobalCppflags)
+ exportedVars.ExportStringListStaticVariable("HostGlobalLdflags", hostGlobalLdflags)
+ exportedVars.ExportStringListStaticVariable("HostGlobalLldflags", hostGlobalLldflags)
// Export the static default CommonGlobalCflags to Bazel.
// TODO(187086342): handle cflags that are set in VariableFuncs.
@@ -320,7 +331,7 @@
"-ftrivial-auto-var-init=zero",
"-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang",
}...)
- exportedStringListVars.Set("CommonGlobalCflags", bazelCommonGlobalCflags)
+ exportedVars.ExportStringList("CommonGlobalCflags", bazelCommonGlobalCflags)
pctx.VariableFunc("CommonGlobalCflags", func(ctx android.PackageVarContext) string {
flags := commonGlobalCflags
@@ -349,17 +360,17 @@
// Export the static default DeviceGlobalCflags to Bazel.
// TODO(187086342): handle cflags that are set in VariableFuncs.
- exportedStringListVars.Set("DeviceGlobalCflags", deviceGlobalCflags)
+ exportedVars.ExportStringList("DeviceGlobalCflags", deviceGlobalCflags)
pctx.VariableFunc("DeviceGlobalCflags", func(ctx android.PackageVarContext) string {
return strings.Join(deviceGlobalCflags, " ")
})
- exportStringListStaticVariable("HostGlobalCflags", hostGlobalCflags)
- exportStringListStaticVariable("NoOverrideGlobalCflags", noOverrideGlobalCflags)
- exportStringListStaticVariable("NoOverrideExternalGlobalCflags", noOverrideExternalGlobalCflags)
- exportStringListStaticVariable("CommonGlobalCppflags", commonGlobalCppflags)
- exportStringListStaticVariable("ExternalCflags", extraExternalCflags)
+ exportedVars.ExportStringListStaticVariable("HostGlobalCflags", hostGlobalCflags)
+ exportedVars.ExportStringListStaticVariable("NoOverrideGlobalCflags", noOverrideGlobalCflags)
+ exportedVars.ExportStringListStaticVariable("NoOverrideExternalGlobalCflags", noOverrideExternalGlobalCflags)
+ exportedVars.ExportStringListStaticVariable("CommonGlobalCppflags", commonGlobalCppflags)
+ exportedVars.ExportStringListStaticVariable("ExternalCflags", extraExternalCflags)
// Everything in these lists is a crime against abstraction and dependency tracking.
// Do not add anything to this list.
@@ -374,11 +385,11 @@
"frameworks/native/opengl/include",
"frameworks/av/include",
}
- exportedStringListVars.Set("CommonGlobalIncludes", commonGlobalIncludes)
+ exportedVars.ExportStringList("CommonGlobalIncludes", commonGlobalIncludes)
pctx.PrefixedExistentPathsForSourcesVariable("CommonGlobalIncludes", "-I", commonGlobalIncludes)
- exportStringStaticVariable("CLANG_DEFAULT_VERSION", ClangDefaultVersion)
- exportStringStaticVariable("CLANG_DEFAULT_SHORT_VERSION", ClangDefaultShortVersion)
+ exportedVars.ExportStringStaticVariable("CLANG_DEFAULT_VERSION", ClangDefaultVersion)
+ exportedVars.ExportStringStaticVariable("CLANG_DEFAULT_SHORT_VERSION", ClangDefaultShortVersion)
pctx.StaticVariableWithEnvOverride("ClangBase", "LLVM_PREBUILTS_BASE", ClangDefaultBase)
pctx.StaticVariableWithEnvOverride("ClangVersion", "LLVM_PREBUILTS_VERSION", ClangDefaultVersion)
@@ -418,7 +429,7 @@
pctx.StaticVariableWithEnvOverride("REAbiLinkerExecStrategy", "RBE_ABI_LINKER_EXEC_STRATEGY", remoteexec.LocalExecStrategy)
}
-var HostPrebuiltTag = exportVariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
+var HostPrebuiltTag = exportedVars.ExportVariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS)
func ClangPath(ctx android.PathContext, file string) android.SourcePath {
type clangToolKey string
diff --git a/cc/config/x86_64_device.go b/cc/config/x86_64_device.go
index 164e7a6..aebda0b 100644
--- a/cc/config/x86_64_device.go
+++ b/cc/config/x86_64_device.go
@@ -91,26 +91,26 @@
pctx.SourcePathVariable("X86_64GccRoot",
"prebuilts/gcc/${HostPrebuiltTag}/x86/x86_64-linux-android-${x86_64GccVersion}")
- exportStringListStaticVariable("X86_64ToolchainCflags", []string{"-m64"})
- exportStringListStaticVariable("X86_64ToolchainLdflags", []string{"-m64"})
+ exportedVars.ExportStringListStaticVariable("X86_64ToolchainCflags", []string{"-m64"})
+ exportedVars.ExportStringListStaticVariable("X86_64ToolchainLdflags", []string{"-m64"})
- exportStringListStaticVariable("X86_64Ldflags", x86_64Ldflags)
- exportStringListStaticVariable("X86_64Lldflags", x86_64Ldflags)
+ exportedVars.ExportStringListStaticVariable("X86_64Ldflags", x86_64Ldflags)
+ exportedVars.ExportStringListStaticVariable("X86_64Lldflags", x86_64Ldflags)
// Clang cflags
- exportStringListStaticVariable("X86_64Cflags", x86_64Cflags)
- exportStringListStaticVariable("X86_64Cppflags", x86_64Cppflags)
+ exportedVars.ExportStringListStaticVariable("X86_64Cflags", x86_64Cflags)
+ exportedVars.ExportStringListStaticVariable("X86_64Cppflags", x86_64Cppflags)
// Yasm flags
- exportStringListStaticVariable("X86_64YasmFlags", []string{
+ exportedVars.ExportStringListStaticVariable("X86_64YasmFlags", []string{
"-f elf64",
"-m amd64",
})
// Extended cflags
- exportedStringListDictVars.Set("X86_64ArchVariantCflags", x86_64ArchVariantCflags)
- exportedStringListDictVars.Set("X86_64ArchFeatureCflags", x86_64ArchFeatureCflags)
+ exportedVars.ExportStringListDict("X86_64ArchVariantCflags", x86_64ArchVariantCflags)
+ exportedVars.ExportStringListDict("X86_64ArchFeatureCflags", x86_64ArchFeatureCflags)
// Architecture variant cflags
for variant, cflags := range x86_64ArchVariantCflags {
diff --git a/cc/config/x86_device.go b/cc/config/x86_device.go
index e32e1bd..421b083 100644
--- a/cc/config/x86_device.go
+++ b/cc/config/x86_device.go
@@ -98,25 +98,25 @@
pctx.SourcePathVariable("X86GccRoot",
"prebuilts/gcc/${HostPrebuiltTag}/x86/x86_64-linux-android-${x86GccVersion}")
- exportStringListStaticVariable("X86ToolchainCflags", []string{"-m32"})
- exportStringListStaticVariable("X86ToolchainLdflags", []string{"-m32"})
+ exportedVars.ExportStringListStaticVariable("X86ToolchainCflags", []string{"-m32"})
+ exportedVars.ExportStringListStaticVariable("X86ToolchainLdflags", []string{"-m32"})
- exportStringListStaticVariable("X86Ldflags", x86Ldflags)
- exportStringListStaticVariable("X86Lldflags", x86Ldflags)
+ exportedVars.ExportStringListStaticVariable("X86Ldflags", x86Ldflags)
+ exportedVars.ExportStringListStaticVariable("X86Lldflags", x86Ldflags)
// Clang cflags
- exportStringListStaticVariable("X86Cflags", x86Cflags)
- exportStringListStaticVariable("X86Cppflags", x86Cppflags)
+ exportedVars.ExportStringListStaticVariable("X86Cflags", x86Cflags)
+ exportedVars.ExportStringListStaticVariable("X86Cppflags", x86Cppflags)
// Yasm flags
- exportStringListStaticVariable("X86YasmFlags", []string{
+ exportedVars.ExportStringListStaticVariable("X86YasmFlags", []string{
"-f elf32",
"-m x86",
})
// Extended cflags
- exportedStringListDictVars.Set("X86ArchVariantCflags", x86ArchVariantCflags)
- exportedStringListDictVars.Set("X86ArchFeatureCflags", x86ArchFeatureCflags)
+ exportedVars.ExportStringListDict("X86ArchVariantCflags", x86ArchVariantCflags)
+ exportedVars.ExportStringListDict("X86ArchFeatureCflags", x86ArchFeatureCflags)
// Architecture variant cflags
for variant, cflags := range x86ArchVariantCflags {
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index e1659d3..4e8fd77 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -121,40 +121,40 @@
)
func init() {
- exportStringStaticVariable("LinuxGccVersion", linuxGccVersion)
- exportStringStaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
+ exportedVars.ExportStringStaticVariable("LinuxGccVersion", linuxGccVersion)
+ exportedVars.ExportStringStaticVariable("LinuxGlibcVersion", linuxGlibcVersion)
// Most places use the full GCC version. A few only use up to the first two numbers.
if p := strings.Split(linuxGccVersion, "."); len(p) > 2 {
- exportStringStaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
+ exportedVars.ExportStringStaticVariable("ShortLinuxGccVersion", strings.Join(p[:2], "."))
} else {
- exportStringStaticVariable("ShortLinuxGccVersion", linuxGccVersion)
+ exportedVars.ExportStringStaticVariable("ShortLinuxGccVersion", linuxGccVersion)
}
- exportSourcePathVariable("LinuxGccRoot",
+ exportedVars.ExportSourcePathVariable("LinuxGccRoot",
"prebuilts/gcc/linux-x86/host/x86_64-linux-glibc${LinuxGlibcVersion}-${ShortLinuxGccVersion}")
- exportStringListStaticVariable("LinuxGccTriple", []string{"x86_64-linux"})
+ exportedVars.ExportStringListStaticVariable("LinuxGccTriple", []string{"x86_64-linux"})
- exportStringListStaticVariable("LinuxCflags", linuxCflags)
- exportStringListStaticVariable("LinuxLdflags", linuxLdflags)
- exportStringListStaticVariable("LinuxLldflags", linuxLdflags)
- exportStringListStaticVariable("LinuxGlibcCflags", linuxGlibcCflags)
- exportStringListStaticVariable("LinuxGlibcLdflags", linuxGlibcLdflags)
- exportStringListStaticVariable("LinuxGlibcLldflags", linuxGlibcLdflags)
- exportStringListStaticVariable("LinuxMuslCflags", linuxMuslCflags)
- exportStringListStaticVariable("LinuxMuslLdflags", linuxMuslLdflags)
- exportStringListStaticVariable("LinuxMuslLldflags", linuxMuslLdflags)
+ exportedVars.ExportStringListStaticVariable("LinuxCflags", linuxCflags)
+ exportedVars.ExportStringListStaticVariable("LinuxLdflags", linuxLdflags)
+ exportedVars.ExportStringListStaticVariable("LinuxLldflags", linuxLdflags)
+ exportedVars.ExportStringListStaticVariable("LinuxGlibcCflags", linuxGlibcCflags)
+ exportedVars.ExportStringListStaticVariable("LinuxGlibcLdflags", linuxGlibcLdflags)
+ exportedVars.ExportStringListStaticVariable("LinuxGlibcLldflags", linuxGlibcLdflags)
+ exportedVars.ExportStringListStaticVariable("LinuxMuslCflags", linuxMuslCflags)
+ exportedVars.ExportStringListStaticVariable("LinuxMuslLdflags", linuxMuslLdflags)
+ exportedVars.ExportStringListStaticVariable("LinuxMuslLldflags", linuxMuslLdflags)
- exportStringListStaticVariable("LinuxX86Cflags", linuxX86Cflags)
- exportStringListStaticVariable("LinuxX8664Cflags", linuxX8664Cflags)
- exportStringListStaticVariable("LinuxX86Ldflags", linuxX86Ldflags)
- exportStringListStaticVariable("LinuxX86Lldflags", linuxX86Ldflags)
- exportStringListStaticVariable("LinuxX8664Ldflags", linuxX8664Ldflags)
- exportStringListStaticVariable("LinuxX8664Lldflags", linuxX8664Ldflags)
+ exportedVars.ExportStringListStaticVariable("LinuxX86Cflags", linuxX86Cflags)
+ exportedVars.ExportStringListStaticVariable("LinuxX8664Cflags", linuxX8664Cflags)
+ exportedVars.ExportStringListStaticVariable("LinuxX86Ldflags", linuxX86Ldflags)
+ exportedVars.ExportStringListStaticVariable("LinuxX86Lldflags", linuxX86Ldflags)
+ exportedVars.ExportStringListStaticVariable("LinuxX8664Ldflags", linuxX8664Ldflags)
+ exportedVars.ExportStringListStaticVariable("LinuxX8664Lldflags", linuxX8664Ldflags)
// Yasm flags
- exportStringListStaticVariable("LinuxX86YasmFlags", []string{"-f elf32 -m x86"})
- exportStringListStaticVariable("LinuxX8664YasmFlags", []string{"-f elf64 -m amd64"})
+ exportedVars.ExportStringListStaticVariable("LinuxX86YasmFlags", []string{"-f elf32 -m x86"})
+ exportedVars.ExportStringListStaticVariable("LinuxX8664YasmFlags", []string{"-f elf64 -m amd64"})
}
type toolchainLinux struct {
diff --git a/cc/linkable.go b/cc/linkable.go
index d4b4770..6bec30c 100644
--- a/cc/linkable.go
+++ b/cc/linkable.go
@@ -176,10 +176,14 @@
IsVndk() bool
IsVndkExt() bool
IsVndkPrivate() bool
+ IsVendorPublicLibrary() bool
+ IsVndkPrebuiltLibrary() bool
HasVendorVariant() bool
HasProductVariant() bool
HasNonSystemVariants() bool
+ ProductSpecific() bool
InProduct() bool
+ SdkAndPlatformVariantVisibleToMake() bool
// SubName returns the modules SubName, used for image and NDK/SDK variations.
SubName() string
diff --git a/cc/pgo.go b/cc/pgo.go
index aa0feae..0632c15 100644
--- a/cc/pgo.go
+++ b/cc/pgo.go
@@ -32,8 +32,8 @@
}
globalPgoProfileProjects = []string{
- "toolchain/pgo-profiles",
- "vendor/google_data/pgo_profile",
+ "toolchain/pgo-profiles/pgo",
+ "vendor/google_data/pgo_profile/pgo",
}
)
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index 03ce2d5..4f7451d 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -750,7 +750,7 @@
return false
}
defer fileA.Close()
- fileB, err := os.Open(a)
+ fileB, err := os.Open(b)
if err != nil {
return false
}
diff --git a/cmd/sbox/sbox_test.go b/cmd/sbox/sbox_test.go
new file mode 100644
index 0000000..3f13d2f
--- /dev/null
+++ b/cmd/sbox/sbox_test.go
@@ -0,0 +1,127 @@
+// Copyright 2022 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package main
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+ "testing"
+)
+
+func Test_filesHaveSameContents(t *testing.T) {
+
+ tests := []struct {
+ name string
+ a string
+ b string
+ missingA bool
+ missingB bool
+
+ equal bool
+ }{
+ {
+ name: "empty",
+ a: "",
+ b: "",
+ equal: true,
+ },
+ {
+ name: "equal",
+ a: "foo",
+ b: "foo",
+ equal: true,
+ },
+ {
+ name: "unequal",
+ a: "foo",
+ b: "bar",
+ equal: false,
+ },
+ {
+ name: "unequal different sizes",
+ a: "foo",
+ b: "foobar",
+ equal: false,
+ },
+ {
+ name: "equal large",
+ a: strings.Repeat("a", 2*1024*1024),
+ b: strings.Repeat("a", 2*1024*1024),
+ equal: true,
+ },
+ {
+ name: "equal large unaligned",
+ a: strings.Repeat("a", 2*1024*1024+10),
+ b: strings.Repeat("a", 2*1024*1024+10),
+ equal: true,
+ },
+ {
+ name: "unequal large",
+ a: strings.Repeat("a", 2*1024*1024),
+ b: strings.Repeat("a", 2*1024*1024-1) + "b",
+ equal: false,
+ },
+ {
+ name: "unequal large unaligned",
+ a: strings.Repeat("a", 2*1024*1024+10),
+ b: strings.Repeat("a", 2*1024*1024+9) + "b",
+ equal: false,
+ },
+ {
+ name: "missing a",
+ missingA: true,
+ b: "foo",
+ equal: false,
+ },
+ {
+ name: "missing b",
+ a: "foo",
+ missingB: true,
+ equal: false,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ tempDir, err := os.MkdirTemp("", "testFilesHaveSameContents")
+ if err != nil {
+ t.Fatalf("failed to create temp dir: %s", err)
+ }
+ defer os.RemoveAll(tempDir)
+
+ fileA := filepath.Join(tempDir, "a")
+ fileB := filepath.Join(tempDir, "b")
+
+ if !tt.missingA {
+ err := ioutil.WriteFile(fileA, []byte(tt.a), 0666)
+ if err != nil {
+ t.Fatalf("failed to write %s: %s", fileA, err)
+ }
+ }
+
+ if !tt.missingB {
+ err := ioutil.WriteFile(fileB, []byte(tt.b), 0666)
+ if err != nil {
+ t.Fatalf("failed to write %s: %s", fileB, err)
+ }
+ }
+
+ if got := filesHaveSameContents(fileA, fileB); got != tt.equal {
+ t.Errorf("filesHaveSameContents() = %v, want %v", got, tt.equal)
+ }
+ })
+ }
+}
diff --git a/cmd/symbols_map/elf.go b/cmd/symbols_map/elf.go
index 3c8b1e4..950e3b2 100644
--- a/cmd/symbols_map/elf.go
+++ b/cmd/symbols_map/elf.go
@@ -38,13 +38,13 @@
return elfIdentifierFromReaderAt(f, filename, allowMissing)
}
-// elfIdentifier extracts the elf build ID from a ReaderAt. If allowMissing is true it returns
-// an empty identifier if the file exists but the build ID note does not.
+// elfIdentifierFromReaderAt extracts the elf build ID from a ReaderAt. If allowMissing is true it
+// returns an empty identifier if the file exists but the build ID note does not.
func elfIdentifierFromReaderAt(r io.ReaderAt, filename string, allowMissing bool) (string, error) {
f, err := elf.NewFile(r)
if err != nil {
if allowMissing {
- if errors.Is(err, io.EOF) {
+ if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) {
return "", nil
}
if _, ok := err.(*elf.FormatError); ok {
diff --git a/cmd/symbols_map/elf_test.go b/cmd/symbols_map/elf_test.go
index b96ea59..a94c87f 100644
--- a/cmd/symbols_map/elf_test.go
+++ b/cmd/symbols_map/elf_test.go
@@ -39,6 +39,10 @@
name: "empty elf",
contents: emptyElfFile(),
},
+ {
+ name: "short section header",
+ contents: shortSectionHeaderElfFile(),
+ },
}
for _, tt := range tests {
@@ -111,3 +115,38 @@
binary.Write(buf, binary.LittleEndian, header)
return buf.String()
}
+
+// shortSectionHeader returns an elf file header with a section header that extends past the end of
+// the file.
+func shortSectionHeaderElfFile() string {
+ ident := [elf.EI_NIDENT]byte{}
+ identBuf := bytes.NewBuffer(ident[0:0:elf.EI_NIDENT])
+ binary.Write(identBuf, binary.LittleEndian, []byte("\x7fELF"))
+ binary.Write(identBuf, binary.LittleEndian, elf.ELFCLASS64)
+ binary.Write(identBuf, binary.LittleEndian, elf.ELFDATA2LSB)
+ binary.Write(identBuf, binary.LittleEndian, elf.EV_CURRENT)
+ binary.Write(identBuf, binary.LittleEndian, elf.ELFOSABI_LINUX)
+ binary.Write(identBuf, binary.LittleEndian, make([]byte, 8))
+
+ header := elf.Header64{
+ Ident: ident,
+ Type: uint16(elf.ET_EXEC),
+ Machine: uint16(elf.EM_X86_64),
+ Version: uint32(elf.EV_CURRENT),
+ Entry: 0,
+ Phoff: uint64(binary.Size(elf.Header64{})),
+ Shoff: uint64(binary.Size(elf.Header64{})),
+ Flags: 0,
+ Ehsize: uint16(binary.Size(elf.Header64{})),
+ Phentsize: 0x38,
+ Phnum: 0,
+ Shentsize: 0x40,
+ Shnum: 1,
+ Shstrndx: 0,
+ }
+
+ buf := &bytes.Buffer{}
+ binary.Write(buf, binary.LittleEndian, header)
+ binary.Write(buf, binary.LittleEndian, []byte{0})
+ return buf.String()
+}
diff --git a/java/app.go b/java/app.go
index 21ee34e..2b52eab 100755
--- a/java/app.go
+++ b/java/app.go
@@ -638,7 +638,21 @@
}
certificates := processMainCert(a.ModuleBase, a.getCertString(ctx), certificateDeps, ctx)
- a.certificate = certificates[0]
+
+ // This can be reached with an empty certificate list if AllowMissingDependencies is set
+ // and the certificate property for this module is a module reference to a missing module.
+ if len(certificates) > 0 {
+ a.certificate = certificates[0]
+ } else {
+ if !ctx.Config().AllowMissingDependencies() && len(ctx.GetMissingDependencies()) > 0 {
+ panic("Should only get here if AllowMissingDependencies set and there are missing dependencies")
+ }
+ // Set a certificate to avoid panics later when accessing it.
+ a.certificate = Certificate{
+ Key: android.PathForModuleOut(ctx, "missing.pk8"),
+ Pem: android.PathForModuleOut(ctx, "missing.pem"),
+ }
+ }
// Build a final signed app package.
packageFile := android.PathForModuleOut(ctx, a.installApkName+".apk")
diff --git a/java/app_test.go b/java/app_test.go
index 08baf54..6a4508c 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2948,3 +2948,24 @@
android.AssertStringDoesContain(t, testCase.name, manifestFixerArgs, "--targetSdkVersion "+testCase.targetSdkVersionExpected)
}
}
+
+func TestAppMissingCertificateAllowMissingDependencies(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ android.PrepareForTestWithAllowMissingDependencies,
+ android.PrepareForTestWithAndroidMk,
+ ).RunTestWithBp(t, `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ certificate: ":missing_certificate",
+ sdk_version: "current",
+ }`)
+
+ foo := result.ModuleForTests("foo", "android_common")
+ fooApk := foo.Output("foo.apk")
+ if fooApk.Rule != android.ErrorRule {
+ t.Fatalf("expected ErrorRule for foo.apk, got %s", fooApk.Rule.String())
+ }
+ android.AssertStringDoesContain(t, "expected error rule message", fooApk.Args["error"], "missing dependencies: missing_certificate\n")
+}
diff --git a/java/config/config.go b/java/config/config.go
index 262c531..95b841f 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -26,7 +26,8 @@
)
var (
- pctx = android.NewPackageContext("android/soong/java/config")
+ pctx = android.NewPackageContext("android/soong/java/config")
+ exportedVars = android.NewExportedVariables(pctx)
LegacyCorePlatformBootclasspathLibraries = []string{"legacy.core.platform.api.stubs", "core-lambda-stubs"}
LegacyCorePlatformSystemModules = "legacy-core-platform-api-stubs-system-modules"
@@ -53,25 +54,40 @@
}
)
-const (
- JavaVmFlags = `-XX:OnError="cat hs_err_pid%p.log" -XX:CICompilerCount=6 -XX:+UseDynamicNumberOfGCThreads`
- JavacVmFlags = `-J-XX:OnError="cat hs_err_pid%p.log" -J-XX:CICompilerCount=6 -J-XX:+UseDynamicNumberOfGCThreads -J-XX:+TieredCompilation -J-XX:TieredStopAtLevel=1`
+var (
+ JavacVmFlags = strings.Join(javacVmFlagsList, " ")
+ javaVmFlagsList = []string{
+ `-XX:OnError="cat hs_err_pid%p.log"`,
+ "-XX:CICompilerCount=6",
+ "-XX:+UseDynamicNumberOfGCThreads",
+ }
+ javacVmFlagsList = []string{
+ `-J-XX:OnError="cat hs_err_pid%p.log"`,
+ "-J-XX:CICompilerCount=6",
+ "-J-XX:+UseDynamicNumberOfGCThreads",
+ "-J-XX:+TieredCompilation",
+ "-J-XX:TieredStopAtLevel=1",
+ }
)
func init() {
pctx.Import("github.com/google/blueprint/bootstrap")
- pctx.StaticVariable("JavacHeapSize", "2048M")
- pctx.StaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
+ exportedVars.ExportStringStaticVariable("JavacHeapSize", "2048M")
+ exportedVars.ExportStringStaticVariable("JavacHeapFlags", "-J-Xmx${JavacHeapSize}")
// ErrorProne can use significantly more memory than javac alone, give it a higher heap
// size (b/221480398).
- pctx.StaticVariable("ErrorProneHeapSize", "4096M")
- pctx.StaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
+ exportedVars.ExportStringStaticVariable("ErrorProneHeapSize", "4096M")
+ exportedVars.ExportStringStaticVariable("ErrorProneHeapFlags", "-J-Xmx${ErrorProneHeapSize}")
- pctx.StaticVariable("DexFlags", "-JXX:OnError='cat hs_err_pid%p.log' -JXX:CICompilerCount=6 -JXX:+UseDynamicNumberOfGCThreads")
+ exportedVars.ExportStringListStaticVariable("DexFlags", []string{
+ `-JXX:OnError="cat hs_err_pid%p.log"`,
+ "-JXX:CICompilerCount=6",
+ "-JXX:+UseDynamicNumberOfGCThreads",
+ })
- pctx.StaticVariable("CommonJdkFlags", strings.Join([]string{
+ exportedVars.ExportStringListStaticVariable("CommonJdkFlags", []string{
`-Xmaxerrs 9999999`,
`-encoding UTF-8`,
`-sourcepath ""`,
@@ -85,10 +101,10 @@
// b/65004097: prevent using java.lang.invoke.StringConcatFactory when using -target 1.9
`-XDstringConcat=inline`,
- }, " "))
+ })
- pctx.StaticVariable("JavaVmFlags", JavaVmFlags)
- pctx.StaticVariable("JavacVmFlags", JavacVmFlags)
+ exportedVars.ExportStringListStaticVariable("JavaVmFlags", javaVmFlagsList)
+ exportedVars.ExportStringListStaticVariable("JavacVmFlags", javacVmFlagsList)
pctx.VariableConfigMethod("hostPrebuiltTag", android.Config.PrebuiltOS)
@@ -184,6 +200,10 @@
hostJNIToolVariableWithSdkToolsPrebuilt("SignapkJniLibrary", "libconscrypt_openjdk_jni")
}
+func BazelJavaToolchainVars(config android.Config) string {
+ return android.BazelToolchainVars(config, exportedVars)
+}
+
func hostBinToolVariableWithSdkToolsPrebuilt(name, tool string) {
pctx.VariableFunc(name, func(ctx android.PackageVarContext) string {
if ctx.Config().AlwaysUsePrebuiltSdks() {
diff --git a/java/config/error_prone.go b/java/config/error_prone.go
index 48681b5..5f853c8 100644
--- a/java/config/error_prone.go
+++ b/java/config/error_prone.go
@@ -16,8 +16,6 @@
import (
"strings"
-
- "android/soong/android"
)
var (
@@ -31,23 +29,23 @@
)
// Wrapper that grabs value of val late so it can be initialized by a later module's init function
-func errorProneVar(name string, val *[]string, sep string) {
- pctx.VariableFunc(name, func(android.PackageVarContext) string {
+func errorProneVar(val *[]string, sep string) func() string {
+ return func() string {
return strings.Join(*val, sep)
- })
+ }
}
func init() {
- errorProneVar("ErrorProneClasspath", &ErrorProneClasspath, ":")
- errorProneVar("ErrorProneChecksError", &ErrorProneChecksError, " ")
- errorProneVar("ErrorProneChecksWarning", &ErrorProneChecksWarning, " ")
- errorProneVar("ErrorProneChecksDefaultDisabled", &ErrorProneChecksDefaultDisabled, " ")
- errorProneVar("ErrorProneChecksOff", &ErrorProneChecksOff, " ")
- errorProneVar("ErrorProneFlags", &ErrorProneFlags, " ")
- pctx.StaticVariable("ErrorProneChecks", strings.Join([]string{
+ exportedVars.ExportVariableFuncVariable("ErrorProneClasspath", errorProneVar(&ErrorProneClasspath, ":"))
+ exportedVars.ExportVariableFuncVariable("ErrorProneChecksError", errorProneVar(&ErrorProneChecksError, " "))
+ exportedVars.ExportVariableFuncVariable("ErrorProneChecksWarning", errorProneVar(&ErrorProneChecksWarning, " "))
+ exportedVars.ExportVariableFuncVariable("ErrorProneChecksDefaultDisabled", errorProneVar(&ErrorProneChecksDefaultDisabled, " "))
+ exportedVars.ExportVariableFuncVariable("ErrorProneChecksOff", errorProneVar(&ErrorProneChecksOff, " "))
+ exportedVars.ExportVariableFuncVariable("ErrorProneFlags", errorProneVar(&ErrorProneFlags, " "))
+ exportedVars.ExportStringListStaticVariable("ErrorProneChecks", []string{
"${ErrorProneChecksOff}",
"${ErrorProneChecksError}",
"${ErrorProneChecksWarning}",
"${ErrorProneChecksDefaultDisabled}",
- }, " "))
+ })
}
diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go
index 95ded34..534a814 100644
--- a/java/hiddenapi_modular.go
+++ b/java/hiddenapi_modular.go
@@ -295,6 +295,12 @@
return dexJar.Path()
}
+// HIDDENAPI_STUB_FLAGS_IMPL_FLAGS is the set of flags that identify implementation only signatures,
+// i.e. those signatures that are not part of any API (including the hidden API).
+var HIDDENAPI_STUB_FLAGS_IMPL_FLAGS = []string{}
+
+var HIDDENAPI_FLAGS_CSV_IMPL_FLAGS = []string{"blocked"}
+
// buildRuleToGenerateHiddenAPIStubFlagsFile creates a rule to create a hidden API stub flags file.
//
// The rule is initialized but not built so that the caller can modify it and select an appropriate
@@ -345,7 +351,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(stubFlagSubsets) > 0 {
- validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, stubFlagSubsets)
+ validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, stubFlagSubsets,
+ HIDDENAPI_STUB_FLAGS_IMPL_FLAGS)
// Add the file that indicates that the file generated by this is valid.
//
@@ -904,7 +911,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(flagSubsets) > 0 {
- validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, flagSubsets)
+ validFile := buildRuleValidateOverlappingCsvFiles(ctx, name, desc, outputPath, flagSubsets,
+ HIDDENAPI_FLAGS_CSV_IMPL_FLAGS)
// Add the file that indicates that the file generated by this is valid.
//
@@ -968,13 +976,29 @@
return patternsFile
}
-// buildRuleRemoveBlockedFlag creates a rule that will remove entries from the input path which
-// only have blocked flags. It will not remove entries that have blocked as well as other flags,
-// e.g. blocked,core-platform-api.
-func buildRuleRemoveBlockedFlag(ctx android.BuilderContext, name string, desc string, inputPath android.Path, filteredPath android.WritablePath) {
+// buildRuleRemoveSignaturesWithImplementationFlags creates a rule that will remove signatures from
+// the input flags file which have only the implementation flags, i.e. are not part of an API.
+//
+// The implementationFlags specifies the set of default flags that identifies the signature of a
+// private, implementation only, member. Signatures that match those flags are removed from the
+// flags as they are implementation only.
+//
+// This is used to remove implementation only signatures from the signature files that are persisted
+// in the sdk snapshot as the sdk snapshots should not include implementation details. The
+// signatures generated by this method will be compared by the buildRuleValidateOverlappingCsvFiles
+// method which treats any missing signatures as if they were implementation only signatures.
+func buildRuleRemoveSignaturesWithImplementationFlags(ctx android.BuilderContext,
+ name string, desc string, inputPath android.Path, filteredPath android.WritablePath,
+ implementationFlags []string) {
+
rule := android.NewRuleBuilder(pctx, ctx)
+ implementationFlagPattern := ""
+ for _, implementationFlag := range implementationFlags {
+ implementationFlagPattern = implementationFlagPattern + "," + implementationFlag
+ }
rule.Command().
- Text(`grep -vE "^[^,]+,blocked$"`).Input(inputPath).Text(">").Output(filteredPath).
+ Text(`grep -vE "^[^,]+` + implementationFlagPattern + `$"`).Input(inputPath).
+ Text(">").Output(filteredPath).
// Grep's exit code depends on whether it finds anything. It is 0 (build success) when it finds
// something and 1 (build failure) when it does not and 2 (when it encounters an error).
// However, while it is unlikely it is not an error if this does not find any matches. The
@@ -986,7 +1010,14 @@
// 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, csvSubsets SignatureCsvSubsets) android.WritablePath {
+//
+// The implementationFlags specifies the set of default flags that identifies the signature of a
+// private, implementation only, member. A signature which is present in a monolithic flags subset
+// defined by SignatureCsvSubset but which is not present in the flags file from the corresponding
+// module is assumed to be an implementation only member and so must have these flags.
+func buildRuleValidateOverlappingCsvFiles(ctx android.BuilderContext, name string, desc string,
+ monolithicFilePath android.WritablePath, csvSubsets SignatureCsvSubsets,
+ implementationFlags []string) android.WritablePath {
// The file which is used to record that the flags file is valid.
validFile := pathForValidation(ctx, monolithicFilePath)
@@ -994,14 +1025,19 @@
rule := android.NewRuleBuilder(pctx, ctx)
command := rule.Command().
BuiltTool("verify_overlaps").
- Input(monolithicFilePath)
+ FlagWithInput("--monolithic-flags ", monolithicFilePath)
for _, subset := range csvSubsets {
command.
+ Flag("--module-flags ").
Textf("%s:%s", subset.CsvFile, subset.SignaturePatternsFile).
Implicit(subset.CsvFile).Implicit(subset.SignaturePatternsFile)
}
+ for _, implementationFlag := range implementationFlags {
+ command.FlagWithArg("--implementation-flag ", implementationFlag)
+ }
+
// If validation passes then update the file that records that.
command.Text("&& touch").Output(validFile)
rule.Build(name+"Validation", desc+" validation")
@@ -1075,12 +1111,16 @@
// Generate the filtered-stub-flags.csv file which contains the filtered stub flags that will be
// compared against the monolithic stub flags.
filteredStubFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-stub-flags.csv")
- buildRuleRemoveBlockedFlag(ctx, "modularHiddenApiFilteredStubFlags", "modular hiddenapi filtered stub flags", stubFlagsCSV, filteredStubFlagsCSV)
+ buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredStubFlags",
+ "modular hiddenapi filtered stub flags", stubFlagsCSV, filteredStubFlagsCSV,
+ HIDDENAPI_STUB_FLAGS_IMPL_FLAGS)
// Generate the filtered-flags.csv file which contains the filtered flags that will be compared
// against the monolithic flags.
filteredFlagsCSV := android.PathForModuleOut(ctx, hiddenApiSubDir, "filtered-flags.csv")
- buildRuleRemoveBlockedFlag(ctx, "modularHiddenApiFilteredFlags", "modular hiddenapi filtered flags", allFlagsCSV, filteredFlagsCSV)
+ buildRuleRemoveSignaturesWithImplementationFlags(ctx, "modularHiddenApiFilteredFlags",
+ "modular hiddenapi filtered flags", allFlagsCSV, filteredFlagsCSV,
+ HIDDENAPI_FLAGS_CSV_IMPL_FLAGS)
// Store the paths in the info for use by other modules and sdk snapshot generation.
output := HiddenAPIOutput{
diff --git a/java/java.go b/java/java.go
index 713fe94..b34d6de 100644
--- a/java/java.go
+++ b/java/java.go
@@ -2041,6 +2041,10 @@
// and also separates dependencies into dynamic dependencies and static dependencies.
// Each corresponding Bazel target type, can have a different method for handling
// dynamic vs. static dependencies, and so these are returned to the calling function.
+type eventLogTagsAttributes struct {
+ Srcs bazel.LabelListAttribute
+}
+
func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) (*javaCommonAttributes, *javaDependencyLabels) {
var srcs bazel.LabelListAttribute
archVariantProps := m.GetArchVariantProperties(ctx, &CommonProperties{})
@@ -2055,11 +2059,32 @@
javaSrcPartition := "java"
protoSrcPartition := "proto"
+ logtagSrcPartition := "logtag"
srcPartitions := bazel.PartitionLabelListAttribute(ctx, &srcs, bazel.LabelPartitions{
- javaSrcPartition: bazel.LabelPartition{Extensions: []string{".java"}, Keep_remainder: true},
- protoSrcPartition: android.ProtoSrcLabelPartition,
+ javaSrcPartition: bazel.LabelPartition{Extensions: []string{".java"}, Keep_remainder: true},
+ logtagSrcPartition: bazel.LabelPartition{Extensions: []string{".logtags", ".logtag"}},
+ protoSrcPartition: android.ProtoSrcLabelPartition,
})
+ javaSrcs := srcPartitions[javaSrcPartition]
+
+ var logtagsSrcs bazel.LabelList
+ if !srcPartitions[logtagSrcPartition].IsEmpty() {
+ logtagsLibName := m.Name() + "_logtags"
+ logtagsSrcs = bazel.MakeLabelList([]bazel.Label{{Label: ":" + logtagsLibName}})
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "event_log_tags",
+ Bzl_load_location: "//build/make/tools:event_log_tags.bzl",
+ },
+ android.CommonAttributes{Name: logtagsLibName},
+ &eventLogTagsAttributes{
+ Srcs: srcPartitions[logtagSrcPartition],
+ },
+ )
+ }
+ javaSrcs.Append(bazel.MakeLabelListAttribute(logtagsSrcs))
+
var javacopts []string
if m.properties.Javacflags != nil {
javacopts = append(javacopts, m.properties.Javacflags...)
@@ -2071,7 +2096,7 @@
}
commonAttrs := &javaCommonAttributes{
- Srcs: srcPartitions[javaSrcPartition],
+ Srcs: javaSrcs,
Plugins: bazel.MakeLabelListAttribute(
android.BazelLabelForModuleDeps(ctx, m.properties.Plugins),
),
diff --git a/java/testing.go b/java/testing.go
index 82aa29b..4000334 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -70,6 +70,10 @@
defaultJavaDir + "/framework/aidl": nil,
// Needed for various deps defined in GatherRequiredDepsForTest()
defaultJavaDir + "/a.java": nil,
+
+ // Needed for R8 rules on apps
+ "build/make/core/proguard.flags": nil,
+ "build/make/core/proguard_basic_keeps.flags": nil,
}.AddToFixture(),
// The java default module definitions.
android.FixtureAddTextFile(defaultJavaDir+"/Android.bp", gatherRequiredDepsForTest()),
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 8807437..df18243 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -32,6 +32,7 @@
"os"
"path/filepath"
"regexp"
+ "sort"
"strconv"
"strings"
"text/scanner"
@@ -106,10 +107,11 @@
"my-dir": &myDirCallParser{},
"patsubst": &substCallParser{fname: "patsubst"},
"product-copy-files-by-pattern": &simpleCallParser{name: baseName + ".product_copy_files_by_pattern", returnType: starlarkTypeList},
- "require-artifacts-in-path": &simpleCallParser{name: baseName + ".require_artifacts_in_path", returnType: starlarkTypeVoid},
- "require-artifacts-in-path-relaxed": &simpleCallParser{name: baseName + ".require_artifacts_in_path_relaxed", returnType: starlarkTypeVoid},
+ "require-artifacts-in-path": &simpleCallParser{name: baseName + ".require_artifacts_in_path", returnType: starlarkTypeVoid, addHandle: true},
+ "require-artifacts-in-path-relaxed": &simpleCallParser{name: baseName + ".require_artifacts_in_path_relaxed", returnType: starlarkTypeVoid, addHandle: true},
// TODO(asmundak): remove it once all calls are removed from configuration makefiles. see b/183161002
"shell": &shellCallParser{},
+ "sort": &simpleCallParser{name: baseName + ".mksort", returnType: starlarkTypeList},
"strip": &simpleCallParser{name: baseName + ".mkstrip", returnType: starlarkTypeString},
"subst": &substCallParser{fname: "subst"},
"warning": &makeControlFuncParser{name: baseName + ".mkwarning"},
@@ -758,6 +760,16 @@
func (ctx *parseContext) handleSubConfig(
v mkparser.Node, pathExpr starlarkExpr, loadAlways bool, processModule func(inheritedModule) starlarkNode) []starlarkNode {
+ // Allow seeing $(sort $(wildcard realPathExpr)) or $(wildcard realPathExpr)
+ // because those are functionally the same as not having the sort/wildcard calls.
+ if ce, ok := pathExpr.(*callExpr); ok && ce.name == "rblf.mksort" && len(ce.args) == 1 {
+ if ce2, ok2 := ce.args[0].(*callExpr); ok2 && ce2.name == "rblf.expand_wildcard" && len(ce2.args) == 1 {
+ pathExpr = ce2.args[0]
+ }
+ } else if ce2, ok2 := pathExpr.(*callExpr); ok2 && ce2.name == "rblf.expand_wildcard" && len(ce2.args) == 1 {
+ pathExpr = ce2.args[0]
+ }
+
// In a simple case, the name of a module to inherit/include is known statically.
if path, ok := maybeString(pathExpr); ok {
// Note that even if this directive loads a module unconditionally, a module may be
@@ -765,6 +777,7 @@
moduleShouldExist := loadAlways && ctx.ifNestLevel == 0
if strings.Contains(path, "*") {
if paths, err := fs.Glob(ctx.script.sourceFS, path); err == nil {
+ sort.Strings(paths)
result := make([]starlarkNode, 0)
for _, p := range paths {
mi := ctx.newDependentModule(p, !moduleShouldExist)
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 3698813..96132cc 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -197,15 +197,31 @@
mkname: "path/product.mk",
in: `
$(call inherit-product, */font.mk)
+$(call inherit-product, $(sort $(wildcard */font.mk)))
+$(call inherit-product, $(wildcard */font.mk))
+
+include */font.mk
+include $(sort $(wildcard */font.mk))
+include $(wildcard */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")
+load("//bar:font.star", _font_init = "init")
+load("//foo: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)
+ rblf.inherit(handle, "bar/font", _font_init)
+ rblf.inherit(handle, "foo/font", _font1_init)
+ rblf.inherit(handle, "bar/font", _font_init)
+ rblf.inherit(handle, "foo/font", _font1_init)
+ rblf.inherit(handle, "bar/font", _font_init)
+ rblf.inherit(handle, "foo/font", _font1_init)
+ _font_init(g, handle)
+ _font1_init(g, handle)
+ _font_init(g, handle)
+ _font1_init(g, handle)
+ _font_init(g, handle)
+ _font1_init(g, handle)
`,
},
{
@@ -759,8 +775,8 @@
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")
+ rblf.require_artifacts_in_path(handle, "foo", "bar")
+ rblf.require_artifacts_in_path_relaxed(handle, "foo", "bar")
rblf.mkdist_for_goals(g, "goal", "from:to")
rblf.add_product_dex_preopt_module_config(handle, "MyModule", "disable")
`,
@@ -1022,12 +1038,13 @@
`,
},
{
- desc: "strip function",
+ desc: "strip/sort functions",
mkname: "product.mk",
in: `
ifeq ($(filter hwaddress,$(PRODUCT_PACKAGES)),)
PRODUCT_PACKAGES := $(strip $(PRODUCT_PACKAGES) hwaddress)
endif
+MY_VAR := $(sort b a c)
`,
expected: `load("//build/make/core:product_config.rbc", "rblf")
@@ -1036,6 +1053,7 @@
if "hwaddress" not in cfg.get("PRODUCT_PACKAGES", []):
rblf.setdefault(handle, "PRODUCT_PACKAGES")
cfg["PRODUCT_PACKAGES"] = (rblf.mkstrip("%s hwaddress" % " ".join(cfg.get("PRODUCT_PACKAGES", [])))).split()
+ g["MY_VAR"] = rblf.mksort("b a c")
`,
},
{
diff --git a/provenance/tools/Android.bp b/provenance/tools/Android.bp
index 1f959bb..0eddd76 100644
--- a/provenance/tools/Android.bp
+++ b/provenance/tools/Android.bp
@@ -14,6 +14,10 @@
* limitations under the License.
*/
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
python_binary_host {
name: "gen_provenance_metadata",
srcs: [
diff --git a/rust/rust.go b/rust/rust.go
index d627261..2a7bdcf 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -332,6 +332,20 @@
return false
}
+func (mod *Module) IsVndkPrebuiltLibrary() bool {
+ // Rust modules do not provide VNDK prebuilts
+ return false
+}
+
+func (mod *Module) IsVendorPublicLibrary() bool {
+ return mod.VendorProperties.IsVendorPublicLibrary
+}
+
+func (mod *Module) SdkAndPlatformVariantVisibleToMake() bool {
+ // Rust modules to not provide Sdk variants
+ return false
+}
+
func (c *Module) IsVndkPrivate() bool {
return false
}
@@ -841,24 +855,7 @@
toolchain := mod.toolchain(ctx)
mod.makeLinkType = cc.GetMakeLinkType(actx, mod)
- // Differentiate static libraries that are vendor available
- if mod.UseVndk() {
- if mod.InProduct() && !mod.OnlyInProduct() {
- mod.Properties.SubName += cc.ProductSuffix
- } else {
- mod.Properties.SubName += cc.VendorSuffix
- }
- } else if mod.InRamdisk() && !mod.OnlyInRamdisk() {
- mod.Properties.SubName += cc.RamdiskSuffix
- } else if mod.InVendorRamdisk() && !mod.OnlyInVendorRamdisk() {
- mod.Properties.SubName += cc.VendorRamdiskSuffix
- } else if mod.InRecovery() && !mod.OnlyInRecovery() {
- mod.Properties.SubName += cc.RecoverySuffix
- }
-
- if mod.Target().NativeBridge == android.NativeBridgeEnabled {
- mod.Properties.SubName += cc.NativeBridgeSuffix
- }
+ mod.Properties.SubName = cc.GetSubnameProperty(actx, mod)
if !toolchain.Supported() {
// This toolchain's unsupported, there's nothing to do for this mod.
diff --git a/scripts/hiddenapi/verify_overlaps.py b/scripts/hiddenapi/verify_overlaps.py
index e5214df..f985a49 100755
--- a/scripts/hiddenapi/verify_overlaps.py
+++ b/scripts/hiddenapi/verify_overlaps.py
@@ -23,13 +23,13 @@
from signature_trie import signature_trie
-def dict_reader(csvfile):
+def dict_reader(csv_file):
return csv.DictReader(
- csvfile, delimiter=",", quotechar="|", fieldnames=["signature"])
+ csv_file, delimiter=",", quotechar="|", fieldnames=["signature"])
def read_flag_trie_from_file(file):
- with open(file, "r") as stream:
+ with open(file, "r", encoding="utf8") as stream:
return read_flag_trie_from_stream(stream)
@@ -43,24 +43,24 @@
def extract_subset_from_monolithic_flags_as_dict_from_file(
- monolithicTrie, patternsFile):
+ monolithic_trie, patterns_file):
"""Extract a subset of flags from the dict of monolithic flags.
- :param monolithicFlagsDict: the dict containing all the monolithic flags.
- :param patternsFile: a file containing a list of signature patterns that
+ :param monolithic_trie: the trie containing all the monolithic flags.
+ :param patterns_file: 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:
+ with open(patterns_file, "r", encoding="utf8") as stream:
return extract_subset_from_monolithic_flags_as_dict_from_stream(
- monolithicTrie, stream)
+ monolithic_trie, stream)
def extract_subset_from_monolithic_flags_as_dict_from_stream(
- monolithicTrie, stream):
+ monolithic_trie, stream):
"""Extract a subset of flags from the trie of monolithic flags.
- :param monolithicTrie: the trie containing all the monolithic flags.
+ :param monolithic_trie: the trie 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.
@@ -68,7 +68,7 @@
dict_signature_to_row = {}
for pattern in stream:
pattern = pattern.rstrip()
- rows = monolithicTrie.get_matching_rows(pattern)
+ rows = monolithic_trie.get_matching_rows(pattern)
for row in rows:
signature = row["signature"]
dict_signature_to_row[signature] = row
@@ -93,86 +93,110 @@
return dict_signature_to_row
-def read_signature_csv_from_file_as_dict(csvFile):
+def read_signature_csv_from_file_as_dict(csv_file):
"""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
+ :param csv_file: the csv file to read
:return: the dict from signature to row.
"""
- with open(csvFile, "r") as f:
+ with open(csv_file, "r", encoding="utf8") as f:
return read_signature_csv_from_stream_as_dict(f)
-def compare_signature_flags(monolithicFlagsDict, modularFlagsDict):
+def compare_signature_flags(monolithic_flags_dict, modular_flags_dict,
+ implementation_flags):
"""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
+ :param monolithic_flags_dict: the dict containing the subset of the
+ monolithic flags that should be equal to the modular flags.
+ :param modular_flags_dict: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 = []
+ mismatching_signatures = []
# 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, [])
- if signature in modularFlagsDict:
- modularRow = modularFlagsDict.get(signature, {})
- modularFlags = modularRow.get(None, [])
+ all_signatures = sorted(
+ set(chain(monolithic_flags_dict.keys(), modular_flags_dict.keys())))
+ for signature in all_signatures:
+ monolithic_row = monolithic_flags_dict.get(signature, {})
+ monolithic_flags = monolithic_row.get(None, [])
+ if signature in modular_flags_dict:
+ modular_row = modular_flags_dict.get(signature, {})
+ modular_flags = modular_row.get(None, [])
else:
- modularFlags = ["blocked"]
- if monolithicFlags != modularFlags:
- mismatchingSignatures.append(
- (signature, modularFlags, monolithicFlags))
- return mismatchingSignatures
+ modular_flags = implementation_flags
+ if monolithic_flags != modular_flags:
+ mismatching_signatures.append(
+ (signature, modular_flags, monolithic_flags))
+ return mismatching_signatures
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")
+ "the monolithic flag file. For each module this uses the provided "
+ "signature patterns to select a subset of the monolithic flags and "
+ "then it compares that subset against the filtered flags provided by "
+ "the module. If the module's filtered flags does not contain flags for "
+ "a signature then it is assumed to have been filtered out because it "
+ "was not part of an API and so is assumed to have the implementation "
+ "flags.")
args_parser.add_argument(
- "modularFlags",
- nargs=argparse.REMAINDER,
- help="Flags produced by individual bootclasspath_fragment modules")
+ "--monolithic-flags", help="The monolithic flag file")
+ args_parser.add_argument(
+ "--module-flags",
+ action="append",
+ help="A colon separated pair of paths. The first is a path to a "
+ "filtered set of flags, and the second is a path to a set of "
+ "signature patterns that identify the set of classes belonging to "
+ "a single bootclasspath_fragment module. Specify once for each module "
+ "that needs to be checked.")
+ args_parser.add_argument(
+ "--implementation-flag",
+ action="append",
+ help="A flag in the set of flags that identifies a signature which is "
+ "not part of an API, i.e. is the signature of a private implementation "
+ "member. Specify as many times as necessary to define the "
+ "implementation flag set. If this is not specified then the "
+ "implementation flag set is empty.")
args = args_parser.parse_args(argv[1:])
# Read in all the flags into the trie
- monolithicFlagsPath = args.monolithicFlags
- monolithicTrie = read_flag_trie_from_file(monolithicFlagsPath)
+ monolithic_flags_path = args.monolithic_flags
+ monolithic_trie = read_flag_trie_from_file(monolithic_flags_path)
+
+ implementation_flags = args.implementation_flag or []
# 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 = \
+ module_pairs = args.module_flags or []
+ for modular_pair in module_pairs:
+ parts = modular_pair.split(":")
+ modular_flags_path = parts[0]
+ modular_patterns_path = parts[1]
+ modular_flags_dict = read_signature_csv_from_file_as_dict(
+ modular_flags_path)
+ monolithic_flags_subset_dict = \
extract_subset_from_monolithic_flags_as_dict_from_file(
- monolithicTrie, modularPatternsPath)
- mismatchingSignatures = compare_signature_flags(
- monolithicFlagsSubsetDict, modularFlagsDict)
- if mismatchingSignatures:
+ monolithic_trie, modular_patterns_path)
+ mismatching_signatures = compare_signature_flags(
+ monolithic_flags_subset_dict, modular_flags_dict,
+ implementation_flags)
+ if mismatching_signatures:
failed = True
print("ERROR: Hidden API flags are inconsistent:")
- print("< " + modularFlagsPath)
- print("> " + monolithicFlagsPath)
- for mismatch in mismatchingSignatures:
+ print("< " + modular_flags_path)
+ print("> " + monolithic_flags_path)
+ for mismatch in mismatching_signatures:
signature = mismatch[0]
print()
print("< " + ",".join([signature] + mismatch[1]))
diff --git a/scripts/hiddenapi/verify_overlaps_test.py b/scripts/hiddenapi/verify_overlaps_test.py
index 8cf2959..0a489ee 100755
--- a/scripts/hiddenapi/verify_overlaps_test.py
+++ b/scripts/hiddenapi/verify_overlaps_test.py
@@ -17,24 +17,26 @@
import io
import unittest
-from verify_overlaps import * #pylint: disable=unused-wildcard-import,wildcard-import
+import verify_overlaps as vo
-#pylint: disable=line-too-long
class TestDetectOverlaps(unittest.TestCase):
- def read_flag_trie_from_string(self, csvdata):
+ @staticmethod
+ def read_flag_trie_from_string(csvdata):
with io.StringIO(csvdata) as f:
- return read_flag_trie_from_stream(f)
+ return vo.read_flag_trie_from_stream(f)
- def read_signature_csv_from_string_as_dict(self, csvdata):
+ @staticmethod
+ def read_signature_csv_from_string_as_dict(csvdata):
with io.StringIO(csvdata) as f:
- return read_signature_csv_from_stream_as_dict(f)
+ return vo.read_signature_csv_from_stream_as_dict(f)
+ @staticmethod
def extract_subset_from_monolithic_flags_as_dict_from_string(
- self, monolithic, patterns):
+ monolithic, patterns):
with io.StringIO(patterns) as f:
- return extract_subset_from_monolithic_flags_as_dict_from_stream(
+ return vo.extract_subset_from_monolithic_flags_as_dict_from_stream(
monolithic, f)
extractInput = """
@@ -50,14 +52,14 @@
monolithic = self.read_flag_trie_from_string(
TestDetectOverlaps.extractInput)
- patterns = 'Ljava/lang/Object;->hashCode()I'
+ 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',
+ "Ljava/lang/Object;->hashCode()I": {
+ None: ["public-api", "system-api", "test-api"],
+ "signature": "Ljava/lang/Object;->hashCode()I",
},
}
self.assertEqual(expected, subset)
@@ -66,18 +68,18 @@
monolithic = self.read_flag_trie_from_string(
TestDetectOverlaps.extractInput)
- patterns = 'java/lang/Object'
+ patterns = "java/lang/Object"
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',
+ "Ljava/lang/Object;->hashCode()I": {
+ None: ["public-api", "system-api", "test-api"],
+ "signature": "Ljava/lang/Object;->hashCode()I",
},
- 'Ljava/lang/Object;->toString()Ljava/lang/String;': {
- None: ['blocked'],
- 'signature': 'Ljava/lang/Object;->toString()Ljava/lang/String;',
+ "Ljava/lang/Object;->toString()Ljava/lang/String;": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/Object;->toString()Ljava/lang/String;",
},
}
self.assertEqual(expected, subset)
@@ -86,20 +88,20 @@
monolithic = self.read_flag_trie_from_string(
TestDetectOverlaps.extractInput)
- patterns = 'java/lang/Character'
+ patterns = "java/lang/Character"
subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
monolithic, patterns)
expected = {
- 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;':
- {
- None: ['blocked'],
- 'signature':
- 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;',
- },
- 'Ljava/lang/Character;->serialVersionUID:J': {
- None: ['sdk'],
- 'signature': 'Ljava/lang/Character;->serialVersionUID:J',
+ "Ljava/lang/Character$UnicodeScript;"
+ "->of(I)Ljava/lang/Character$UnicodeScript;": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/Character$UnicodeScript;"
+ "->of(I)Ljava/lang/Character$UnicodeScript;",
+ },
+ "Ljava/lang/Character;->serialVersionUID:J": {
+ None: ["sdk"],
+ "signature": "Ljava/lang/Character;->serialVersionUID:J",
},
}
self.assertEqual(expected, subset)
@@ -108,17 +110,17 @@
monolithic = self.read_flag_trie_from_string(
TestDetectOverlaps.extractInput)
- patterns = 'java/lang/Character$UnicodeScript'
+ patterns = "java/lang/Character$UnicodeScript"
subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
monolithic, patterns)
expected = {
- 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;':
- {
- None: ['blocked'],
- 'signature':
- 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;',
- },
+ "Ljava/lang/Character$UnicodeScript;"
+ "->of(I)Ljava/lang/Character$UnicodeScript;": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/Character$UnicodeScript;"
+ "->of(I)Ljava/lang/Character$UnicodeScript;",
+ },
}
self.assertEqual(expected, subset)
@@ -126,32 +128,32 @@
monolithic = self.read_flag_trie_from_string(
TestDetectOverlaps.extractInput)
- patterns = 'java/lang/*'
+ patterns = "java/lang/*"
subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
monolithic, patterns)
expected = {
- 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;':
- {
- None: ['blocked'],
- 'signature':
- 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;',
- },
- 'Ljava/lang/Character;->serialVersionUID:J': {
- None: ['sdk'],
- 'signature': 'Ljava/lang/Character;->serialVersionUID:J',
+ "Ljava/lang/Character$UnicodeScript;"
+ "->of(I)Ljava/lang/Character$UnicodeScript;": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/Character$UnicodeScript;"
+ "->of(I)Ljava/lang/Character$UnicodeScript;",
},
- 'Ljava/lang/Object;->hashCode()I': {
- None: ['public-api', 'system-api', 'test-api'],
- 'signature': 'Ljava/lang/Object;->hashCode()I',
+ "Ljava/lang/Character;->serialVersionUID:J": {
+ None: ["sdk"],
+ "signature": "Ljava/lang/Character;->serialVersionUID:J",
},
- 'Ljava/lang/Object;->toString()Ljava/lang/String;': {
- None: ['blocked'],
- 'signature': 'Ljava/lang/Object;->toString()Ljava/lang/String;',
+ "Ljava/lang/Object;->hashCode()I": {
+ None: ["public-api", "system-api", "test-api"],
+ "signature": "Ljava/lang/Object;->hashCode()I",
},
- 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V': {
- None: ['blocked'],
- 'signature': 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V',
+ "Ljava/lang/Object;->toString()Ljava/lang/String;": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/Object;->toString()Ljava/lang/String;",
+ },
+ "Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V",
},
}
self.assertEqual(expected, subset)
@@ -160,36 +162,36 @@
monolithic = self.read_flag_trie_from_string(
TestDetectOverlaps.extractInput)
- patterns = 'java/**'
+ patterns = "java/**"
subset = self.extract_subset_from_monolithic_flags_as_dict_from_string(
monolithic, patterns)
expected = {
- 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;':
- {
- None: ['blocked'],
- 'signature':
- 'Ljava/lang/Character$UnicodeScript;->of(I)Ljava/lang/Character$UnicodeScript;',
- },
- 'Ljava/lang/Character;->serialVersionUID:J': {
- None: ['sdk'],
- 'signature': 'Ljava/lang/Character;->serialVersionUID:J',
+ "Ljava/lang/Character$UnicodeScript;"
+ "->of(I)Ljava/lang/Character$UnicodeScript;": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/Character$UnicodeScript;"
+ "->of(I)Ljava/lang/Character$UnicodeScript;",
},
- 'Ljava/lang/Object;->hashCode()I': {
- None: ['public-api', 'system-api', 'test-api'],
- 'signature': 'Ljava/lang/Object;->hashCode()I',
+ "Ljava/lang/Character;->serialVersionUID:J": {
+ None: ["sdk"],
+ "signature": "Ljava/lang/Character;->serialVersionUID:J",
},
- 'Ljava/lang/Object;->toString()Ljava/lang/String;': {
- None: ['blocked'],
- 'signature': 'Ljava/lang/Object;->toString()Ljava/lang/String;',
+ "Ljava/lang/Object;->hashCode()I": {
+ None: ["public-api", "system-api", "test-api"],
+ "signature": "Ljava/lang/Object;->hashCode()I",
},
- 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V': {
- None: ['blocked'],
- 'signature': 'Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V',
+ "Ljava/lang/Object;->toString()Ljava/lang/String;": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/Object;->toString()Ljava/lang/String;",
},
- 'Ljava/util/zip/ZipFile;-><clinit>()V': {
- None: ['blocked'],
- 'signature': 'Ljava/util/zip/ZipFile;-><clinit>()V',
+ "Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V": {
+ None: ["blocked"],
+ "signature": "Ljava/lang/ProcessBuilder$Redirect$1;-><init>()V",
+ },
+ "Ljava/util/zip/ZipFile;-><clinit>()V": {
+ None: ["blocked"],
+ "signature": "Ljava/util/zip/ZipFile;-><clinit>()V",
},
}
self.assertEqual(expected, subset)
@@ -200,7 +202,7 @@
Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
Ljava/lang/Object;->hashCode()I,blocked
""")
- self.assertTrue('Duplicate signature: Ljava/lang/Object;->hashCode()I'
+ self.assertTrue("Duplicate signature: Ljava/lang/Object;->hashCode()I"
in str(context.exception))
def test_read_trie_missing_member(self):
@@ -209,8 +211,8 @@
Ljava/lang/Object,public-api,system-api,test-api
""")
self.assertTrue(
- 'Invalid signature: Ljava/lang/Object, does not identify a specific member'
- in str(context.exception))
+ "Invalid signature: Ljava/lang/Object, "
+ "does not identify a specific member" in str(context.exception))
def test_match(self):
monolithic = self.read_signature_csv_from_string_as_dict("""
@@ -219,7 +221,8 @@
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)
+ mismatches = vo.compare_signature_flags(monolithic, modular,
+ ["blocked"])
expected = []
self.assertEqual(expected, mismatches)
@@ -230,12 +233,13 @@
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)
+ mismatches = vo.compare_signature_flags(monolithic, modular,
+ ["blocked"])
expected = [
(
- 'Ljava/lang/Object;->toString()Ljava/lang/String;',
- ['public-api', 'system-api', 'test-api'],
- ['public-api'],
+ "Ljava/lang/Object;->toString()Ljava/lang/String;",
+ ["public-api", "system-api", "test-api"],
+ ["public-api"],
),
]
self.assertEqual(expected, mismatches)
@@ -247,12 +251,13 @@
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)
+ mismatches = vo.compare_signature_flags(monolithic, modular,
+ ["blocked"])
expected = [
(
- 'Ljava/lang/Object;->toString()Ljava/lang/String;',
- ['public-api', 'system-api', 'test-api'],
- ['blocked'],
+ "Ljava/lang/Object;->toString()Ljava/lang/String;",
+ ["public-api", "system-api", "test-api"],
+ ["blocked"],
),
]
self.assertEqual(expected, mismatches)
@@ -264,26 +269,28 @@
modular = self.read_signature_csv_from_string_as_dict("""
Ljava/lang/Object;->toString()Ljava/lang/String;,blocked
""")
- mismatches = compare_signature_flags(monolithic, modular)
+ mismatches = vo.compare_signature_flags(monolithic, modular,
+ ["blocked"])
expected = [
(
- 'Ljava/lang/Object;->toString()Ljava/lang/String;',
- ['blocked'],
- ['public-api', 'system-api', 'test-api'],
+ "Ljava/lang/Object;->toString()Ljava/lang/String;",
+ ["blocked"],
+ ["public-api", "system-api", "test-api"],
),
]
self.assertEqual(expected, mismatches)
def test_match_treat_missing_from_modular_as_blocked(self):
- monolithic = self.read_signature_csv_from_string_as_dict('')
+ 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)
+ mismatches = vo.compare_signature_flags(monolithic, modular,
+ ["blocked"])
expected = [
(
- 'Ljava/lang/Object;->toString()Ljava/lang/String;',
- ['public-api', 'system-api', 'test-api'],
+ "Ljava/lang/Object;->toString()Ljava/lang/String;",
+ ["public-api", "system-api", "test-api"],
[],
),
]
@@ -294,12 +301,13 @@
Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
""")
modular = {}
- mismatches = compare_signature_flags(monolithic, modular)
+ mismatches = vo.compare_signature_flags(monolithic, modular,
+ ["blocked"])
expected = [
(
- 'Ljava/lang/Object;->hashCode()I',
- ['blocked'],
- ['public-api', 'system-api', 'test-api'],
+ "Ljava/lang/Object;->hashCode()I",
+ ["blocked"],
+ ["public-api", "system-api", "test-api"],
),
]
self.assertEqual(expected, mismatches)
@@ -309,12 +317,50 @@
Ljava/lang/Object;->hashCode()I,blocked
""")
modular = {}
- mismatches = compare_signature_flags(monolithic, modular)
+ mismatches = vo.compare_signature_flags(monolithic, modular,
+ ["blocked"])
+ expected = []
+ self.assertEqual(expected, mismatches)
+
+ def test_match_treat_missing_from_modular_as_empty(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 = vo.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_mismatch_treat_missing_from_modular_as_empty(self):
+ monolithic = self.read_signature_csv_from_string_as_dict("""
+Ljava/lang/Object;->hashCode()I,public-api,system-api,test-api
+""")
+ modular = {}
+ mismatches = vo.compare_signature_flags(monolithic, modular, [])
+ expected = [
+ (
+ "Ljava/lang/Object;->hashCode()I",
+ [],
+ ["public-api", "system-api", "test-api"],
+ ),
+ ]
+ self.assertEqual(expected, mismatches)
+
+ def test_empty_missing_from_modular(self):
+ monolithic = self.read_signature_csv_from_string_as_dict("""
+Ljava/lang/Object;->hashCode()I
+""")
+ modular = {}
+ mismatches = vo.compare_signature_flags(monolithic, modular, [])
expected = []
self.assertEqual(expected, mismatches)
-#pylint: enable=line-too-long
-
-if __name__ == '__main__':
+if __name__ == "__main__":
unittest.main(verbosity=2)
diff --git a/starlark_fmt/format.go b/starlark_fmt/format.go
index 23eee59..3e51fa1 100644
--- a/starlark_fmt/format.go
+++ b/starlark_fmt/format.go
@@ -39,21 +39,26 @@
// PrintsStringList returns a Starlark-compatible string of a list of Strings/Labels.
func PrintStringList(items []string, indentLevel int) string {
- return PrintList(items, indentLevel, `"%s"`)
+ return PrintList(items, indentLevel, func(s string) string {
+ if strings.Contains(s, "\"") {
+ return `'''%s'''`
+ }
+ return `"%s"`
+ })
}
// PrintList returns a Starlark-compatible string of list formmated as requested.
-func PrintList(items []string, indentLevel int, formatString string) string {
+func PrintList(items []string, indentLevel int, formatString func(string) string) string {
if len(items) == 0 {
return "[]"
} else if len(items) == 1 {
- return fmt.Sprintf("["+formatString+"]", items[0])
+ return fmt.Sprintf("["+formatString(items[0])+"]", items[0])
}
list := make([]string, 0, len(items)+2)
list = append(list, "[")
innerIndent := Indention(indentLevel + 1)
for _, item := range items {
- list = append(list, fmt.Sprintf(`%s`+formatString+`,`, innerIndent, item))
+ list = append(list, fmt.Sprintf(`%s`+formatString(item)+`,`, innerIndent, item))
}
list = append(list, Indention(indentLevel)+"]")
return strings.Join(list, "\n")
diff --git a/starlark_fmt/format_test.go b/starlark_fmt/format_test.go
index 90f78ef..9450a31 100644
--- a/starlark_fmt/format_test.go
+++ b/starlark_fmt/format_test.go
@@ -18,6 +18,10 @@
"testing"
)
+func simpleFormat(s string) string {
+ return "%s"
+}
+
func TestPrintEmptyStringList(t *testing.T) {
in := []string{}
indentLevel := 0
@@ -54,7 +58,7 @@
func TestPrintEmptyList(t *testing.T) {
in := []string{}
indentLevel := 0
- out := PrintList(in, indentLevel, "%s")
+ out := PrintList(in, indentLevel, simpleFormat)
expectedOut := "[]"
if out != expectedOut {
t.Errorf("Expected %q, got %q", expectedOut, out)
@@ -64,7 +68,7 @@
func TestPrintSingleElementList(t *testing.T) {
in := []string{"1"}
indentLevel := 0
- out := PrintList(in, indentLevel, "%s")
+ out := PrintList(in, indentLevel, simpleFormat)
expectedOut := `[1]`
if out != expectedOut {
t.Errorf("Expected %q, got %q", expectedOut, out)
@@ -74,7 +78,7 @@
func TestPrintMultiElementList(t *testing.T) {
in := []string{"1", "2"}
indentLevel := 0
- out := PrintList(in, indentLevel, "%s")
+ out := PrintList(in, indentLevel, simpleFormat)
expectedOut := `[
1,
2,
@@ -87,7 +91,7 @@
func TestListWithNonZeroIndent(t *testing.T) {
in := []string{"1", "2"}
indentLevel := 1
- out := PrintList(in, indentLevel, "%s")
+ out := PrintList(in, indentLevel, simpleFormat)
expectedOut := `[
1,
2,
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index f935f06..88ef615 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -98,9 +98,6 @@
"build/soong/scripts/jar-wrapper.sh": nil,
- "build/make/core/proguard.flags": nil,
- "build/make/core/proguard_basic_keeps.flags": nil,
-
"jdk8/jre/lib/jce.jar": nil,
"jdk8/jre/lib/rt.jar": nil,
"jdk8/lib/tools.jar": nil,
diff --git a/ui/build/config.go b/ui/build/config.go
index dd5bd0c..e271bfc 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -144,6 +144,12 @@
// fetchEnvConfig optionally fetches environment config from an
// experiments system to control Soong features dynamically.
func fetchEnvConfig(ctx Context, config *configImpl, envConfigName string) error {
+ configName := envConfigName + "." + jsonSuffix
+ expConfigFetcher := &smpb.ExpConfigFetcher{}
+ defer func() {
+ ctx.Metrics.ExpConfigFetcher(expConfigFetcher)
+ }()
+
s, err := os.Stat(configFetcher)
if err != nil {
if os.IsNotExist(err) {
@@ -152,31 +158,38 @@
return err
}
if s.Mode()&0111 == 0 {
+ status := smpb.ExpConfigFetcher_ERROR
+ expConfigFetcher.Status = &status
return fmt.Errorf("configuration fetcher binary %v is not executable: %v", configFetcher, s.Mode())
}
- configExists := false
- outConfigFilePath := filepath.Join(config.OutDir(), envConfigName+jsonSuffix)
- if _, err := os.Stat(outConfigFilePath); err == nil {
- configExists = true
- }
-
tCtx, cancel := context.WithTimeout(ctx, envConfigFetchTimeout)
defer cancel()
- cmd := exec.CommandContext(tCtx, configFetcher, "-output_config_dir", config.OutDir())
+ fetchStart := time.Now()
+ cmd := exec.CommandContext(tCtx, configFetcher, "-output_config_dir", config.OutDir(),
+ "-output_config_name", configName)
if err := cmd.Start(); err != nil {
+ status := smpb.ExpConfigFetcher_ERROR
+ expConfigFetcher.Status = &status
return err
}
- // If a config file already exists, return immediately and run the config file
- // fetch in the background. Otherwise, wait for the config file to be fetched.
- if configExists {
- go cmd.Wait()
- return nil
- }
if err := cmd.Wait(); err != nil {
+ status := smpb.ExpConfigFetcher_ERROR
+ expConfigFetcher.Status = &status
return err
}
+ fetchEnd := time.Now()
+ expConfigFetcher.Micros = proto.Uint64(uint64(fetchEnd.Sub(fetchStart).Microseconds()))
+ outConfigFilePath := filepath.Join(config.OutDir(), configName)
+ expConfigFetcher.Filename = proto.String(outConfigFilePath)
+ if _, err := os.Stat(outConfigFilePath); err == nil {
+ status := smpb.ExpConfigFetcher_CONFIG
+ expConfigFetcher.Status = &status
+ } else {
+ status := smpb.ExpConfigFetcher_NO_CONFIG
+ expConfigFetcher.Status = &status
+ }
return nil
}
diff --git a/ui/metrics/metrics.go b/ui/metrics/metrics.go
index 6f1ed60..0c62865 100644
--- a/ui/metrics/metrics.go
+++ b/ui/metrics/metrics.go
@@ -38,6 +38,7 @@
"time"
"android/soong/shared"
+
"google.golang.org/protobuf/proto"
soong_metrics_proto "android/soong/ui/metrics/metrics_proto"
@@ -135,6 +136,11 @@
m.metrics.SystemResourceInfo = b
}
+// ExpConfigFetcher stores information about the expconfigfetcher.
+func (m *Metrics) ExpConfigFetcher(b *soong_metrics_proto.ExpConfigFetcher) {
+ m.metrics.ExpConfigFetcher = b
+}
+
// SetMetadataMetrics sets information about the build such as the target
// product, host architecture and out directory.
func (m *Metrics) SetMetadataMetrics(metadata map[string]string) {
diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go
index 26229c6..69f5689 100644
--- a/ui/metrics/metrics_proto/metrics.pb.go
+++ b/ui/metrics/metrics_proto/metrics.pb.go
@@ -217,6 +217,65 @@
return file_metrics_proto_rawDescGZIP(), []int{5, 0}
}
+type ExpConfigFetcher_ConfigStatus int32
+
+const (
+ ExpConfigFetcher_NO_CONFIG ExpConfigFetcher_ConfigStatus = 0
+ ExpConfigFetcher_CONFIG ExpConfigFetcher_ConfigStatus = 1
+ ExpConfigFetcher_ERROR ExpConfigFetcher_ConfigStatus = 2
+)
+
+// Enum value maps for ExpConfigFetcher_ConfigStatus.
+var (
+ ExpConfigFetcher_ConfigStatus_name = map[int32]string{
+ 0: "NO_CONFIG",
+ 1: "CONFIG",
+ 2: "ERROR",
+ }
+ ExpConfigFetcher_ConfigStatus_value = map[string]int32{
+ "NO_CONFIG": 0,
+ "CONFIG": 1,
+ "ERROR": 2,
+ }
+)
+
+func (x ExpConfigFetcher_ConfigStatus) Enum() *ExpConfigFetcher_ConfigStatus {
+ p := new(ExpConfigFetcher_ConfigStatus)
+ *p = x
+ return p
+}
+
+func (x ExpConfigFetcher_ConfigStatus) String() string {
+ return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (ExpConfigFetcher_ConfigStatus) Descriptor() protoreflect.EnumDescriptor {
+ return file_metrics_proto_enumTypes[3].Descriptor()
+}
+
+func (ExpConfigFetcher_ConfigStatus) Type() protoreflect.EnumType {
+ return &file_metrics_proto_enumTypes[3]
+}
+
+func (x ExpConfigFetcher_ConfigStatus) Number() protoreflect.EnumNumber {
+ return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *ExpConfigFetcher_ConfigStatus) UnmarshalJSON(b []byte) error {
+ num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+ if err != nil {
+ return err
+ }
+ *x = ExpConfigFetcher_ConfigStatus(num)
+ return nil
+}
+
+// Deprecated: Use ExpConfigFetcher_ConfigStatus.Descriptor instead.
+func (ExpConfigFetcher_ConfigStatus) EnumDescriptor() ([]byte, []int) {
+ return file_metrics_proto_rawDescGZIP(), []int{9, 0}
+}
+
type MetricsBase struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -274,6 +333,8 @@
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"`
+ // The metrics of the experiment config fetcher
+ ExpConfigFetcher *ExpConfigFetcher `protobuf:"bytes,28,opt,name=exp_config_fetcher,json=expConfigFetcher" json:"exp_config_fetcher,omitempty"`
}
// Default values for MetricsBase fields.
@@ -505,6 +566,13 @@
return nil
}
+func (x *MetricsBase) GetExpConfigFetcher() *ExpConfigFetcher {
+ if x != nil {
+ return x.ExpConfigFetcher
+ }
+ return nil
+}
+
type BuildConfig struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@@ -1150,12 +1218,81 @@
return nil
}
+type ExpConfigFetcher struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The result of the call to expconfigfetcher
+ // NO_CONFIG - Not part of experiment
+ // CONFIG - Part of experiment, config copied successfully
+ // ERROR - expconfigfetcher failed
+ Status *ExpConfigFetcher_ConfigStatus `protobuf:"varint,1,opt,name=status,enum=soong_build_metrics.ExpConfigFetcher_ConfigStatus" json:"status,omitempty"`
+ // The output config filename
+ Filename *string `protobuf:"bytes,2,opt,name=filename" json:"filename,omitempty"`
+ // Time, in microseconds, taken by the expconfigfetcher
+ Micros *uint64 `protobuf:"varint,3,opt,name=micros" json:"micros,omitempty"`
+}
+
+func (x *ExpConfigFetcher) Reset() {
+ *x = ExpConfigFetcher{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_metrics_proto_msgTypes[9]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ExpConfigFetcher) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ExpConfigFetcher) ProtoMessage() {}
+
+func (x *ExpConfigFetcher) ProtoReflect() protoreflect.Message {
+ mi := &file_metrics_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 ExpConfigFetcher.ProtoReflect.Descriptor instead.
+func (*ExpConfigFetcher) Descriptor() ([]byte, []int) {
+ return file_metrics_proto_rawDescGZIP(), []int{9}
+}
+
+func (x *ExpConfigFetcher) GetStatus() ExpConfigFetcher_ConfigStatus {
+ if x != nil && x.Status != nil {
+ return *x.Status
+ }
+ return ExpConfigFetcher_NO_CONFIG
+}
+
+func (x *ExpConfigFetcher) GetFilename() string {
+ if x != nil && x.Filename != nil {
+ return *x.Filename
+ }
+ return ""
+}
+
+func (x *ExpConfigFetcher) GetMicros() uint64 {
+ if x != nil && x.Micros != nil {
+ return *x.Micros
+ }
+ return 0
+}
+
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,
+ 0x72, 0x69, 0x63, 0x73, 0x22, 0xad, 0x0d, 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,
@@ -1249,122 +1386,140 @@
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,
- 0xd3, 0x01, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12,
- 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x67, 0x6f, 0x6d, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28,
- 0x08, 0x52, 0x07, 0x75, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73,
- 0x65, 0x5f, 0x72, 0x62, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x75, 0x73, 0x65,
- 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, 0x12, 0x18, 0x0a, 0x07, 0x74,
- 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x74, 0x61,
- 0x72, 0x67, 0x65, 0x74, 0x73, 0x22, 0x6f, 0x0a, 0x12, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x52,
- 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x32, 0x0a, 0x15, 0x74,
- 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x6d, 0x65,
- 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x13, 0x74, 0x6f, 0x74, 0x61,
- 0x6c, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12,
- 0x25, 0x0a, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x63, 0x70, 0x75,
- 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62,
- 0x6c, 0x65, 0x43, 0x70, 0x75, 0x73, 0x22, 0x81, 0x02, 0x0a, 0x08, 0x50, 0x65, 0x72, 0x66, 0x49,
- 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69,
- 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69,
- 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20,
- 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61,
- 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x73,
- 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x72, 0x65, 0x61, 0x6c,
- 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x72, 0x65, 0x61,
- 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f,
- 0x75, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02, 0x18, 0x01, 0x52, 0x09, 0x6d,
- 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x65, 0x12, 0x60, 0x0a, 0x17, 0x70, 0x72, 0x6f, 0x63,
- 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x69,
- 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x6f, 0x6f, 0x6e,
- 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e,
- 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, 0xfa, 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, 0x12, 0x35, 0x0a, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73,
- 0x18, 0x06, 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, 0x06, 0x65, 0x76, 0x65, 0x6e, 0x74, 0x73, 0x42, 0x28, 0x5a,
+ 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x62, 0x61, 0x7a, 0x65, 0x6c, 0x52, 0x75, 0x6e, 0x73, 0x12,
+ 0x53, 0x0a, 0x12, 0x65, 0x78, 0x70, 0x5f, 0x63, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x5f, 0x66, 0x65,
+ 0x74, 0x63, 0x68, 0x65, 0x72, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x73, 0x6f,
+ 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63,
+ 0x73, 0x2e, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74, 0x63, 0x68,
+ 0x65, 0x72, 0x52, 0x10, 0x65, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74,
+ 0x63, 0x68, 0x65, 0x72, 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, 0xd3, 0x01, 0x0a, 0x0b, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x43, 0x6f,
+ 0x6e, 0x66, 0x69, 0x67, 0x12, 0x19, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x5f, 0x67, 0x6f, 0x6d, 0x61,
+ 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x75, 0x73, 0x65, 0x47, 0x6f, 0x6d, 0x61, 0x12,
+ 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x5f, 0x72, 0x62, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08,
+ 0x52, 0x06, 0x75, 0x73, 0x65, 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,
+ 0x12, 0x18, 0x0a, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28,
+ 0x09, 0x52, 0x07, 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x73, 0x22, 0x6f, 0x0a, 0x12, 0x53, 0x79,
+ 0x73, 0x74, 0x65, 0x6d, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x49, 0x6e, 0x66, 0x6f,
+ 0x12, 0x32, 0x0a, 0x15, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x70, 0x68, 0x79, 0x73, 0x69, 0x63,
+ 0x61, 0x6c, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x13, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x50, 0x68, 0x79, 0x73, 0x69, 0x63, 0x61, 0x6c, 0x4d, 0x65,
+ 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c,
+ 0x65, 0x5f, 0x63, 0x70, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x61, 0x76,
+ 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x70, 0x75, 0x73, 0x22, 0x81, 0x02, 0x0a, 0x08,
+ 0x50, 0x65, 0x72, 0x66, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63,
+ 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x64,
+ 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
+ 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1d,
+ 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x72, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01,
+ 0x28, 0x04, 0x52, 0x09, 0x73, 0x74, 0x61, 0x72, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x1b, 0x0a,
+ 0x09, 0x72, 0x65, 0x61, 0x6c, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04,
+ 0x52, 0x08, 0x72, 0x65, 0x61, 0x6c, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x21, 0x0a, 0x0a, 0x6d, 0x65,
+ 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x75, 0x73, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x42, 0x02,
+ 0x18, 0x01, 0x52, 0x09, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x55, 0x73, 0x65, 0x12, 0x60, 0x0a,
+ 0x17, 0x70, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x65, 0x73, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75,
+ 0x72, 0x63, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28,
+ 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74,
+ 0x72, 0x69, 0x63, 0x73, 0x2e, 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, 0xfa, 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, 0x12, 0x35, 0x0a, 0x06, 0x65,
+ 0x76, 0x65, 0x6e, 0x74, 0x73, 0x18, 0x06, 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, 0x06, 0x65, 0x76, 0x65, 0x6e,
+ 0x74, 0x73, 0x22, 0xc8, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67,
+ 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75,
+ 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x32, 0x2e, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f,
+ 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x45, 0x78,
+ 0x70, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x46, 0x65, 0x74, 0x63, 0x68, 0x65, 0x72, 0x2e, 0x43,
+ 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61,
+ 0x74, 0x75, 0x73, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18,
+ 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12,
+ 0x16, 0x0a, 0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52,
+ 0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x22, 0x34, 0x0a, 0x0c, 0x43, 0x6f, 0x6e, 0x66, 0x69,
+ 0x67, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x4f, 0x5f, 0x43, 0x4f,
+ 0x4e, 0x46, 0x49, 0x47, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4f, 0x4e, 0x46, 0x49, 0x47,
+ 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 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,
@@ -1382,46 +1537,50 @@
return file_metrics_proto_rawDescData
}
-var file_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 3)
-var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
+var file_metrics_proto_enumTypes = make([]protoimpl.EnumInfo, 4)
+var file_metrics_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
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
+ (ExpConfigFetcher_ConfigStatus)(0), // 3: soong_build_metrics.ExpConfigFetcher.ConfigStatus
+ (*MetricsBase)(nil), // 4: soong_build_metrics.MetricsBase
+ (*BuildConfig)(nil), // 5: soong_build_metrics.BuildConfig
+ (*SystemResourceInfo)(nil), // 6: soong_build_metrics.SystemResourceInfo
+ (*PerfInfo)(nil), // 7: soong_build_metrics.PerfInfo
+ (*ProcessResourceInfo)(nil), // 8: soong_build_metrics.ProcessResourceInfo
+ (*ModuleTypeInfo)(nil), // 9: soong_build_metrics.ModuleTypeInfo
+ (*CriticalUserJourneyMetrics)(nil), // 10: soong_build_metrics.CriticalUserJourneyMetrics
+ (*CriticalUserJourneysMetrics)(nil), // 11: soong_build_metrics.CriticalUserJourneysMetrics
+ (*SoongBuildMetrics)(nil), // 12: soong_build_metrics.SoongBuildMetrics
+ (*ExpConfigFetcher)(nil), // 13: soong_build_metrics.ExpConfigFetcher
}
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
- 6, // 17: soong_build_metrics.SoongBuildMetrics.events:type_name -> soong_build_metrics.PerfInfo
- 18, // [18:18] is the sub-list for method output_type
- 18, // [18:18] is the sub-list for method input_type
- 18, // [18:18] is the sub-list for extension type_name
- 18, // [18:18] is the sub-list for extension extendee
- 0, // [0:18] is the sub-list for field type_name
+ 7, // 4: soong_build_metrics.MetricsBase.setup_tools:type_name -> soong_build_metrics.PerfInfo
+ 7, // 5: soong_build_metrics.MetricsBase.kati_runs:type_name -> soong_build_metrics.PerfInfo
+ 7, // 6: soong_build_metrics.MetricsBase.soong_runs:type_name -> soong_build_metrics.PerfInfo
+ 7, // 7: soong_build_metrics.MetricsBase.ninja_runs:type_name -> soong_build_metrics.PerfInfo
+ 7, // 8: soong_build_metrics.MetricsBase.total:type_name -> soong_build_metrics.PerfInfo
+ 12, // 9: soong_build_metrics.MetricsBase.soong_build_metrics:type_name -> soong_build_metrics.SoongBuildMetrics
+ 5, // 10: soong_build_metrics.MetricsBase.build_config:type_name -> soong_build_metrics.BuildConfig
+ 6, // 11: soong_build_metrics.MetricsBase.system_resource_info:type_name -> soong_build_metrics.SystemResourceInfo
+ 7, // 12: soong_build_metrics.MetricsBase.bazel_runs:type_name -> soong_build_metrics.PerfInfo
+ 13, // 13: soong_build_metrics.MetricsBase.exp_config_fetcher:type_name -> soong_build_metrics.ExpConfigFetcher
+ 8, // 14: soong_build_metrics.PerfInfo.processes_resource_info:type_name -> soong_build_metrics.ProcessResourceInfo
+ 2, // 15: soong_build_metrics.ModuleTypeInfo.build_system:type_name -> soong_build_metrics.ModuleTypeInfo.BuildSystem
+ 4, // 16: soong_build_metrics.CriticalUserJourneyMetrics.metrics:type_name -> soong_build_metrics.MetricsBase
+ 10, // 17: soong_build_metrics.CriticalUserJourneysMetrics.cujs:type_name -> soong_build_metrics.CriticalUserJourneyMetrics
+ 7, // 18: soong_build_metrics.SoongBuildMetrics.events:type_name -> soong_build_metrics.PerfInfo
+ 3, // 19: soong_build_metrics.ExpConfigFetcher.status:type_name -> soong_build_metrics.ExpConfigFetcher.ConfigStatus
+ 20, // [20:20] is the sub-list for method output_type
+ 20, // [20:20] is the sub-list for method input_type
+ 20, // [20:20] is the sub-list for extension type_name
+ 20, // [20:20] is the sub-list for extension extendee
+ 0, // [0:20] is the sub-list for field type_name
}
func init() { file_metrics_proto_init() }
@@ -1538,14 +1697,26 @@
return nil
}
}
+ file_metrics_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
+ switch v := v.(*ExpConfigFetcher); 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,
+ NumEnums: 4,
+ NumMessages: 10,
NumExtensions: 0,
NumServices: 0,
},
diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto
index 26e4d73..814eb67 100644
--- a/ui/metrics/metrics_proto/metrics.proto
+++ b/ui/metrics/metrics_proto/metrics.proto
@@ -108,6 +108,9 @@
// The metrics for calling Bazel.
repeated PerfInfo bazel_runs = 27;
+
+ // The metrics of the experiment config fetcher
+ optional ExpConfigFetcher exp_config_fetcher = 28;
}
message BuildConfig {
@@ -239,3 +242,22 @@
// Runtime metrics for soong_build execution.
repeated PerfInfo events = 6;
}
+
+message ExpConfigFetcher {
+ enum ConfigStatus {
+ NO_CONFIG = 0;
+ CONFIG = 1;
+ ERROR = 2;
+ }
+ // The result of the call to expconfigfetcher
+ // NO_CONFIG - Not part of experiment
+ // CONFIG - Part of experiment, config copied successfully
+ // ERROR - expconfigfetcher failed
+ optional ConfigStatus status = 1;
+
+ // The output config filename
+ optional string filename = 2;
+
+ // Time, in microseconds, taken by the expconfigfetcher
+ optional uint64 micros = 3;
+}