diff options
39 files changed, 1230 insertions, 2222 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index a5cea1720..af82942cb 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -37,184 +37,186 @@ const ( var ( Bp2buildDefaultConfig = Bp2BuildConfig{ - "prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively, - "art/libartpalette": Bp2BuildDefaultTrueRecursively, - "art/libartbase": Bp2BuildDefaultTrueRecursively, - "art/libdexfile": Bp2BuildDefaultTrueRecursively, - "art/libnativebridge": Bp2BuildDefaultTrueRecursively, - "art/runtime": Bp2BuildDefaultTrueRecursively, - "art/tools": Bp2BuildDefaultTrue, - "bionic": Bp2BuildDefaultTrueRecursively, - "bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue, - "build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively, - "build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively, - "build/bazel/examples/python": Bp2BuildDefaultTrueRecursively, - "build/bazel/examples/gensrcs": Bp2BuildDefaultTrueRecursively, - "build/make/target/product/security": Bp2BuildDefaultTrue, - "build/make/tools/signapk": Bp2BuildDefaultTrue, - "build/make/tools/zipalign": Bp2BuildDefaultTrueRecursively, - "build/soong": Bp2BuildDefaultTrue, - "build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir - "build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue, - "build/soong/cc/symbolfile": Bp2BuildDefaultTrue, - "build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively, - "build/soong/scripts": Bp2BuildDefaultTrueRecursively, - "cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively, - "development/apps/DevelopmentSettings": Bp2BuildDefaultTrue, - "development/apps/Fallback": Bp2BuildDefaultTrue, - "development/apps/WidgetPreview": Bp2BuildDefaultTrue, - "development/samples/BasicGLSurfaceView": Bp2BuildDefaultTrue, - "development/samples/BluetoothChat": Bp2BuildDefaultTrue, - "development/samples/BrokenKeyDerivation": Bp2BuildDefaultTrue, - "development/samples/Compass": Bp2BuildDefaultTrue, - "development/samples/ContactManager": Bp2BuildDefaultTrue, - "development/samples/FixedGridLayout": Bp2BuildDefaultTrue, - "development/samples/HelloEffects": Bp2BuildDefaultTrue, - "development/samples/Home": Bp2BuildDefaultTrue, - "development/samples/HoneycombGallery": Bp2BuildDefaultTrue, - "development/samples/JetBoy": Bp2BuildDefaultTrue, - "development/samples/KeyChainDemo": Bp2BuildDefaultTrue, - "development/samples/LceDemo": Bp2BuildDefaultTrue, - "development/samples/LunarLander": Bp2BuildDefaultTrue, - "development/samples/MultiResolution": Bp2BuildDefaultTrue, - "development/samples/MultiWindow": Bp2BuildDefaultTrue, - "development/samples/NotePad": Bp2BuildDefaultTrue, - "development/samples/Obb": Bp2BuildDefaultTrue, - "development/samples/RSSReader": Bp2BuildDefaultTrue, - "development/samples/ReceiveShareDemo": Bp2BuildDefaultTrue, - "development/samples/SearchableDictionary": Bp2BuildDefaultTrue, - "development/samples/SipDemo": Bp2BuildDefaultTrue, - "development/samples/SkeletonApp": Bp2BuildDefaultTrue, - "development/samples/Snake": Bp2BuildDefaultTrue, - "development/samples/SpellChecker/": Bp2BuildDefaultTrueRecursively, - "development/samples/ThemedNavBarKeyboard": Bp2BuildDefaultTrue, - "development/samples/ToyVpn": Bp2BuildDefaultTrue, - "development/samples/TtsEngine": Bp2BuildDefaultTrue, - "development/samples/USB/AdbTest": Bp2BuildDefaultTrue, - "development/samples/USB/MissileLauncher": Bp2BuildDefaultTrue, - "development/samples/VoiceRecognitionService": Bp2BuildDefaultTrue, - "development/samples/VoicemailProviderDemo": Bp2BuildDefaultTrue, - "development/samples/WiFiDirectDemo": Bp2BuildDefaultTrue, - "development/sdk": Bp2BuildDefaultTrueRecursively, - "external/aac": Bp2BuildDefaultTrueRecursively, - "external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively, - "external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively, - "external/auto/common": Bp2BuildDefaultTrueRecursively, - "external/auto/service": Bp2BuildDefaultTrueRecursively, - "external/boringssl": Bp2BuildDefaultTrueRecursively, - "external/bouncycastle": Bp2BuildDefaultTrue, - "external/brotli": Bp2BuildDefaultTrue, - "external/conscrypt": Bp2BuildDefaultTrue, - "external/e2fsprogs": Bp2BuildDefaultTrueRecursively, - "external/eigen": Bp2BuildDefaultTrueRecursively, - "external/erofs-utils": Bp2BuildDefaultTrueRecursively, - "external/error_prone": Bp2BuildDefaultTrueRecursively, - "external/expat": Bp2BuildDefaultTrueRecursively, - "external/f2fs-tools": Bp2BuildDefaultTrue, - "external/flac": Bp2BuildDefaultTrueRecursively, - "external/fmtlib": Bp2BuildDefaultTrueRecursively, - "external/google-benchmark": Bp2BuildDefaultTrueRecursively, - "external/googletest": Bp2BuildDefaultTrueRecursively, - "external/gwp_asan": Bp2BuildDefaultTrueRecursively, - "external/hamcrest": Bp2BuildDefaultTrueRecursively, - "external/icu": Bp2BuildDefaultTrueRecursively, - "external/icu/android_icu4j": Bp2BuildDefaultFalse, // java rules incomplete - "external/icu/icu4j": Bp2BuildDefaultFalse, // java rules incomplete - "external/jarjar": Bp2BuildDefaultTrueRecursively, - "external/javapoet": Bp2BuildDefaultTrueRecursively, - "external/jemalloc_new": Bp2BuildDefaultTrueRecursively, - "external/jsoncpp": Bp2BuildDefaultTrueRecursively, - "external/junit": Bp2BuildDefaultTrueRecursively, - "external/libavc": Bp2BuildDefaultTrueRecursively, - "external/libcap": Bp2BuildDefaultTrueRecursively, - "external/libcxx": Bp2BuildDefaultTrueRecursively, - "external/libcxxabi": Bp2BuildDefaultTrueRecursively, - "external/libevent": Bp2BuildDefaultTrueRecursively, - "external/libgav1": Bp2BuildDefaultTrueRecursively, - "external/libhevc": Bp2BuildDefaultTrueRecursively, - "external/libmpeg2": Bp2BuildDefaultTrueRecursively, - "external/libpng": Bp2BuildDefaultTrueRecursively, - "external/lz4/lib": Bp2BuildDefaultTrue, - "external/lzma/C": Bp2BuildDefaultTrueRecursively, - "external/mdnsresponder": Bp2BuildDefaultTrueRecursively, - "external/minijail": Bp2BuildDefaultTrueRecursively, - "external/pcre": Bp2BuildDefaultTrueRecursively, - "external/protobuf": Bp2BuildDefaultTrueRecursively, - "external/python/six": Bp2BuildDefaultTrueRecursively, - "external/rappor": Bp2BuildDefaultTrueRecursively, - "external/scudo": Bp2BuildDefaultTrueRecursively, - "external/selinux/libselinux": Bp2BuildDefaultTrueRecursively, - "external/selinux/libsepol": Bp2BuildDefaultTrueRecursively, - "external/zlib": Bp2BuildDefaultTrueRecursively, - "external/zopfli": Bp2BuildDefaultTrueRecursively, - "external/zstd": Bp2BuildDefaultTrueRecursively, - "frameworks/av/media/codecs": Bp2BuildDefaultTrueRecursively, - "frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively, - "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, - "frameworks/base/startop/apps/test": Bp2BuildDefaultTrue, - "frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively, - "frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively, - "frameworks/native/libs/arect": Bp2BuildDefaultTrueRecursively, - "frameworks/native/libs/math": Bp2BuildDefaultTrueRecursively, - "frameworks/native/libs/nativebase": Bp2BuildDefaultTrueRecursively, - "frameworks/native/opengl/tests/gl2_cameraeye": Bp2BuildDefaultTrue, - "frameworks/native/opengl/tests/gl2_java": Bp2BuildDefaultTrue, - "frameworks/native/opengl/tests/testLatency": Bp2BuildDefaultTrue, - "frameworks/native/opengl/tests/testPauseResume": Bp2BuildDefaultTrue, - "frameworks/native/opengl/tests/testViewport": Bp2BuildDefaultTrue, - "frameworks/proto_logging/stats/stats_log_api_gen": Bp2BuildDefaultTrueRecursively, - "libnativehelper": Bp2BuildDefaultTrueRecursively, - "packages/apps/DevCamera": Bp2BuildDefaultTrue, - "packages/apps/HTMLViewer": Bp2BuildDefaultTrue, - "packages/apps/Protips": Bp2BuildDefaultTrue, - "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively, - "packages/modules/adb": Bp2BuildDefaultTrue, - "packages/modules/adb/apex": Bp2BuildDefaultTrue, - "packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively, - "packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively, - "packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively, - "packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively, - "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively, - "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively, - "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultTrue, - "packages/screensavers/Basic": Bp2BuildDefaultTrue, - "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultTrue, - "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, - "prebuilts/tools/common/m2": Bp2BuildDefaultTrue, - "system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures - "system/apex/apexer": Bp2BuildDefaultTrue, - "system/apex/libs": Bp2BuildDefaultTrueRecursively, - "system/apex/proto": Bp2BuildDefaultTrueRecursively, - "system/apex/tools": Bp2BuildDefaultTrueRecursively, - "system/core/debuggerd": Bp2BuildDefaultTrueRecursively, - "system/core/diagnose_usb": Bp2BuildDefaultTrueRecursively, - "system/core/libasyncio": Bp2BuildDefaultTrue, - "system/core/libcrypto_utils": Bp2BuildDefaultTrueRecursively, - "system/core/libcutils": Bp2BuildDefaultTrueRecursively, - "system/core/libpackagelistparser": Bp2BuildDefaultTrueRecursively, - "system/core/libprocessgroup": Bp2BuildDefaultTrue, - "system/core/libprocessgroup/cgrouprc": Bp2BuildDefaultTrue, - "system/core/libprocessgroup/cgrouprc_format": Bp2BuildDefaultTrue, - "system/core/libsystem": Bp2BuildDefaultTrueRecursively, - "system/core/libutils": Bp2BuildDefaultTrueRecursively, - "system/core/libvndksupport": Bp2BuildDefaultTrueRecursively, - "system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively, - "system/libartpalette": Bp2BuildDefaultTrueRecursively, - "system/libbase": Bp2BuildDefaultTrueRecursively, - "system/libfmq": Bp2BuildDefaultTrue, - "system/libhwbinder": Bp2BuildDefaultTrueRecursively, - "system/libprocinfo": Bp2BuildDefaultTrue, - "system/libziparchive": Bp2BuildDefaultTrueRecursively, - "system/logging/liblog": Bp2BuildDefaultTrueRecursively, - "system/media/audio": Bp2BuildDefaultTrueRecursively, - "system/memory/libion": Bp2BuildDefaultTrueRecursively, - "system/memory/libmemunreachable": Bp2BuildDefaultTrueRecursively, - "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively, - "system/timezone/apex": Bp2BuildDefaultTrueRecursively, - "system/timezone/output_data": Bp2BuildDefaultTrueRecursively, - "system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively, - "tools/apksig": Bp2BuildDefaultTrue, - "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, + "prebuilts/runtime/mainline/platform/sdk": Bp2BuildDefaultTrueRecursively, + "art/libartpalette": Bp2BuildDefaultTrueRecursively, + "art/libartbase": Bp2BuildDefaultTrueRecursively, + "art/libdexfile": Bp2BuildDefaultTrueRecursively, + "art/libnativebridge": Bp2BuildDefaultTrueRecursively, + "art/runtime": Bp2BuildDefaultTrueRecursively, + "art/tools": Bp2BuildDefaultTrue, + "bionic": Bp2BuildDefaultTrueRecursively, + "bootable/recovery/tools/recovery_l10n": Bp2BuildDefaultTrue, + "build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively, + "build/bazel/examples/soong_config_variables": Bp2BuildDefaultTrueRecursively, + "build/bazel/examples/python": Bp2BuildDefaultTrueRecursively, + "build/bazel/examples/gensrcs": Bp2BuildDefaultTrueRecursively, + "build/make/target/product/security": Bp2BuildDefaultTrue, + "build/make/tools/signapk": Bp2BuildDefaultTrue, + "build/make/tools/zipalign": Bp2BuildDefaultTrueRecursively, + "build/soong": Bp2BuildDefaultTrue, + "build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir + "build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue, + "build/soong/cc/symbolfile": Bp2BuildDefaultTrue, + "build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively, + "build/soong/scripts": Bp2BuildDefaultTrueRecursively, + "cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively, + "development/apps/DevelopmentSettings": Bp2BuildDefaultTrue, + "development/apps/Fallback": Bp2BuildDefaultTrue, + "development/apps/WidgetPreview": Bp2BuildDefaultTrue, + "development/samples/BasicGLSurfaceView": Bp2BuildDefaultTrue, + "development/samples/BluetoothChat": Bp2BuildDefaultTrue, + "development/samples/BrokenKeyDerivation": Bp2BuildDefaultTrue, + "development/samples/Compass": Bp2BuildDefaultTrue, + "development/samples/ContactManager": Bp2BuildDefaultTrue, + "development/samples/FixedGridLayout": Bp2BuildDefaultTrue, + "development/samples/HelloEffects": Bp2BuildDefaultTrue, + "development/samples/Home": Bp2BuildDefaultTrue, + "development/samples/HoneycombGallery": Bp2BuildDefaultTrue, + "development/samples/JetBoy": Bp2BuildDefaultTrue, + "development/samples/KeyChainDemo": Bp2BuildDefaultTrue, + "development/samples/LceDemo": Bp2BuildDefaultTrue, + "development/samples/LunarLander": Bp2BuildDefaultTrue, + "development/samples/MultiResolution": Bp2BuildDefaultTrue, + "development/samples/MultiWindow": Bp2BuildDefaultTrue, + "development/samples/NotePad": Bp2BuildDefaultTrue, + "development/samples/Obb": Bp2BuildDefaultTrue, + "development/samples/RSSReader": Bp2BuildDefaultTrue, + "development/samples/ReceiveShareDemo": Bp2BuildDefaultTrue, + "development/samples/SearchableDictionary": Bp2BuildDefaultTrue, + "development/samples/SipDemo": Bp2BuildDefaultTrue, + "development/samples/SkeletonApp": Bp2BuildDefaultTrue, + "development/samples/Snake": Bp2BuildDefaultTrue, + "development/samples/SpellChecker/": Bp2BuildDefaultTrueRecursively, + "development/samples/ThemedNavBarKeyboard": Bp2BuildDefaultTrue, + "development/samples/ToyVpn": Bp2BuildDefaultTrue, + "development/samples/TtsEngine": Bp2BuildDefaultTrue, + "development/samples/USB/AdbTest": Bp2BuildDefaultTrue, + "development/samples/USB/MissileLauncher": Bp2BuildDefaultTrue, + "development/samples/VoiceRecognitionService": Bp2BuildDefaultTrue, + "development/samples/VoicemailProviderDemo": Bp2BuildDefaultTrue, + "development/samples/WiFiDirectDemo": Bp2BuildDefaultTrue, + "development/sdk": Bp2BuildDefaultTrueRecursively, + "external/aac": Bp2BuildDefaultTrueRecursively, + "external/arm-optimized-routines": Bp2BuildDefaultTrueRecursively, + "external/auto/android-annotation-stubs": Bp2BuildDefaultTrueRecursively, + "external/auto/common": Bp2BuildDefaultTrueRecursively, + "external/auto/service": Bp2BuildDefaultTrueRecursively, + "external/boringssl": Bp2BuildDefaultTrueRecursively, + "external/bouncycastle": Bp2BuildDefaultTrue, + "external/brotli": Bp2BuildDefaultTrue, + "external/conscrypt": Bp2BuildDefaultTrue, + "external/e2fsprogs": Bp2BuildDefaultTrueRecursively, + "external/eigen": Bp2BuildDefaultTrueRecursively, + "external/erofs-utils": Bp2BuildDefaultTrueRecursively, + "external/error_prone": Bp2BuildDefaultTrueRecursively, + "external/expat": Bp2BuildDefaultTrueRecursively, + "external/f2fs-tools": Bp2BuildDefaultTrue, + "external/flac": Bp2BuildDefaultTrueRecursively, + "external/fmtlib": Bp2BuildDefaultTrueRecursively, + "external/google-benchmark": Bp2BuildDefaultTrueRecursively, + "external/googletest": Bp2BuildDefaultTrueRecursively, + "external/gwp_asan": Bp2BuildDefaultTrueRecursively, + "external/hamcrest": Bp2BuildDefaultTrueRecursively, + "external/icu": Bp2BuildDefaultTrueRecursively, + "external/icu/android_icu4j": Bp2BuildDefaultFalse, // java rules incomplete + "external/icu/icu4j": Bp2BuildDefaultFalse, // java rules incomplete + "external/jarjar": Bp2BuildDefaultTrueRecursively, + "external/javapoet": Bp2BuildDefaultTrueRecursively, + "external/jemalloc_new": Bp2BuildDefaultTrueRecursively, + "external/jsoncpp": Bp2BuildDefaultTrueRecursively, + "external/junit": Bp2BuildDefaultTrueRecursively, + "external/libavc": Bp2BuildDefaultTrueRecursively, + "external/libcap": Bp2BuildDefaultTrueRecursively, + "external/libcxx": Bp2BuildDefaultTrueRecursively, + "external/libcxxabi": Bp2BuildDefaultTrueRecursively, + "external/libevent": Bp2BuildDefaultTrueRecursively, + "external/libgav1": Bp2BuildDefaultTrueRecursively, + "external/libhevc": Bp2BuildDefaultTrueRecursively, + "external/libmpeg2": Bp2BuildDefaultTrueRecursively, + "external/libpng": Bp2BuildDefaultTrueRecursively, + "external/lz4/lib": Bp2BuildDefaultTrue, + "external/lzma/C": Bp2BuildDefaultTrueRecursively, + "external/mdnsresponder": Bp2BuildDefaultTrueRecursively, + "external/minijail": Bp2BuildDefaultTrueRecursively, + "external/pcre": Bp2BuildDefaultTrueRecursively, + "external/protobuf": Bp2BuildDefaultTrueRecursively, + "external/python/six": Bp2BuildDefaultTrueRecursively, + "external/rappor": Bp2BuildDefaultTrueRecursively, + "external/scudo": Bp2BuildDefaultTrueRecursively, + "external/selinux/libselinux": Bp2BuildDefaultTrueRecursively, + "external/selinux/libsepol": Bp2BuildDefaultTrueRecursively, + "external/zlib": Bp2BuildDefaultTrueRecursively, + "external/zopfli": Bp2BuildDefaultTrueRecursively, + "external/zstd": Bp2BuildDefaultTrueRecursively, + "frameworks/av/media/codecs": Bp2BuildDefaultTrueRecursively, + "frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively, + "frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue, + "frameworks/base/startop/apps/test": Bp2BuildDefaultTrue, + "frameworks/base/tests/appwidgets/AppWidgetHostTest": Bp2BuildDefaultTrueRecursively, + "frameworks/native/libs/adbd_auth": Bp2BuildDefaultTrueRecursively, + "frameworks/native/libs/arect": Bp2BuildDefaultTrueRecursively, + "frameworks/native/libs/math": Bp2BuildDefaultTrueRecursively, + "frameworks/native/libs/nativebase": Bp2BuildDefaultTrueRecursively, + "frameworks/native/opengl/tests/gl2_cameraeye": Bp2BuildDefaultTrue, + "frameworks/native/opengl/tests/gl2_java": Bp2BuildDefaultTrue, + "frameworks/native/opengl/tests/testLatency": Bp2BuildDefaultTrue, + "frameworks/native/opengl/tests/testPauseResume": Bp2BuildDefaultTrue, + "frameworks/native/opengl/tests/testViewport": Bp2BuildDefaultTrue, + "frameworks/proto_logging/stats/stats_log_api_gen": Bp2BuildDefaultTrueRecursively, + "libnativehelper": Bp2BuildDefaultTrueRecursively, + "packages/apps/DevCamera": Bp2BuildDefaultTrue, + "packages/apps/HTMLViewer": Bp2BuildDefaultTrue, + "packages/apps/Protips": Bp2BuildDefaultTrue, + "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively, + "packages/modules/adb": Bp2BuildDefaultTrue, + "packages/modules/adb/apex": Bp2BuildDefaultTrue, + "packages/modules/adb/crypto": Bp2BuildDefaultTrueRecursively, + "packages/modules/adb/libs": Bp2BuildDefaultTrueRecursively, + "packages/modules/adb/pairing_auth": Bp2BuildDefaultTrueRecursively, + "packages/modules/adb/pairing_connection": Bp2BuildDefaultTrueRecursively, + "packages/modules/adb/proto": Bp2BuildDefaultTrueRecursively, + "packages/modules/adb/tls": Bp2BuildDefaultTrueRecursively, + "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultTrue, + "packages/screensavers/Basic": Bp2BuildDefaultTrue, + "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultTrue, + "prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively, + "prebuilts/tools/common/m2": Bp2BuildDefaultTrue, + "system/apex": Bp2BuildDefaultFalse, // TODO(b/207466993): flaky failures + "system/apex/apexer": Bp2BuildDefaultTrue, + "system/apex/libs": Bp2BuildDefaultTrueRecursively, + "system/apex/proto": Bp2BuildDefaultTrueRecursively, + "system/apex/tools": Bp2BuildDefaultTrueRecursively, + "system/core/debuggerd": Bp2BuildDefaultTrueRecursively, + "system/core/diagnose_usb": Bp2BuildDefaultTrueRecursively, + "system/core/libasyncio": Bp2BuildDefaultTrue, + "system/core/libcrypto_utils": Bp2BuildDefaultTrueRecursively, + "system/core/libcutils": Bp2BuildDefaultTrueRecursively, + "system/core/libpackagelistparser": Bp2BuildDefaultTrueRecursively, + "system/core/libprocessgroup": Bp2BuildDefaultTrue, + "system/core/libprocessgroup/cgrouprc": Bp2BuildDefaultTrue, + "system/core/libprocessgroup/cgrouprc_format": Bp2BuildDefaultTrue, + "system/core/libsystem": Bp2BuildDefaultTrueRecursively, + "system/core/libutils": Bp2BuildDefaultTrueRecursively, + "system/core/libvndksupport": Bp2BuildDefaultTrueRecursively, + "system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively, + "system/core/property_service/libpropertyinfoserializer": Bp2BuildDefaultTrueRecursively, + "system/libartpalette": Bp2BuildDefaultTrueRecursively, + "system/libbase": Bp2BuildDefaultTrueRecursively, + "system/libfmq": Bp2BuildDefaultTrue, + "system/libhwbinder": Bp2BuildDefaultTrueRecursively, + "system/libprocinfo": Bp2BuildDefaultTrue, + "system/libziparchive": Bp2BuildDefaultTrueRecursively, + "system/logging/liblog": Bp2BuildDefaultTrueRecursively, + "system/media/audio": Bp2BuildDefaultTrueRecursively, + "system/memory/libion": Bp2BuildDefaultTrueRecursively, + "system/memory/libmemunreachable": Bp2BuildDefaultTrueRecursively, + "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively, + "system/timezone/apex": Bp2BuildDefaultTrueRecursively, + "system/timezone/output_data": Bp2BuildDefaultTrueRecursively, + "system/tools/sysprop": Bp2BuildDefaultTrue, + "system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively, + "tools/apksig": Bp2BuildDefaultTrue, + "tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively, } Bp2buildKeepExistingBuildFile = map[string]bool{ diff --git a/android/bazel_handler.go b/android/bazel_handler.go index f1ec55eb9..3be9805be 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -34,6 +34,21 @@ import ( "android/soong/bazel" ) +var ( + writeBazelFile = pctx.AndroidStaticRule("bazelWriteFileRule", blueprint.RuleParams{ + Command: `sed "s/\\\\n/\n/g" ${out}.rsp >${out}`, + Rspfile: "${out}.rsp", + RspfileContent: "${content}", + }, "content") + _ = pctx.HostBinToolVariable("bazelBuildRunfilesTool", "build-runfiles") + buildRunfilesRule = pctx.AndroidStaticRule("bazelBuildRunfiles", blueprint.RuleParams{ + Command: "${bazelBuildRunfilesTool} ${in} ${outDir}", + Depfile: "", + Description: "", + CommandDeps: []string{"${bazelBuildRunfilesTool}"}, + }, "outDir") +) + func init() { RegisterMixedBuildsMutator(InitRegistrationContext) } @@ -173,26 +188,26 @@ type MockBazelContext struct { LabelToPythonBinary map[string]string } -func (m MockBazelContext) QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey) { +func (m MockBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) { panic("unimplemented") } -func (m MockBazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, error) { +func (m MockBazelContext) GetOutputFiles(label string, _ configKey) ([]string, error) { result, _ := m.LabelToOutputFiles[label] return result, nil } -func (m MockBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, error) { +func (m MockBazelContext) GetCcInfo(label string, _ configKey) (cquery.CcInfo, error) { result, _ := m.LabelToCcInfo[label] return result, nil } -func (m MockBazelContext) GetPythonBinary(label string, cfgKey configKey) (string, error) { +func (m MockBazelContext) GetPythonBinary(label string, _ configKey) (string, error) { result, _ := m.LabelToPythonBinary[label] return result, nil } -func (m MockBazelContext) InvokeBazel(config Config) error { +func (m MockBazelContext) InvokeBazel(_ Config) error { panic("unimplemented") } @@ -246,23 +261,23 @@ func (bazelCtx *bazelContext) GetPythonBinary(label string, cfgKey configKey) (s return "", fmt.Errorf("no bazel response found for %v", key) } -func (n noopBazelContext) QueueBazelRequest(label string, requestType cqueryRequest, cfgKey configKey) { +func (n noopBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configKey) { panic("unimplemented") } -func (n noopBazelContext) GetOutputFiles(label string, cfgKey configKey) ([]string, error) { +func (n noopBazelContext) GetOutputFiles(_ string, _ configKey) ([]string, error) { panic("unimplemented") } -func (n noopBazelContext) GetCcInfo(label string, cfgKey configKey) (cquery.CcInfo, error) { +func (n noopBazelContext) GetCcInfo(_ string, _ configKey) (cquery.CcInfo, error) { panic("unimplemented") } -func (n noopBazelContext) GetPythonBinary(label string, cfgKey configKey) (string, error) { +func (n noopBazelContext) GetPythonBinary(_ string, _ configKey) (string, error) { panic("unimplemented") } -func (n noopBazelContext) InvokeBazel(config Config) error { +func (n noopBazelContext) InvokeBazel(_ Config) error { panic("unimplemented") } @@ -304,7 +319,7 @@ func bazelPathsFromConfig(c *config) (*bazelPaths, error) { p := bazelPaths{ soongOutDir: c.soongOutDir, } - missingEnvVars := []string{} + var missingEnvVars []string if len(c.Getenv("BAZEL_HOME")) > 1 { p.homeDir = c.Getenv("BAZEL_HOME") } else { @@ -365,10 +380,8 @@ type mockBazelRunner struct { extraFlags []string } -func (r *mockBazelRunner) issueBazelCommand(paths *bazelPaths, - runName bazel.RunName, - command bazelCommand, - extraFlags ...string) (string, string, error) { +func (r *mockBazelRunner) issueBazelCommand(_ *bazelPaths, _ bazel.RunName, + command bazelCommand, extraFlags ...string) (string, string, error) { r.commands = append(r.commands, command) r.extraFlags = append(r.extraFlags, strings.Join(extraFlags, " ")) if ret, ok := r.bazelCommandResults[command]; ok { @@ -396,26 +409,30 @@ func (r *builtinBazelRunner) issueBazelCommand(paths *bazelPaths, runName bazel. command.command, } cmdFlags = append(cmdFlags, command.expression) - cmdFlags = append(cmdFlags, "--profile="+shared.BazelMetricsFilename(paths, runName)) - - // Set default platforms to canonicalized values for mixed builds requests. - // If these are set in the bazelrc, they will have values that are - // non-canonicalized to @sourceroot labels, and thus be invalid when - // referenced from the buildroot. - // - // The actual platform values here may be overridden by configuration - // transitions from the buildroot. - cmdFlags = append(cmdFlags, - fmt.Sprintf("--platforms=%s", "//build/bazel/platforms:android_target")) cmdFlags = append(cmdFlags, - fmt.Sprintf("--extra_toolchains=%s", "//prebuilts/clang/host/linux-x86:all")) - // This should be parameterized on the host OS, but let's restrict to linux - // to keep things simple for now. - cmdFlags = append(cmdFlags, - fmt.Sprintf("--host_platform=%s", "//build/bazel/platforms:linux_x86_64")) - - // Explicitly disable downloading rules (such as canonical C++ and Java rules) from the network. - cmdFlags = append(cmdFlags, "--experimental_repository_disable_download") + // TODO(asmundak): is it needed in every build? + "--profile="+shared.BazelMetricsFilename(paths, runName), + + // Set default platforms to canonicalized values for mixed builds requests. + // If these are set in the bazelrc, they will have values that are + // non-canonicalized to @sourceroot labels, and thus be invalid when + // referenced from the buildroot. + // + // The actual platform values here may be overridden by configuration + // transitions from the buildroot. + fmt.Sprintf("--platforms=%s", "//build/bazel/platforms:android_target"), + fmt.Sprintf("--extra_toolchains=%s", "//prebuilts/clang/host/linux-x86:all"), + + // This should be parameterized on the host OS, but let's restrict to linux + // to keep things simple for now. + fmt.Sprintf("--host_platform=%s", "//build/bazel/platforms:linux_x86_64"), + + // Explicitly disable downloading rules (such as canonical C++ and Java rules) from the network. + "--experimental_repository_disable_download", + + // Suppress noise + "--ui_event_filters=-INFO", + "--noshow_progress") cmdFlags = append(cmdFlags, extraFlags...) bazelCmd := exec.Command(paths.bazelPath, cmdFlags...) @@ -682,8 +699,6 @@ func (p *bazelPaths) outDir() string { func (context *bazelContext) InvokeBazel(config Config) error { context.results = make(map[cqueryKey]string) - var cqueryOutput string - var cqueryErr string var err error soongInjectionPath := absolutePath(context.paths.injectedFilesDir()) @@ -700,45 +715,27 @@ func (context *bazelContext) InvokeBazel(config Config) error { return err } } - err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "WORKSPACE.bazel"), []byte{}, 0666) - if err != nil { + if err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "WORKSPACE.bazel"), []byte{}, 0666); err != nil { return err } - - err = ioutil.WriteFile( - filepath.Join(mixedBuildsPath, "main.bzl"), - context.mainBzlFileContents(), 0666) - if err != nil { + if err = ioutil.WriteFile(filepath.Join(mixedBuildsPath, "main.bzl"), context.mainBzlFileContents(), 0666); err != nil { return err } - - err = ioutil.WriteFile( - filepath.Join(mixedBuildsPath, "BUILD.bazel"), - context.mainBuildFileContents(), 0666) - if err != nil { + if err = ioutil.WriteFile(filepath.Join(mixedBuildsPath, "BUILD.bazel"), context.mainBuildFileContents(), 0666); err != nil { return err } cqueryFileRelpath := filepath.Join(context.paths.injectedFilesDir(), "buildroot.cquery") - err = ioutil.WriteFile( - absolutePath(cqueryFileRelpath), - context.cqueryStarlarkFileContents(), 0666) - if err != nil { + if err = ioutil.WriteFile(absolutePath(cqueryFileRelpath), context.cqueryStarlarkFileContents(), 0666); err != nil { return err } - buildrootLabel := "@soong_injection//mixed_builds:buildroot" - cqueryOutput, cqueryErr, err = context.issueBazelCommand( - context.paths, - bazel.CqueryBuildRootRunName, - bazelCommand{"cquery", fmt.Sprintf("deps(%s, 2)", buildrootLabel)}, - "--output=starlark", - "--starlark:file="+absolutePath(cqueryFileRelpath)) - err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"), - []byte(cqueryOutput), 0666) + const buildrootLabel = "@soong_injection//mixed_builds:buildroot" + cqueryCmd := bazelCommand{"cquery", fmt.Sprintf("deps(%s, 2)", buildrootLabel)} + cqueryOutput, cqueryErr, err := context.issueBazelCommand(context.paths, bazel.CqueryBuildRootRunName, cqueryCmd, + "--output=starlark", "--starlark:file="+absolutePath(cqueryFileRelpath)) if err != nil { - return err + err = ioutil.WriteFile(filepath.Join(soongInjectionPath, "cquery.out"), []byte(cqueryOutput), 0666) } - if err != nil { return err } @@ -750,7 +747,6 @@ func (context *bazelContext) InvokeBazel(config Config) error { cqueryResults[splitLine[0]] = splitLine[1] } } - for val := range context.requests { if cqueryResult, ok := cqueryResults[getCqueryId(val)]; ok { context.results[val] = cqueryResult @@ -762,37 +758,27 @@ func (context *bazelContext) InvokeBazel(config Config) error { // Issue an aquery command to retrieve action information about the bazel build tree. // - var aqueryOutput string - var coverageFlags []string + // Use jsonproto instead of proto; actual proto parsing would require a dependency on Bazel's + // proto sources, which would add a number of unnecessary dependencies. + extraFlags := []string{"--output=jsonproto", "--include_file_write_contents"} if Bool(config.productVariables.ClangCoverage) { - coverageFlags = append(coverageFlags, "--collect_code_coverage") - if len(config.productVariables.NativeCoveragePaths) > 0 || - len(config.productVariables.NativeCoverageExcludePaths) > 0 { - includePaths := JoinWithPrefixAndSeparator(config.productVariables.NativeCoveragePaths, "+", ",") - excludePaths := JoinWithPrefixAndSeparator(config.productVariables.NativeCoverageExcludePaths, "-", ",") - if len(includePaths) > 0 && len(excludePaths) > 0 { - includePaths += "," - } - coverageFlags = append(coverageFlags, fmt.Sprintf(`--instrumentation_filter=%s`, - includePaths+excludePaths)) + extraFlags = append(extraFlags, "--collect_code_coverage") + paths := make([]string, 0, 2) + if p := config.productVariables.NativeCoveragePaths; len(p) > 0 { + paths = append(paths, JoinWithPrefixAndSeparator(p, "+", ",")) + } + if p := config.productVariables.NativeCoverageExcludePaths; len(p) > 0 { + paths = append(paths, JoinWithPrefixAndSeparator(p, "-", ",")) + } + if len(paths) > 0 { + extraFlags = append(extraFlags, "--instrumentation_filter="+strings.Join(paths, ",")) } } - - extraFlags := append([]string{"--output=jsonproto"}, coverageFlags...) - - aqueryOutput, _, err = context.issueBazelCommand( - context.paths, - bazel.AqueryBuildRootRunName, - bazelCommand{"aquery", fmt.Sprintf("deps(%s)", buildrootLabel)}, - // Use jsonproto instead of proto; actual proto parsing would require a dependency on Bazel's - // proto sources, which would add a number of unnecessary dependencies. - extraFlags...) - - if err != nil { - return err + aqueryCmd := bazelCommand{"aquery", fmt.Sprintf("deps(%s)", buildrootLabel)} + if aqueryOutput, _, err := context.issueBazelCommand(context.paths, bazel.AqueryBuildRootRunName, aqueryCmd, + extraFlags...); err == nil { + context.buildStatements, context.depsets, err = bazel.AqueryBuildStatements([]byte(aqueryOutput)) } - - context.buildStatements, context.depsets, err = bazel.AqueryBuildStatements([]byte(aqueryOutput)) if err != nil { return err } @@ -800,12 +786,8 @@ func (context *bazelContext) InvokeBazel(config Config) error { // Issue a build command of the phony root to generate symlink forests for dependencies of the // Bazel build. This is necessary because aquery invocations do not generate this symlink forest, // but some of symlinks may be required to resolve source dependencies of the build. - _, _, err = context.issueBazelCommand( - context.paths, - bazel.BazelBuildPhonyRootRunName, - bazelCommand{"build", "@soong_injection//mixed_builds:phonyroot"}) - - if err != nil { + buildCmd := bazelCommand{"build", "@soong_injection//mixed_builds:phonyroot"} + if _, _, err = context.issueBazelCommand(context.paths, bazel.BazelBuildPhonyRootRunName, buildCmd); err != nil { return err } @@ -874,13 +856,56 @@ func (c *bazelSingleton) GenerateBuildActions(ctx SingletonContext) { executionRoot := path.Join(ctx.Config().BazelContext.OutputBase(), "execroot", "__main__") bazelOutDir := path.Join(executionRoot, "bazel-out") for index, buildStatement := range ctx.Config().BazelContext.BuildStatementsToRegister() { - if len(buildStatement.Command) < 1 { + if len(buildStatement.Command) > 0 { + rule := NewRuleBuilder(pctx, ctx) + createCommand(rule.Command(), buildStatement, executionRoot, bazelOutDir, ctx) + desc := fmt.Sprintf("%s: %s", buildStatement.Mnemonic, buildStatement.OutputPaths) + rule.Build(fmt.Sprintf("bazel %d", index), desc) + continue + } + // Certain actions returned by aquery (for instance FileWrite) do not contain a command + // and thus require special treatment. If BuildStatement were an interface implementing + // buildRule(ctx) function, the code here would just call it. + // Unfortunately, the BuildStatement is defined in + // the 'bazel' package, which cannot depend on 'android' package where ctx is defined, + // because this would cause circular dependency. So, until we move aquery processing + // to the 'android' package, we need to handle special cases here. + if buildStatement.Mnemonic == "FileWrite" || buildStatement.Mnemonic == "SourceSymlinkManifest" { + // Pass file contents as the value of the rule's "content" argument. + // Escape newlines and $ in the contents (the action "writeBazelFile" restores "\\n" + // back to the newline, and Ninja reads $$ as $. + escaped := strings.ReplaceAll(strings.ReplaceAll(buildStatement.FileContents, "\n", "\\n"), + "$", "$$") + ctx.Build(pctx, BuildParams{ + Rule: writeBazelFile, + Output: PathForBazelOut(ctx, buildStatement.OutputPaths[0]), + Description: fmt.Sprintf("%s %s", buildStatement.Mnemonic, buildStatement.OutputPaths[0]), + Args: map[string]string{ + "content": escaped, + }, + }) + } else if buildStatement.Mnemonic == "SymlinkTree" { + // build-runfiles arguments are the manifest file and the target directory + // where it creates the symlink tree according to this manifest (and then + // writes the MANIFEST file to it). + outManifest := PathForBazelOut(ctx, buildStatement.OutputPaths[0]) + outManifestPath := outManifest.String() + if !strings.HasSuffix(outManifestPath, "MANIFEST") { + panic("the base name of the symlink tree action should be MANIFEST, got " + outManifestPath) + } + outDir := filepath.Dir(outManifestPath) + ctx.Build(pctx, BuildParams{ + Rule: buildRunfilesRule, + Output: outManifest, + Inputs: []Path{PathForBazelOut(ctx, buildStatement.InputPaths[0])}, + Description: "symlink tree for " + outDir, + Args: map[string]string{ + "outDir": outDir, + }, + }) + } else { panic(fmt.Sprintf("unhandled build statement: %v", buildStatement)) } - rule := NewRuleBuilder(pctx, ctx) - createCommand(rule.Command(), buildStatement, executionRoot, bazelOutDir, ctx) - desc := fmt.Sprintf("%s: %s", buildStatement.Mnemonic, buildStatement.OutputPaths) - rule.Build(fmt.Sprintf("bazel %d", index), desc) } } diff --git a/android/sdk.go b/android/sdk.go index 533f2f4ec..07b94b246 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -677,6 +677,10 @@ type SdkMemberType interface { // SupportedLinkages returns the names of the linkage variants supported by this module. SupportedLinkages() []string + // ArePrebuiltsRequired returns true if prebuilts are required in the sdk snapshot, false + // otherwise. + ArePrebuiltsRequired() bool + // AddDependencies adds dependencies from the SDK module to all the module variants the member // type contributes to the SDK. `names` is the list of module names given in the member type // property (as returned by SdkPropertyName()) in the SDK module. The exact set of variants @@ -782,7 +786,12 @@ type SdkMemberTypeBase struct { // If not specified then it is assumed to be available on all targeted build releases. SupportedBuildReleaseSpecification string - SupportsSdk bool + // Set to true if this must be usable with the sdk/sdk_snapshot module types. Otherwise, it will + // only be usable with module_exports/module_exports_snapshots module types. + SupportsSdk bool + + // Set to true if prebuilt host artifacts of this member may be specific to the host OS. Only + // applicable to modules where HostSupported() is true. HostOsDependent bool // When set to true UseSourceModuleTypeInSnapshot indicates that the member type creates a source @@ -790,6 +799,11 @@ type SdkMemberTypeBase struct { // code from automatically adding a prefer: true flag. UseSourceModuleTypeInSnapshot bool + // Set to proptools.BoolPtr(false) if this member does not generate prebuilts but is only provided + // to allow the sdk to gather members from this member's dependencies. If not specified then + // defaults to true. + PrebuiltsRequired *bool + // The list of supported traits. Traits []SdkMemberTrait } @@ -814,6 +828,10 @@ func (b *SdkMemberTypeBase) IsHostOsDependent() bool { return b.HostOsDependent } +func (b *SdkMemberTypeBase) ArePrebuiltsRequired() bool { + return proptools.BoolDefault(b.PrebuiltsRequired, true) +} + func (b *SdkMemberTypeBase) UsesSourceModuleTypeInSnapshot() bool { return b.UseSourceModuleTypeInSnapshot } diff --git a/android/sdk_version.go b/android/sdk_version.go index 2004c9290..c188c4808 100644 --- a/android/sdk_version.go +++ b/android/sdk_version.go @@ -28,6 +28,9 @@ type SdkContext interface { // MinSdkVersion returns SdkSpec that corresponds to the min_sdk_version property of the current module, // or from sdk_version if it is not set. MinSdkVersion(ctx EarlyModuleContext) SdkSpec + // ReplaceMaxSdkVersionPlaceholder returns SdkSpec to replace the maxSdkVersion property of permission and + // uses-permission tags if it is set. + ReplaceMaxSdkVersionPlaceholder(ctx EarlyModuleContext) SdkSpec // TargetSdkVersion returns the SdkSpec that corresponds to the target_sdk_version property of the current module, // or from sdk_version if it is not set. TargetSdkVersion(ctx EarlyModuleContext) SdkSpec diff --git a/apex/Android.bp b/apex/Android.bp index fcdf8e6be..6533c6103 100644 --- a/apex/Android.bp +++ b/apex/Android.bp @@ -23,6 +23,7 @@ bootstrap_go_package { srcs: [ "androidmk.go", "apex.go", + "apex_sdk_member.go", "apex_singleton.go", "builder.go", "constants.go", diff --git a/apex/apex.go b/apex/apex.go index 5678b06bf..7b6707ce6 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -606,6 +606,18 @@ type dependencyTag struct { // replacement. This is needed because some prebuilt modules do not provide all the information // needed by the apex. sourceOnly bool + + // If not-nil and an APEX is a member of an SDK then dependencies of that APEX with this tag will + // also be added as exported members of that SDK. + memberType android.SdkMemberType +} + +func (d *dependencyTag) SdkMemberType(_ android.Module) android.SdkMemberType { + return d.memberType +} + +func (d *dependencyTag) ExportMember() bool { + return true } func (d *dependencyTag) String() string { @@ -617,6 +629,7 @@ func (d *dependencyTag) ReplaceSourceWithPrebuilt() bool { } var _ android.ReplaceSourceWithPrebuilt = &dependencyTag{} +var _ android.SdkMemberDependencyTag = &dependencyTag{} var ( androidAppTag = &dependencyTag{name: "androidApp", payload: true} @@ -624,8 +637,8 @@ var ( certificateTag = &dependencyTag{name: "certificate"} executableTag = &dependencyTag{name: "executable", payload: true} fsTag = &dependencyTag{name: "filesystem", payload: true} - bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true} - sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true} + bcpfTag = &dependencyTag{name: "bootclasspathFragment", payload: true, sourceOnly: true, memberType: java.BootclasspathFragmentSdkMemberType} + sscpfTag = &dependencyTag{name: "systemserverclasspathFragment", payload: true, sourceOnly: true, memberType: java.SystemServerClasspathFragmentSdkMemberType} compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true} javaLibTag = &dependencyTag{name: "javaLib", payload: true} jniLibTag = &dependencyTag{name: "jniLib", payload: true} diff --git a/apex/apex_sdk_member.go b/apex/apex_sdk_member.go new file mode 100644 index 000000000..284158f07 --- /dev/null +++ b/apex/apex_sdk_member.go @@ -0,0 +1,58 @@ +// Copyright (C) 2022 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package apex + +import ( + "android/soong/android" + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +// This file contains support for using apex modules within an sdk. + +func init() { + // Register sdk member types. + android.RegisterSdkMemberType(&apexSdkMemberType{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ + PropertyName: "apexes", + SupportsSdk: true, + + // The apexes property does not need to be included in the snapshot as adding an apex to an + // sdk does not produce any prebuilts of the apex. + PrebuiltsRequired: proptools.BoolPtr(false), + }, + }) +} + +type apexSdkMemberType struct { + android.SdkMemberTypeBase +} + +func (mt *apexSdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) { + ctx.AddVariationDependencies(nil, dependencyTag, names...) +} + +func (mt *apexSdkMemberType) IsInstance(module android.Module) bool { + _, ok := module.(*apexBundle) + return ok +} + +func (mt *apexSdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule { + panic("Sdk does not create prebuilts of the apexes in its snapshot") +} + +func (mt *apexSdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties { + panic("Sdk does not create prebuilts of the apexes in its snapshot") +} diff --git a/apex/builder.go b/apex/builder.go index e3c447632..1956b4447 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -76,16 +76,12 @@ var ( Command: `rm -f $out && ${jsonmodify} $in ` + `-a provideNativeLibs ${provideNativeLibs} ` + `-a requireNativeLibs ${requireNativeLibs} ` + + `-se version 0 ${default_version} ` + `${opt} ` + `-o $out`, CommandDeps: []string{"${jsonmodify}"}, Description: "prepare ${out}", - }, "provideNativeLibs", "requireNativeLibs", "opt") - - stripCommentsApexManifestRule = pctx.StaticRule("stripCommentsApexManifestRule", blueprint.RuleParams{ - Command: `sed '/^\s*\/\//d' $in > $out`, - Description: "strip lines starting with // ${in}=>${out}", - }) + }, "provideNativeLibs", "requireNativeLibs", "default_version", "opt") stripApexManifestRule = pctx.StaticRule("stripApexManifestRule", blueprint.RuleParams{ Command: `rm -f $out && ${conv_apex_manifest} strip $in -o $out`, @@ -112,7 +108,6 @@ var ( `--canned_fs_config ${canned_fs_config} ` + `--include_build_info ` + `--payload_type image ` + - `--apex_version ${apex_version} ` + `--key ${key} ${opt_flags} ${image_dir} ${out} `, CommandDeps: []string{"${apexer}", "${avbtool}", "${e2fsdroid}", "${merge_zips}", "${mke2fs}", "${resize2fs}", "${sefcontext_compile}", "${make_f2fs}", "${sload_f2fs}", "${make_erofs}", @@ -120,7 +115,7 @@ var ( Rspfile: "${out}.copy_commands", RspfileContent: "${copy_commands}", Description: "APEX ${image_dir} => ${out}", - }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "payload_fs_type", "apex_version") + }, "tool_path", "image_dir", "copy_commands", "file_contexts", "canned_fs_config", "key", "opt_flags", "manifest", "payload_fs_type") zipApexRule = pctx.StaticRule("zipApexRule", blueprint.RuleParams{ Command: `rm -rf ${image_dir} && mkdir -p ${image_dir} && ` + @@ -128,13 +123,12 @@ var ( `APEXER_TOOL_PATH=${tool_path} ` + `${apexer} --force --manifest ${manifest} ` + `--payload_type zip ` + - `--apex_version ${apex_version} ` + `${image_dir} ${out} `, CommandDeps: []string{"${apexer}", "${merge_zips}", "${soong_zip}", "${zipalign}", "${aapt2}"}, Rspfile: "${out}.copy_commands", RspfileContent: "${copy_commands}", Description: "ZipAPEX ${image_dir} => ${out}", - }, "tool_path", "image_dir", "copy_commands", "manifest", "apex_version") + }, "tool_path", "image_dir", "copy_commands", "manifest") apexProtoConvertRule = pctx.AndroidStaticRule("apexProtoConvertRule", blueprint.RuleParams{ @@ -212,21 +206,15 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, optCommands = append(optCommands, "-a jniLibs "+strings.Join(jniLibs, " ")) } - manifestJsonCommentsStripped := android.PathForModuleOut(ctx, "apex_manifest_comments_stripped.json") - ctx.Build(pctx, android.BuildParams{ - Rule: stripCommentsApexManifestRule, - Input: src, - Output: manifestJsonCommentsStripped, - }) - manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json") ctx.Build(pctx, android.BuildParams{ Rule: apexManifestRule, - Input: manifestJsonCommentsStripped, + Input: src, Output: manifestJsonFullOut, Args: map[string]string{ "provideNativeLibs": strings.Join(provideNativeLibs, " "), "requireNativeLibs": strings.Join(requireNativeLibs, " "), + "default_version": defaultManifestVersion, "opt": strings.Join(optCommands, " "), }, }) @@ -684,7 +672,6 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { "file_contexts": fileContexts.String(), "canned_fs_config": cannedFsConfig.String(), "key": a.privateKeyFile.String(), - "apex_version": defaultManifestVersion, "opt_flags": strings.Join(optFlags, " "), }, }) @@ -781,7 +768,6 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { "image_dir": imageDir.String(), "copy_commands": strings.Join(copyCommands, " && "), "manifest": a.manifestPbOut.String(), - "apex_version": defaultManifestVersion, }, }) } diff --git a/bazel/aquery.go b/bazel/aquery.go index 1d1f49cdf..ae2b107e1 100644 --- a/bazel/aquery.go +++ b/bazel/aquery.go @@ -21,7 +21,6 @@ import ( "fmt" "path/filepath" "reflect" - "regexp" "sort" "strings" @@ -83,6 +82,7 @@ type action struct { OutputIds []artifactId TemplateContent string Substitutions []KeyValuePair + FileContents string } // actionGraphContainer contains relevant portions of Bazel's aquery proto, ActionGraphContainer. @@ -110,6 +110,7 @@ type BuildStatement struct { // input path string, but not both. InputDepsetHashes []string InputPaths []string + FileContents string } // A helper type for aquery processing which facilitates retrieval of path IDs from their @@ -139,9 +140,6 @@ var templateActionOverriddenTokens = map[string]string{ "%python_binary%": "python3", } -// This pattern matches the MANIFEST file created for a py_binary target. -var manifestFilePattern = regexp.MustCompile(".*/.+\\.runfiles/MANIFEST$") - // The file name of py3wrapper.sh, which is used by py_binary targets. const py3wrapperFileName = "/py3wrapper.sh" @@ -225,20 +223,12 @@ func (a *aqueryArtifactHandler) populateDepsetMaps(depset depSetOfFiles, middlem // Swap middleman artifacts with their corresponding depsets and drop the middleman artifacts. transitiveDepsetIds = append(transitiveDepsetIds, depsetsToUse...) } else if strings.HasSuffix(path, py3wrapperFileName) || - manifestFilePattern.MatchString(path) || strings.HasPrefix(path, "../bazel_tools") { // Drop these artifacts. // See go/python-binary-host-mixed-build for more details. - // 1) For py3wrapper.sh, there is no action for creating py3wrapper.sh in the aquery output of - // Bazel py_binary targets, so there is no Ninja build statements generated for creating it. - // 2) For MANIFEST file, SourceSymlinkManifest action is in aquery output of Bazel py_binary targets, - // but it doesn't contain sufficient information so no Ninja build statements are generated - // for creating it. - // So in mixed build mode, when these two are used as input of some Ninja build statement, - // since there is no build statement to create them, they should be removed from input paths. - // TODO(b/197135294): Clean up this custom runfiles handling logic when - // SourceSymlinkManifest and SymlinkTree actions are supported. - // 3) ../bazel_tools: they have MODIFY timestamp 10years in the future and would cause the + // 1) Drop py3wrapper.sh, just use python binary, the launcher script generated by the + // TemplateExpandAction handles everything necessary to launch a Pythin application. + // 2) ../bazel_tools: they have MODIFY timestamp 10years in the future and would cause the // containing depset to always be considered newer than their outputs. } else { directArtifactPaths = append(directArtifactPaths, path) @@ -346,12 +336,14 @@ func AqueryBuildStatements(aqueryJsonProto []byte) ([]BuildStatement, []AqueryDe } var buildStatement BuildStatement - if isSymlinkAction(actionEntry) { + if actionEntry.isSymlinkAction() { buildStatement, err = aqueryHandler.symlinkActionBuildStatement(actionEntry) - } else if isTemplateExpandAction(actionEntry) && len(actionEntry.Arguments) < 1 { + } else if actionEntry.isTemplateExpandAction() && len(actionEntry.Arguments) < 1 { buildStatement, err = aqueryHandler.templateExpandActionBuildStatement(actionEntry) - } else if isPythonZipperAction(actionEntry) { - buildStatement, err = aqueryHandler.pythonZipperActionBuildStatement(actionEntry, buildStatements) + } else if actionEntry.isFileWriteAction() { + buildStatement, err = aqueryHandler.fileWriteActionBuildStatement(actionEntry) + } else if actionEntry.isSymlinkTreeAction() { + buildStatement, err = aqueryHandler.symlinkTreeActionBuildStatement(actionEntry) } else if len(actionEntry.Arguments) < 1 { return nil, nil, fmt.Errorf("received action with no command: [%s]", actionEntry.Mnemonic) } else { @@ -452,54 +444,6 @@ func (a *aqueryArtifactHandler) normalActionBuildStatement(actionEntry action) ( return buildStatement, nil } -func (a *aqueryArtifactHandler) pythonZipperActionBuildStatement(actionEntry action, prevBuildStatements []BuildStatement) (BuildStatement, error) { - inputPaths, err := a.getInputPaths(actionEntry.InputDepSetIds) - if err != nil { - return BuildStatement{}, err - } - outputPaths, depfile, err := a.getOutputPaths(actionEntry) - if err != nil { - return BuildStatement{}, err - } - - if len(inputPaths) < 1 || len(outputPaths) != 1 { - return BuildStatement{}, fmt.Errorf("Expect 1+ input and 1 output to python zipper action, got: input %q, output %q", inputPaths, outputPaths) - } - command := strings.Join(proptools.ShellEscapeListIncludingSpaces(actionEntry.Arguments), " ") - inputPaths, command = removePy3wrapperScript(inputPaths, command) - command = addCommandForPyBinaryRunfilesDir(command, outputPaths[0]) - // Add the python zip file as input of the corresponding python binary stub script in Ninja build statements. - // In Ninja build statements, the outputs of dependents of a python binary have python binary stub script as input, - // which is not sufficient without the python zip file from which runfiles directory is created for py_binary. - // - // The following logic relies on that Bazel aquery output returns actions in the order that - // PythonZipper is after TemplateAction of creating Python binary stub script. If later Bazel doesn't return actions - // in that order, the following logic might not find the build statement generated for Python binary - // stub script and the build might fail. So the check of pyBinaryFound is added to help debug in case later Bazel might change aquery output. - // See go/python-binary-host-mixed-build for more details. - pythonZipFilePath := outputPaths[0] - pyBinaryFound := false - for i := range prevBuildStatements { - if len(prevBuildStatements[i].OutputPaths) == 1 && prevBuildStatements[i].OutputPaths[0]+".zip" == pythonZipFilePath { - prevBuildStatements[i].InputPaths = append(prevBuildStatements[i].InputPaths, pythonZipFilePath) - pyBinaryFound = true - } - } - if !pyBinaryFound { - return BuildStatement{}, fmt.Errorf("Could not find the correspondinging Python binary stub script of PythonZipper: %q", outputPaths) - } - - buildStatement := BuildStatement{ - Command: command, - Depfile: depfile, - OutputPaths: outputPaths, - InputPaths: inputPaths, - Env: actionEntry.EnvironmentVariables, - Mnemonic: actionEntry.Mnemonic, - } - return buildStatement, nil -} - func (a *aqueryArtifactHandler) templateExpandActionBuildStatement(actionEntry action) (BuildStatement, error) { outputPaths, depfile, err := a.getOutputPaths(actionEntry) if err != nil { @@ -532,6 +476,47 @@ func (a *aqueryArtifactHandler) templateExpandActionBuildStatement(actionEntry a return buildStatement, nil } +func (a *aqueryArtifactHandler) fileWriteActionBuildStatement(actionEntry action) (BuildStatement, error) { + outputPaths, _, err := a.getOutputPaths(actionEntry) + var depsetHashes []string + if err == nil { + depsetHashes, err = a.depsetContentHashes(actionEntry.InputDepSetIds) + } + if err != nil { + return BuildStatement{}, err + } + return BuildStatement{ + Depfile: nil, + OutputPaths: outputPaths, + Env: actionEntry.EnvironmentVariables, + Mnemonic: actionEntry.Mnemonic, + InputDepsetHashes: depsetHashes, + FileContents: actionEntry.FileContents, + }, nil +} + +func (a *aqueryArtifactHandler) symlinkTreeActionBuildStatement(actionEntry action) (BuildStatement, error) { + outputPaths, _, err := a.getOutputPaths(actionEntry) + if err != nil { + return BuildStatement{}, err + } + inputPaths, err := a.getInputPaths(actionEntry.InputDepSetIds) + if err != nil { + return BuildStatement{}, err + } + if len(inputPaths) != 1 || len(outputPaths) != 1 { + return BuildStatement{}, fmt.Errorf("Expect 1 input and 1 output to symlink action, got: input %q, output %q", inputPaths, outputPaths) + } + // The actual command is generated in bazelSingleton.GenerateBuildActions + return BuildStatement{ + Depfile: nil, + OutputPaths: outputPaths, + Env: actionEntry.EnvironmentVariables, + Mnemonic: actionEntry.Mnemonic, + InputPaths: inputPaths, + }, nil +} + func (a *aqueryArtifactHandler) symlinkActionBuildStatement(actionEntry action) (BuildStatement, error) { outputPaths, depfile, err := a.getOutputPaths(actionEntry) if err != nil { @@ -614,76 +599,35 @@ func escapeCommandlineArgument(str string) string { return replacer.Replace(str) } -// removePy3wrapperScript removes py3wrapper.sh from the input paths and command of the action of -// creating python zip file in mixed build mode. py3wrapper.sh is returned as input by aquery but -// there is no action returned by aquery for creating it. So in mixed build "python3" is used -// as the PYTHON_BINARY in python binary stub script, and py3wrapper.sh is not needed and should be -// removed from input paths and command of creating python zip file. -// See go/python-binary-host-mixed-build for more details. -// TODO(b/205879240) remove this after py3wrapper.sh could be created in the mixed build mode. -func removePy3wrapperScript(inputPaths []string, command string) (newInputPaths []string, newCommand string) { - // Remove from inputs - var filteredInputPaths []string - for _, path := range inputPaths { - if !strings.HasSuffix(path, py3wrapperFileName) { - filteredInputPaths = append(filteredInputPaths, path) - } - } - newInputPaths = filteredInputPaths - - // Remove from command line - var re = regexp.MustCompile(`\S*` + py3wrapperFileName) - newCommand = re.ReplaceAllString(command, "") - return -} - -// addCommandForPyBinaryRunfilesDir adds commands creating python binary runfiles directory. -// runfiles directory is created by using MANIFEST file and MANIFEST file is the output of -// SourceSymlinkManifest action is in aquery output of Bazel py_binary targets, -// but since SourceSymlinkManifest doesn't contain sufficient information -// so MANIFEST file could not be created, which also blocks the creation of runfiles directory. -// See go/python-binary-host-mixed-build for more details. -// TODO(b/197135294) create runfiles directory from MANIFEST file once it can be created from SourceSymlinkManifest action. -func addCommandForPyBinaryRunfilesDir(oldCommand string, zipFilePath string) string { - // Unzip the zip file, zipFilePath looks like <python_binary>.zip - runfilesDirName := zipFilePath[0:len(zipFilePath)-4] + ".runfiles" - command := fmt.Sprintf("%s x %s -d %s", "../bazel_tools/tools/zip/zipper/zipper", zipFilePath, runfilesDirName) - // Create a symbolic link in <python_binary>.runfiles/, which is the expected structure - // when running the python binary stub script. - command += fmt.Sprintf(" && ln -sf runfiles/__main__ %s", runfilesDirName) - return oldCommand + " && " + command -} - -func isSymlinkAction(a action) bool { +func (a action) isSymlinkAction() bool { return a.Mnemonic == "Symlink" || a.Mnemonic == "SolibSymlink" || a.Mnemonic == "ExecutableSymlink" } -func isTemplateExpandAction(a action) bool { +func (a action) isTemplateExpandAction() bool { return a.Mnemonic == "TemplateExpand" } -func isPythonZipperAction(a action) bool { - return a.Mnemonic == "PythonZipper" +func (a action) isFileWriteAction() bool { + return a.Mnemonic == "FileWrite" || a.Mnemonic == "SourceSymlinkManifest" +} + +func (a action) isSymlinkTreeAction() bool { + return a.Mnemonic == "SymlinkTree" } func shouldSkipAction(a action) bool { - // TODO(b/180945121): Handle complex symlink actions. - if a.Mnemonic == "SymlinkTree" || a.Mnemonic == "SourceSymlinkManifest" { - return true - } // Middleman actions are not handled like other actions; they are handled separately as a // preparatory step so that their inputs may be relayed to actions depending on middleman // artifacts. if a.Mnemonic == "Middleman" { return true } - // Skip "Fail" actions, which are placeholder actions designed to always fail. - if a.Mnemonic == "Fail" { + // PythonZipper is bogus action returned by aquery, ignore it (b/236198693) + if a.Mnemonic == "PythonZipper" { return true } - // TODO(b/180946980): Handle FileWrite. The aquery proto currently contains no information - // about the contents that are written. - if a.Mnemonic == "FileWrite" { + // Skip "Fail" actions, which are placeholder actions designed to always fail. + if a.Mnemonic == "Fail" { return true } if a.Mnemonic == "BaselineCoverage" { diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go index c759d56ee..3a2bf0f38 100644 --- a/bazel/aquery_test.go +++ b/bazel/aquery_test.go @@ -460,6 +460,43 @@ func TestTransitiveInputDepsets(t *testing.T) { } } +func TestSymlinkTree(t *testing.T) { + const inputString = ` +{ + "artifacts": [ + { "id": 1, "pathFragmentId": 1 }, + { "id": 2, "pathFragmentId": 2 }], + "actions": [{ + "targetId": 1, + "actionKey": "x", + "mnemonic": "SymlinkTree", + "configurationId": 1, + "inputDepSetIds": [1], + "outputIds": [2], + "primaryOutputId": 2, + "executionPlatform": "//build/bazel/platforms:linux_x86_64" + }], + "pathFragments": [ + { "id": 1, "label": "foo.manifest" }, + { "id": 2, "label": "foo.runfiles/MANIFEST" }], + "depSetOfFiles": [ + { "id": 1, "directArtifactIds": [1] }] +} +` + actual, _, err := AqueryBuildStatements([]byte(inputString)) + if err != nil { + t.Errorf("Unexpected error %q", err) + } + assertBuildStatements(t, []BuildStatement{ + { + Command: "", + OutputPaths: []string{"foo.runfiles/MANIFEST"}, + Mnemonic: "SymlinkTree", + InputPaths: []string{"foo.manifest"}, + }, + }, actual) +} + func TestBazelOutRemovalFromInputDepsets(t *testing.T) { const inputString = `{ "artifacts": [{ @@ -861,151 +898,67 @@ func TestTemplateExpandActionNoOutput(t *testing.T) { assertError(t, err, `Expect 1 output to template expand action, got: output []`) } -func TestPythonZipperActionSuccess(t *testing.T) { +func TestFileWrite(t *testing.T) { const inputString = ` { "artifacts": [ - { "id": 1, "pathFragmentId": 1 }, - { "id": 2, "pathFragmentId": 2 }, - { "id": 3, "pathFragmentId": 3 }, - { "id": 4, "pathFragmentId": 4 }, - { "id": 5, "pathFragmentId": 10 }, - { "id": 10, "pathFragmentId": 20 }], + { "id": 1, "pathFragmentId": 1 }], "actions": [{ "targetId": 1, "actionKey": "x", - "mnemonic": "TemplateExpand", + "mnemonic": "FileWrite", "configurationId": 1, "outputIds": [1], "primaryOutputId": 1, "executionPlatform": "//build/bazel/platforms:linux_x86_64", - "templateContent": "Test template substitutions: %token1%, %python_binary%", - "substitutions": [{ - "key": "%token1%", - "value": "abcd" - },{ - "key": "%python_binary%", - "value": "python3" - }] - },{ - "targetId": 1, - "actionKey": "x", - "mnemonic": "PythonZipper", - "configurationId": 1, - "arguments": ["../bazel_tools/tools/zip/zipper/zipper", "cC", "python_binary.zip", "__main__.py\u003dbazel-out/k8-fastbuild/bin/python_binary.temp", "__init__.py\u003d", "runfiles/__main__/__init__.py\u003d", "runfiles/__main__/python_binary.py\u003dpython_binary.py", "runfiles/bazel_tools/tools/python/py3wrapper.sh\u003dbazel-out/bazel_tools/k8-fastbuild/bin/tools/python/py3wrapper.sh"], - "outputIds": [2], - "inputDepSetIds": [1], - "primaryOutputId": 2 + "fileContents": "file data\n" }], - "depSetOfFiles": [ - { "id": 1, "directArtifactIds": [4, 3, 5] }], "pathFragments": [ - { "id": 1, "label": "python_binary" }, - { "id": 2, "label": "python_binary.zip" }, - { "id": 3, "label": "python_binary.py" }, - { "id": 9, "label": ".." }, - { "id": 8, "label": "bazel_tools", "parentId": 9 }, - { "id": 7, "label": "tools", "parentId": 8 }, - { "id": 6, "label": "zip", "parentId": 7 }, - { "id": 5, "label": "zipper", "parentId": 6 }, - { "id": 4, "label": "zipper", "parentId": 5 }, - { "id": 16, "label": "bazel-out" }, - { "id": 15, "label": "bazel_tools", "parentId": 16 }, - { "id": 14, "label": "k8-fastbuild", "parentId": 15 }, - { "id": 13, "label": "bin", "parentId": 14 }, - { "id": 12, "label": "tools", "parentId": 13 }, - { "id": 11, "label": "python", "parentId": 12 }, - { "id": 10, "label": "py3wrapper.sh", "parentId": 11 }, - { "id": 20, "label": "python_binary" }] -}` + { "id": 1, "label": "foo.manifest" }] +} +` actual, _, err := AqueryBuildStatements([]byte(inputString)) - if err != nil { t.Errorf("Unexpected error %q", err) } - - expectedBuildStatements := []BuildStatement{ - { - Command: "/bin/bash -c 'echo \"Test template substitutions: abcd, python3\" | sed \"s/\\\\\\\\n/\\\\n/g\" > python_binary && " + - "chmod a+x python_binary'", - InputPaths: []string{"python_binary.zip"}, - OutputPaths: []string{"python_binary"}, - Mnemonic: "TemplateExpand", - }, + assertBuildStatements(t, []BuildStatement{ { - Command: "../bazel_tools/tools/zip/zipper/zipper cC python_binary.zip __main__.py=bazel-out/k8-fastbuild/bin/python_binary.temp " + - "__init__.py= runfiles/__main__/__init__.py= runfiles/__main__/python_binary.py=python_binary.py && " + - "../bazel_tools/tools/zip/zipper/zipper x python_binary.zip -d python_binary.runfiles && ln -sf runfiles/__main__ python_binary.runfiles", - InputPaths: []string{"python_binary.py"}, - OutputPaths: []string{"python_binary.zip"}, - Mnemonic: "PythonZipper", + OutputPaths: []string{"foo.manifest"}, + Mnemonic: "FileWrite", + FileContents: "file data\n", }, - } - assertBuildStatements(t, expectedBuildStatements, actual) + }, actual) } -func TestPythonZipperActionNoInput(t *testing.T) { +func TestSourceSymlinkManifest(t *testing.T) { const inputString = ` { "artifacts": [ - { "id": 1, "pathFragmentId": 1 }, - { "id": 2, "pathFragmentId": 2 }], + { "id": 1, "pathFragmentId": 1 }], "actions": [{ "targetId": 1, "actionKey": "x", - "mnemonic": "PythonZipper", + "mnemonic": "SourceSymlinkManifest", "configurationId": 1, - "arguments": ["../bazel_tools/tools/zip/zipper/zipper", "cC", "python_binary.zip", "__main__.py\u003dbazel-out/k8-fastbuild/bin/python_binary.temp", "__init__.py\u003d", "runfiles/__main__/__init__.py\u003d", "runfiles/__main__/python_binary.py\u003dpython_binary.py", "runfiles/bazel_tools/tools/python/py3wrapper.sh\u003dbazel-out/bazel_tools/k8-fastbuild/bin/tools/python/py3wrapper.sh"], - "outputIds": [2], - "primaryOutputId": 2 + "outputIds": [1], + "primaryOutputId": 1, + "executionPlatform": "//build/bazel/platforms:linux_x86_64", + "fileContents": "symlink target\n" }], "pathFragments": [ - { "id": 1, "label": "python_binary" }, - { "id": 2, "label": "python_binary.zip" }] -}` - _, _, err := AqueryBuildStatements([]byte(inputString)) - assertError(t, err, `Expect 1+ input and 1 output to python zipper action, got: input [], output ["python_binary.zip"]`) + { "id": 1, "label": "foo.manifest" }] } - -func TestPythonZipperActionNoOutput(t *testing.T) { - const inputString = ` -{ - "artifacts": [ - { "id": 1, "pathFragmentId": 1 }, - { "id": 2, "pathFragmentId": 2 }, - { "id": 3, "pathFragmentId": 3 }, - { "id": 4, "pathFragmentId": 4 }, - { "id": 5, "pathFragmentId": 10 }], - "actions": [{ - "targetId": 1, - "actionKey": "x", - "mnemonic": "PythonZipper", - "configurationId": 1, - "arguments": ["../bazel_tools/tools/zip/zipper/zipper", "cC", "python_binary.zip", "__main__.py\u003dbazel-out/k8-fastbuild/bin/python_binary.temp", "__init__.py\u003d", "runfiles/__main__/__init__.py\u003d", "runfiles/__main__/python_binary.py\u003dpython_binary.py", "runfiles/bazel_tools/tools/python/py3wrapper.sh\u003dbazel-out/bazel_tools/k8-fastbuild/bin/tools/python/py3wrapper.sh"], - "inputDepSetIds": [1] - }], - "depSetOfFiles": [ - { "id": 1, "directArtifactIds": [4, 3, 5]}], - "pathFragments": [ - { "id": 1, "label": "python_binary" }, - { "id": 2, "label": "python_binary.zip" }, - { "id": 3, "label": "python_binary.py" }, - { "id": 9, "label": ".." }, - { "id": 8, "label": "bazel_tools", "parentId": 9 }, - { "id": 7, "label": "tools", "parentId": 8 }, - { "id": 6, "label": "zip", "parentId": 7 }, - { "id": 5, "label": "zipper", "parentId": 6 }, - { "id": 4, "label": "zipper", "parentId": 5 }, - { "id": 16, "label": "bazel-out" }, - { "id": 15, "label": "bazel_tools", "parentId": 16 }, - { "id": 14, "label": "k8-fastbuild", "parentId": 15 }, - { "id": 13, "label": "bin", "parentId": 14 }, - { "id": 12, "label": "tools", "parentId": 13 }, - { "id": 11, "label": "python", "parentId": 12 }, - { "id": 10, "label": "py3wrapper.sh", "parentId": 11 }] -}` - _, _, err := AqueryBuildStatements([]byte(inputString)) - assertError(t, err, `Expect 1+ input and 1 output to python zipper action, got: input ["python_binary.py"], output []`) +` + actual, _, err := AqueryBuildStatements([]byte(inputString)) + if err != nil { + t.Errorf("Unexpected error %q", err) + } + assertBuildStatements(t, []BuildStatement{ + { + OutputPaths: []string{"foo.manifest"}, + Mnemonic: "SourceSymlinkManifest", + }, + }, actual) } func assertError(t *testing.T, err error, expected string) { diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go index de139c439..d8011d69f 100644 --- a/dexpreopt/dexpreopt.go +++ b/dexpreopt/dexpreopt.go @@ -394,10 +394,14 @@ func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, g if !android.PrefixInList(preoptFlags, "--compiler-filter=") { var compilerFilter string if systemServerJars.ContainsJar(module.Name) { - // Jars of system server, use the product option if it is set, speed otherwise. if global.SystemServerCompilerFilter != "" { + // Use the product option if it is set. compilerFilter = global.SystemServerCompilerFilter + } else if profile != nil { + // Use "speed-profile" for system server jars that have a profile. + compilerFilter = "speed-profile" } else { + // Use "speed" for system server jars that do not have a profile. compilerFilter = "speed" } } else if contains(global.SpeedApps, module.Name) || contains(global.SystemServerApps, module.Name) { diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go index 66d5abab6..1a87b30d4 100644 --- a/fuzz/fuzz_common.go +++ b/fuzz/fuzz_common.go @@ -18,6 +18,7 @@ package fuzz import ( "encoding/json" + "fmt" "sort" "strings" @@ -61,9 +62,65 @@ type ArchOs struct { Dir string } +type PrivilegedLevel string + +const ( + // Environment with the most minimal permissions. + Constrained PrivilegedLevel = "Constrained" + // Typical execution environment running unprivileged code. + Unprivileged = "Unprivileged" + // May have access to elevated permissions. + Privileged = "Privileged" + // Trusted computing base. + Tcb = "TCB" + // Bootloader chain. + Bootloader = "Bootloader" + // Tusted execution environment. + Tee = "Tee" + // Secure enclave. + Se = "Se" + // Other. + Other = "Other" +) + +func IsValidConfig(fuzzModule FuzzPackagedModule, moduleName string) bool { + var config = fuzzModule.FuzzProperties.Fuzz_config + if config != nil { + var level = PrivilegedLevel(config.Privilege_level) + if level != "" { + switch level { + case Constrained, Unprivileged, Privileged, Tcb, Bootloader, Tee, Se, Other: + return true + } + panic(fmt.Errorf("Invalid privileged level in fuzz config in %s", moduleName)) + } + return true + } else { + return false + } +} + type FuzzConfig struct { // Email address of people to CC on bugs or contact about this fuzz target. Cc []string `json:"cc,omitempty"` + // A brief description of what the fuzzed code does. + Description string `json:"description,omitempty"` + // Can this code be triggered remotely or only locally. + Remotely_accessible bool `json:"remotely_accessible,omitempty"` + // Is the fuzzed code host only, i.e. test frameworks or support utilities. + Host_only bool `json:"host_only,omitempty"` + // Can third party/untrusted apps supply data to fuzzed code. + Untrusted_data bool `json:"untrusted_data,omitempty"` + // Is the code being fuzzed in a privileged, constrained or any other + // context from: + // https://source.android.com/security/overview/updates-resources#context_types. + Privilege_level PrivilegedLevel `json:"privilege_level,omitempty"` + // Can the fuzzed code isolated or can be called by multiple users/processes. + Isolated bool `json:"users_isolation,omitempty"` + // When code was relaeased or will be released. + Production_date string `json:"production_date,omitempty"` + // Prevents critical service functionality like phone calls, bluetooth, etc. + Critical bool `json:"critical,omitempty"` // Specify whether to enable continuous fuzzing on devices. Defaults to true. Fuzz_on_haiku_device *bool `json:"fuzz_on_haiku_device,omitempty"` // Specify whether to enable continuous fuzzing on host. Defaults to true. @@ -159,7 +216,7 @@ func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module and } // Additional fuzz config. - if fuzzModule.Config != nil { + if fuzzModule.Config != nil && IsValidConfig(fuzzModule, module.Name()) { files = append(files, FileToZip{fuzzModule.Config, ""}) } diff --git a/java/aar.go b/java/aar.go index 00ff7e774..cf84309f4 100644 --- a/java/aar.go +++ b/java/aar.go @@ -678,6 +678,10 @@ func (a *AARImport) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpe return a.SdkVersion(ctx) } +func (a *AARImport) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { + return android.SdkSpecFrom(ctx, "") +} + func (a *AARImport) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return a.SdkVersion(ctx) } diff --git a/java/android_manifest.go b/java/android_manifest.go index a297b2c10..c61823d06 100644 --- a/java/android_manifest.go +++ b/java/android_manifest.go @@ -136,6 +136,11 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path, ctx.ModuleErrorf("invalid minSdkVersion: %s", err) } + replaceMaxSdkVersionPlaceholder, err := params.SdkContext.ReplaceMaxSdkVersionPlaceholder(ctx).EffectiveVersion(ctx) + if err != nil { + ctx.ModuleErrorf("invalid ReplaceMaxSdkVersionPlaceholder: %s", err) + } + if UseApiFingerprint(ctx) && ctx.ModuleName() != "framework-res" { minSdkVersion = ctx.Config().PlatformSdkCodename() + fmt.Sprintf(".$$(cat %s)", ApiFingerprintPath(ctx).String()) deps = append(deps, ApiFingerprintPath(ctx)) @@ -145,6 +150,7 @@ func ManifestFixer(ctx android.ModuleContext, manifest android.Path, ctx.ModuleErrorf("invalid minSdkVersion: %s", err) } args = append(args, "--minSdkVersion ", minSdkVersion) + args = append(args, "--replaceMaxSdkVersionPlaceholder ", strconv.Itoa(replaceMaxSdkVersionPlaceholder.FinalOrFutureInt())) args = append(args, "--raise-min-sdk-version") } diff --git a/java/base.go b/java/base.go index c399c4063..94daf37fc 100644 --- a/java/base.go +++ b/java/base.go @@ -204,6 +204,10 @@ type DeviceProperties struct { // Defaults to empty string "". See sdk_version for possible values. Max_sdk_version *string + // if not blank, set the maxSdkVersion properties of permission and uses-permission tags. + // Defaults to empty string "". See sdk_version for possible values. + Replace_max_sdk_version_placeholder *string + // if not blank, set the targetSdkVersion in the AndroidManifest.xml. // Defaults to sdk_version if not set. See sdk_version for possible values. Target_sdk_version *string @@ -649,6 +653,11 @@ func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return android.SdkSpecFrom(ctx, maxSdkVersion) } +func (j *Module) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { + replaceMaxSdkVersionPlaceholder := proptools.StringDefault(j.deviceProperties.Replace_max_sdk_version_placeholder, "") + return android.SdkSpecFrom(ctx, replaceMaxSdkVersionPlaceholder) +} + func (j *Module) MinSdkVersionString() string { return j.minSdkVersion.Raw } diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index 0591012fd..f08b64b23 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -32,12 +32,7 @@ import ( func init() { registerBootclasspathFragmentBuildComponents(android.InitRegistrationContext) - android.RegisterSdkMemberType(&bootclasspathFragmentMemberType{ - SdkMemberTypeBase: android.SdkMemberTypeBase{ - PropertyName: "bootclasspath_fragments", - SupportsSdk: true, - }, - }) + android.RegisterSdkMemberType(BootclasspathFragmentSdkMemberType) } func registerBootclasspathFragmentBuildComponents(ctx android.RegistrationContext) { @@ -46,6 +41,15 @@ func registerBootclasspathFragmentBuildComponents(ctx android.RegistrationContex ctx.RegisterModuleType("prebuilt_bootclasspath_fragment", prebuiltBootclasspathFragmentFactory) } +// BootclasspathFragmentSdkMemberType is the member type used to add bootclasspath_fragments to +// the SDK snapshot. It is exported for use by apex. +var BootclasspathFragmentSdkMemberType = &bootclasspathFragmentMemberType{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ + PropertyName: "bootclasspath_fragments", + SupportsSdk: true, + }, +} + type bootclasspathFragmentContentDependencyTag struct { blueprint.BaseDependencyTag } diff --git a/java/dexpreopt.go_v1 b/java/dexpreopt.go_v1 deleted file mode 100644 index 0adaf9917..000000000 --- a/java/dexpreopt.go_v1 +++ /dev/null @@ -1,404 +0,0 @@ -// Copyright 2018 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package java - -import ( - "path/filepath" - "strings" - - "android/soong/android" - "android/soong/dexpreopt" -) - -type DexpreopterInterface interface { - IsInstallable() bool // Structs that embed dexpreopter must implement this. - dexpreoptDisabled(ctx android.BaseModuleContext) bool - DexpreoptBuiltInstalledForApex() []dexpreopterInstall - AndroidMkEntriesForApex() []android.AndroidMkEntries -} - -type dexpreopterInstall struct { - // A unique name to distinguish an output from others for the same java library module. Usually in - // the form of `<arch>-<encoded-path>.odex/vdex/art`. - name string - - // The name of the input java module. - moduleName string - - // The path to the dexpreopt output on host. - outputPathOnHost android.Path - - // The directory on the device for the output to install to. - installDirOnDevice android.InstallPath - - // The basename (the last segment of the path) for the output to install as. - installFileOnDevice string -} - -// The full module name of the output in the makefile. -func (install *dexpreopterInstall) FullModuleName() string { - return install.moduleName + install.SubModuleName() -} - -// The sub-module name of the output in the makefile (the name excluding the java module name). -func (install *dexpreopterInstall) SubModuleName() string { - return "-dexpreopt-" + install.name -} - -// Returns Make entries for installing the file. -// -// This function uses a value receiver rather than a pointer receiver to ensure that the object is -// safe to use in `android.AndroidMkExtraEntriesFunc`. -func (install dexpreopterInstall) ToMakeEntries() android.AndroidMkEntries { - return android.AndroidMkEntries{ - Class: "ETC", - SubName: install.SubModuleName(), - OutputFile: android.OptionalPathForPath(install.outputPathOnHost), - ExtraEntries: []android.AndroidMkExtraEntriesFunc{ - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_PATH", install.installDirOnDevice.String()) - entries.SetString("LOCAL_INSTALLED_MODULE_STEM", install.installFileOnDevice) - entries.SetString("LOCAL_NOT_AVAILABLE_FOR_PLATFORM", "false") - }, - }, - } -} - -type dexpreopter struct { - dexpreoptProperties DexpreoptProperties - - installPath android.InstallPath - uncompressedDex bool - isSDKLibrary bool - isApp bool - isTest bool - isPresignedPrebuilt bool - preventInstall bool - - manifestFile android.Path - statusFile android.WritablePath - enforceUsesLibs bool - classLoaderContexts dexpreopt.ClassLoaderContextMap - - // See the `dexpreopt` function for details. - builtInstalled string - builtInstalledForApex []dexpreopterInstall - - // The config is used for two purposes: - // - Passing dexpreopt information about libraries from Soong to Make. This is needed when - // a <uses-library> is defined in Android.bp, but used in Android.mk (see dex_preopt_config_merger.py). - // Note that dexpreopt.config might be needed even if dexpreopt is disabled for the library itself. - // - Dexpreopt post-processing (using dexpreopt artifacts from a prebuilt system image to incrementally - // dexpreopt another partition). - configPath android.WritablePath -} - -type DexpreoptProperties struct { - Dex_preopt struct { - // If false, prevent dexpreopting. Defaults to true. - Enabled *bool - - // If true, generate an app image (.art file) for this module. - App_image *bool - - // If true, use a checked-in profile to guide optimization. Defaults to false unless - // a matching profile is set or a profile is found in PRODUCT_DEX_PREOPT_PROFILE_DIR - // that matches the name of this module, in which case it is defaulted to true. - Profile_guided *bool - - // If set, provides the path to profile relative to the Android.bp file. If not set, - // defaults to searching for a file that matches the name of this module in the default - // profile location set by PRODUCT_DEX_PREOPT_PROFILE_DIR, or empty if not found. - Profile *string `android:"path"` - } -} - -func init() { - dexpreopt.DexpreoptRunningInSoong = true -} - -func isApexVariant(ctx android.BaseModuleContext) bool { - apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) - return !apexInfo.IsForPlatform() -} - -func forPrebuiltApex(ctx android.BaseModuleContext) bool { - apexInfo := ctx.Provider(android.ApexInfoProvider).(android.ApexInfo) - return apexInfo.ForPrebuiltApex -} - -func moduleName(ctx android.BaseModuleContext) string { - // Remove the "prebuilt_" prefix if the module is from a prebuilt because the prefix is not - // expected by dexpreopter. - return android.RemoveOptionalPrebuiltPrefix(ctx.ModuleName()) -} - -func (d *dexpreopter) dexpreoptDisabled(ctx android.BaseModuleContext) bool { - if !ctx.Device() { - return true - } - - if d.isTest { - return true - } - - if !BoolDefault(d.dexpreoptProperties.Dex_preopt.Enabled, true) { - return true - } - - // If the module is from a prebuilt APEX, it shouldn't be installable, but it can still be - // dexpreopted. - if !ctx.Module().(DexpreopterInterface).IsInstallable() && !forPrebuiltApex(ctx) { - return true - } - - if !android.IsModulePreferred(ctx.Module()) { - return true - } - - global := dexpreopt.GetGlobalConfig(ctx) - - if global.DisablePreopt { - return true - } - - if inList(moduleName(ctx), global.DisablePreoptModules) { - return true - } - - isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx)) - if isApexVariant(ctx) { - // Don't preopt APEX variant module unless the module is an APEX system server jar and we are - // building the entire system image. - if !isApexSystemServerJar || ctx.Config().UnbundledBuild() { - return true - } - } else { - // Don't preopt the platform variant of an APEX system server jar to avoid conflicts. - if isApexSystemServerJar { - return true - } - } - - // TODO: contains no java code - - return false -} - -func dexpreoptToolDepsMutator(ctx android.BottomUpMutatorContext) { - if d, ok := ctx.Module().(DexpreopterInterface); !ok || d.dexpreoptDisabled(ctx) { - return - } - dexpreopt.RegisterToolDeps(ctx) -} - -func (d *dexpreopter) odexOnSystemOther(ctx android.ModuleContext, installPath android.InstallPath) bool { - return dexpreopt.OdexOnSystemOtherByName(moduleName(ctx), android.InstallPathToOnDevicePath(ctx, installPath), dexpreopt.GetGlobalConfig(ctx)) -} - -// Returns the install path of the dex jar of a module. -// -// Do not rely on `ApexInfo.ApexVariationName` because it can be something like "apex1000", rather -// than the `name` in the path `/apex/<name>` as suggested in its comment. -// -// This function is on a best-effort basis. It cannot handle the case where an APEX jar is not a -// system server jar, which is fine because we currently only preopt system server jars for APEXes. -func (d *dexpreopter) getInstallPath( - ctx android.ModuleContext, defaultInstallPath android.InstallPath) android.InstallPath { - global := dexpreopt.GetGlobalConfig(ctx) - if global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx)) { - dexLocation := dexpreopt.GetSystemServerDexLocation(ctx, global, moduleName(ctx)) - return android.PathForModuleInPartitionInstall(ctx, "", strings.TrimPrefix(dexLocation, "/")) - } - if !d.dexpreoptDisabled(ctx) && isApexVariant(ctx) && - filepath.Base(defaultInstallPath.PartitionDir()) != "apex" { - ctx.ModuleErrorf("unable to get the install path of the dex jar for dexpreopt") - } - return defaultInstallPath -} - -func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.WritablePath) { - global := dexpreopt.GetGlobalConfig(ctx) - - // TODO(b/148690468): The check on d.installPath is to bail out in cases where - // the dexpreopter struct hasn't been fully initialized before we're called, - // e.g. in aar.go. This keeps the behaviour that dexpreopting is effectively - // disabled, even if installable is true. - if d.installPath.Base() == "." { - return - } - - dexLocation := android.InstallPathToOnDevicePath(ctx, d.installPath) - - providesUsesLib := moduleName(ctx) - if ulib, ok := ctx.Module().(ProvidesUsesLib); ok { - name := ulib.ProvidesUsesLib() - if name != nil { - providesUsesLib = *name - } - } - - // If it is test, make config files regardless of its dexpreopt setting. - // The config files are required for apps defined in make which depend on the lib. - if d.isTest && d.dexpreoptDisabled(ctx) { - return - } - - isSystemServerJar := global.AllSystemServerJars(ctx).ContainsJar(moduleName(ctx)) - - bootImage := defaultBootImageConfig(ctx) - dexFiles, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp) - - targets := ctx.MultiTargets() - if len(targets) == 0 { - // assume this is a java library, dexpreopt for all arches for now - for _, target := range ctx.Config().Targets[android.Android] { - if target.NativeBridge == android.NativeBridgeDisabled { - targets = append(targets, target) - } - } - if isSystemServerJar && !d.isSDKLibrary { - // If the module is not an SDK library and it's a system server jar, only preopt the primary arch. - targets = targets[:1] - } - } - - var archs []android.ArchType - var images android.Paths - var imagesDeps []android.OutputPaths - for _, target := range targets { - archs = append(archs, target.Arch.ArchType) - variant := bootImage.getVariant(target) - images = append(images, variant.imagePathOnHost) - imagesDeps = append(imagesDeps, variant.imagesDeps) - } - // The image locations for all Android variants are identical. - hostImageLocations, deviceImageLocations := bootImage.getAnyAndroidVariant().imageLocations() - - var profileClassListing android.OptionalPath - var profileBootListing android.OptionalPath - profileIsTextListing := false - if BoolDefault(d.dexpreoptProperties.Dex_preopt.Profile_guided, true) { - // If dex_preopt.profile_guided is not set, default it based on the existence of the - // dexprepot.profile option or the profile class listing. - if String(d.dexpreoptProperties.Dex_preopt.Profile) != "" { - profileClassListing = android.OptionalPathForPath( - android.PathForModuleSrc(ctx, String(d.dexpreoptProperties.Dex_preopt.Profile))) - profileBootListing = android.ExistentPathForSource(ctx, - ctx.ModuleDir(), String(d.dexpreoptProperties.Dex_preopt.Profile)+"-boot") - profileIsTextListing = true - } else if global.ProfileDir != "" { - profileClassListing = android.ExistentPathForSource(ctx, - global.ProfileDir, moduleName(ctx)+".prof") - } - } - - // Full dexpreopt config, used to create dexpreopt build rules. - dexpreoptConfig := &dexpreopt.ModuleConfig{ - Name: moduleName(ctx), - DexLocation: dexLocation, - BuildPath: android.PathForModuleOut(ctx, "dexpreopt", moduleName(ctx)+".jar").OutputPath, - DexPath: dexJarFile, - ManifestPath: android.OptionalPathForPath(d.manifestFile), - UncompressedDex: d.uncompressedDex, - HasApkLibraries: false, - PreoptFlags: nil, - - ProfileClassListing: profileClassListing, - ProfileIsTextListing: profileIsTextListing, - ProfileBootListing: profileBootListing, - - EnforceUsesLibrariesStatusFile: dexpreopt.UsesLibrariesStatusFile(ctx), - EnforceUsesLibraries: d.enforceUsesLibs, - ProvidesUsesLibrary: providesUsesLib, - ClassLoaderContexts: d.classLoaderContexts, - - Archs: archs, - DexPreoptImagesDeps: imagesDeps, - DexPreoptImageLocationsOnHost: hostImageLocations, - DexPreoptImageLocationsOnDevice: deviceImageLocations, - - PreoptBootClassPathDexFiles: dexFiles.Paths(), - PreoptBootClassPathDexLocations: dexLocations, - - PreoptExtractedApk: false, - - NoCreateAppImage: !BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, true), - ForceCreateAppImage: BoolDefault(d.dexpreoptProperties.Dex_preopt.App_image, false), - - PresignedPrebuilt: d.isPresignedPrebuilt, - } - - d.configPath = android.PathForModuleOut(ctx, "dexpreopt", "dexpreopt.config") - dexpreopt.WriteModuleConfig(ctx, dexpreoptConfig, d.configPath) - - if d.dexpreoptDisabled(ctx) { - return - } - - globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) - - dexpreoptRule, err := dexpreopt.GenerateDexpreoptRule(ctx, globalSoong, global, dexpreoptConfig) - if err != nil { - ctx.ModuleErrorf("error generating dexpreopt rule: %s", err.Error()) - return - } - - dexpreoptRule.Build("dexpreopt", "dexpreopt") - - isApexSystemServerJar := global.AllApexSystemServerJars(ctx).ContainsJar(moduleName(ctx)) - - for _, install := range dexpreoptRule.Installs() { - // Remove the "/" prefix because the path should be relative to $ANDROID_PRODUCT_OUT. - installDir := strings.TrimPrefix(filepath.Dir(install.To), "/") - installBase := filepath.Base(install.To) - arch := filepath.Base(installDir) - installPath := android.PathForModuleInPartitionInstall(ctx, "", installDir) - - if isApexSystemServerJar { - // APEX variants of java libraries are hidden from Make, so their dexpreopt - // outputs need special handling. Currently, for APEX variants of java - // libraries, only those in the system server classpath are handled here. - // Preopting of boot classpath jars in the ART APEX are handled in - // java/dexpreopt_bootjars.go, and other APEX jars are not preopted. - // The installs will be handled by Make as sub-modules of the java library. - d.builtInstalledForApex = append(d.builtInstalledForApex, dexpreopterInstall{ - name: arch + "-" + installBase, - moduleName: moduleName(ctx), - outputPathOnHost: install.From, - installDirOnDevice: installPath, - installFileOnDevice: installBase, - }) - } else if !d.preventInstall { - ctx.InstallFile(installPath, installBase, install.From) - } - } - - if !isApexSystemServerJar { - d.builtInstalled = dexpreoptRule.Installs().String() - } -} - -func (d *dexpreopter) DexpreoptBuiltInstalledForApex() []dexpreopterInstall { - return d.builtInstalledForApex -} - -func (d *dexpreopter) AndroidMkEntriesForApex() []android.AndroidMkEntries { - var entries []android.AndroidMkEntries - for _, install := range d.builtInstalledForApex { - entries = append(entries, install.ToMakeEntries()) - } - return entries -} diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 7c4da3ef6..b4cd07a78 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -785,24 +785,26 @@ func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) and } defaultProfile := "frameworks/base/config/boot-image-profile.txt" + extraProfile := "frameworks/base/config/boot-image-profile-extra.txt" rule := android.NewRuleBuilder(pctx, ctx) - var bootImageProfile android.Path - if len(global.BootImageProfiles) > 1 { - combinedBootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt") - rule.Command().Text("cat").Inputs(global.BootImageProfiles).Text(">").Output(combinedBootImageProfile) - bootImageProfile = combinedBootImageProfile - } else if len(global.BootImageProfiles) == 1 { - bootImageProfile = global.BootImageProfiles[0] + var profiles android.Paths + if len(global.BootImageProfiles) > 0 { + profiles = append(profiles, global.BootImageProfiles...) } else if path := android.ExistentPathForSource(ctx, defaultProfile); path.Valid() { - bootImageProfile = path.Path() + profiles = append(profiles, path.Path()) } else { // No profile (not even a default one, which is the case on some branches // like master-art-host that don't have frameworks/base). // Return nil and continue without profile. return nil } + if path := android.ExistentPathForSource(ctx, extraProfile); path.Valid() { + profiles = append(profiles, path.Path()) + } + bootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt") + rule.Command().Text("cat").Inputs(profiles).Text(">").Output(bootImageProfile) profile := image.dir.Join(ctx, "boot.prof") diff --git a/java/dexpreopt_bootjars.go_v1 b/java/dexpreopt_bootjars.go_v1 deleted file mode 100644 index 07a357bb5..000000000 --- a/java/dexpreopt_bootjars.go_v1 +++ /dev/null @@ -1,952 +0,0 @@ -// Copyright 2019 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package java - -import ( - "path/filepath" - "strings" - - "android/soong/android" - "android/soong/dexpreopt" - - "github.com/google/blueprint/proptools" -) - -// ================================================================================================= -// WIP - see http://b/177892522 for details -// -// The build support for boot images is currently being migrated away from singleton to modules so -// the documentation may not be strictly accurate. Rather than update the documentation at every -// step which will create a lot of churn the changes that have been made will be listed here and the -// documentation will be updated once it is closer to the final result. -// -// Changes: -// 1) dex_bootjars is now a singleton module and not a plain singleton. -// 2) Boot images are now represented by the boot_image module type. -// 3) The art boot image is called "art-boot-image", the framework boot image is called -// "framework-boot-image". -// 4) They are defined in art/build/boot/Android.bp and frameworks/base/boot/Android.bp -// respectively. -// 5) Each boot_image retrieves the appropriate boot image configuration from the map returned by -// genBootImageConfigs() using the image_name specified in the boot_image module. -// ================================================================================================= - -// This comment describes: -// 1. ART boot images in general (their types, structure, file layout, etc.) -// 2. build system support for boot images -// -// 1. ART boot images -// ------------------ -// -// A boot image in ART is a set of files that contain AOT-compiled native code and a heap snapshot -// of AOT-initialized classes for the bootclasspath Java libraries. A boot image is compiled from a -// set of DEX jars by the dex2oat compiler. A boot image is used for two purposes: 1) it is -// installed on device and loaded at runtime, and 2) other Java libraries and apps are compiled -// against it (compilation may take place either on host, known as "dexpreopt", or on device, known -// as "dexopt"). -// -// A boot image is not a single file, but a collection of interrelated files. Each boot image has a -// number of components that correspond to the Java libraries that constitute it. For each component -// there are multiple files: -// - *.oat or *.odex file with native code (architecture-specific, one per instruction set) -// - *.art file with pre-initialized Java classes (architecture-specific, one per instruction set) -// - *.vdex file with verification metadata for the DEX bytecode (architecture independent) -// -// *.vdex files for the boot images do not contain the DEX bytecode itself, because the -// bootclasspath DEX files are stored on disk in uncompressed and aligned form. Consequently a boot -// image is not self-contained and cannot be used without its DEX files. To simplify the management -// of boot image files, ART uses a certain naming scheme and associates the following metadata with -// each boot image: -// - A stem, which is a symbolic name that is prepended to boot image file names. -// - A location (on-device path to the boot image files). -// - A list of boot image locations (on-device paths to dependency boot images). -// - A set of DEX locations (on-device paths to the DEX files, one location for one DEX file used -// to compile the boot image). -// -// There are two kinds of boot images: -// - primary boot images -// - boot image extensions -// -// 1.1. Primary boot images -// ------------------------ -// -// A primary boot image is compiled for a core subset of bootclasspath Java libraries. It does not -// depend on any other images, and other boot images may depend on it. -// -// For example, assuming that the stem is "boot", the location is /apex/com.android.art/javalib/, -// the set of core bootclasspath libraries is A B C, and the boot image is compiled for ARM targets -// (32 and 64 bits), it will have three components with the following files: -// - /apex/com.android.art/javalib/{arm,arm64}/boot.{art,oat,vdex} -// - /apex/com.android.art/javalib/{arm,arm64}/boot-B.{art,oat,vdex} -// - /apex/com.android.art/javalib/{arm,arm64}/boot-C.{art,oat,vdex} -// -// The files of the first component are special: they do not have the component name appended after -// the stem. This naming convention dates back to the times when the boot image was not split into -// components, and there were just boot.oat and boot.art. The decision to split was motivated by -// licensing reasons for one of the bootclasspath libraries. -// -// As of November 2020 the only primary boot image in Android is the image in the ART APEX -// com.android.art. The primary ART boot image contains the Core libraries that are part of the ART -// module. When the ART module gets updated, the primary boot image will be updated with it, and all -// dependent images will get invalidated (the checksum of the primary image stored in dependent -// images will not match), unless they are updated in sync with the ART module. -// -// 1.2. Boot image extensions -// -------------------------- -// -// A boot image extension is compiled for a subset of bootclasspath Java libraries (in particular, -// this subset does not include the Core bootclasspath libraries that go into the primary boot -// image). A boot image extension depends on the primary boot image and optionally some other boot -// image extensions. Other images may depend on it. In other words, boot image extensions can form -// acyclic dependency graphs. -// -// The motivation for boot image extensions comes from the Mainline project. Consider a situation -// when the list of bootclasspath libraries is A B C, and both A and B are parts of the Android -// platform, but C is part of an updatable APEX com.android.C. When the APEX is updated, the Java -// code for C might have changed compared to the code that was used to compile the boot image. -// Consequently, the whole boot image is obsolete and invalidated (even though the code for A and B -// that does not depend on C is up to date). To avoid this, the original monolithic boot image is -// split in two parts: the primary boot image that contains A B, and the boot image extension that -// contains C and depends on the primary boot image (extends it). -// -// For example, assuming that the stem is "boot", the location is /system/framework, the set of -// bootclasspath libraries is D E (where D is part of the platform and is located in -// /system/framework, and E is part of a non-updatable APEX com.android.E and is located in -// /apex/com.android.E/javalib), and the boot image is compiled for ARM targets (32 and 64 bits), -// it will have two components with the following files: -// - /system/framework/{arm,arm64}/boot-D.{art,oat,vdex} -// - /system/framework/{arm,arm64}/boot-E.{art,oat,vdex} -// -// As of November 2020 the only boot image extension in Android is the Framework boot image -// extension. It extends the primary ART boot image and contains Framework libraries and other -// bootclasspath libraries from the platform and non-updatable APEXes that are not included in the -// ART image. The Framework boot image extension is updated together with the platform. In the -// future other boot image extensions may be added for some updatable modules. -// -// -// 2. Build system support for boot images -// --------------------------------------- -// -// The primary ART boot image needs to be compiled with one dex2oat invocation that depends on DEX -// jars for the core libraries. Framework boot image extension needs to be compiled with one dex2oat -// invocation that depends on the primary ART boot image and all bootclasspath DEX jars except the -// core libraries as they are already part of the primary ART boot image. -// -// 2.1. Libraries that go in the boot images -// ----------------------------------------- -// -// The contents of each boot image are determined by the PRODUCT variables. The primary ART APEX -// boot image contains libraries listed in the ART_APEX_JARS variable in the AOSP makefiles. The -// Framework boot image extension contains libraries specified in the PRODUCT_BOOT_JARS and -// PRODUCT_BOOT_JARS_EXTRA variables. The AOSP makefiles specify some common Framework libraries, -// but more product-specific libraries can be added in the product makefiles. -// -// Each component of the PRODUCT_BOOT_JARS and PRODUCT_BOOT_JARS_EXTRA variables is a -// colon-separated pair <apex>:<library>, where <apex> is the variant name of a non-updatable APEX, -// "platform" if the library is a part of the platform in the system partition, or "system_ext" if -// it's in the system_ext partition. -// -// In these variables APEXes are identified by their "variant names", i.e. the names they get -// mounted as in /apex on device. In Soong modules that is the name set in the "apex_name" -// properties, which default to the "name" values. For example, many APEXes have both -// com.android.xxx and com.google.android.xxx modules in Soong, but take the same place -// /apex/com.android.xxx at runtime. In these cases the variant name is always com.android.xxx, -// regardless which APEX goes into the product. See also android.ApexInfo.ApexVariationName and -// apex.apexBundleProperties.Apex_name. -// -// A related variable PRODUCT_APEX_BOOT_JARS contains bootclasspath libraries that are in APEXes. -// They are not included in the boot image. The only exception here are ART jars and core-icu4j.jar -// that have been historically part of the boot image and are now in apexes; they are in boot images -// and core-icu4j.jar is generally treated as being part of PRODUCT_BOOT_JARS. -// -// One exception to the above rules are "coverage" builds (a special build flavor which requires -// setting environment variable EMMA_INSTRUMENT_FRAMEWORK=true). In coverage builds the Java code in -// boot image libraries is instrumented, which means that the instrumentation library (jacocoagent) -// needs to be added to the list of bootclasspath DEX jars. -// -// In general, there is a requirement that the source code for a boot image library must be -// available at build time (e.g. it cannot be a stub that has a separate implementation library). -// -// 2.2. Static configs -// ------------------- -// -// Because boot images are used to dexpreopt other Java modules, the paths to boot image files must -// be known by the time dexpreopt build rules for the dependent modules are generated. Boot image -// configs are constructed very early during the build, before build rule generation. The configs -// provide predefined paths to boot image files (these paths depend only on static build -// configuration, such as PRODUCT variables, and use hard-coded directory names). -// -// 2.3. Singleton -// -------------- -// -// Build rules for the boot images are generated with a Soong singleton. Because a singleton has no -// dependencies on other modules, it has to find the modules for the DEX jars using VisitAllModules. -// Soong loops through all modules and compares each module against a list of bootclasspath library -// names. Then it generates build rules that copy DEX jars from their intermediate module-specific -// locations to the hard-coded locations predefined in the boot image configs. -// -// It would be possible to use a module with proper dependencies instead, but that would require -// changes in the way Soong generates variables for Make: a singleton can use one MakeVars() method -// that writes variables to out/soong/make_vars-*.mk, which is included early by the main makefile, -// but module(s) would have to use out/soong/Android-*.mk which has a group of LOCAL_* variables -// for each module, and is included later. -// -// 2.4. Install rules -// ------------------ -// -// The primary boot image and the Framework extension are installed in different ways. The primary -// boot image is part of the ART APEX: it is copied into the APEX intermediate files, packaged -// together with other APEX contents, extracted and mounted on device. The Framework boot image -// extension is installed by the rules defined in makefiles (make/core/dex_preopt_libart.mk). Soong -// writes out a few DEXPREOPT_IMAGE_* variables for Make; these variables contain boot image names, -// paths and so on. -// - -var artApexNames = []string{ - "com.android.art", - "com.android.art.debug", - "com.android.art.testing", - "com.google.android.art", - "com.google.android.art.debug", - "com.google.android.art.testing", -} - -func init() { - RegisterDexpreoptBootJarsComponents(android.InitRegistrationContext) -} - -// Target-independent description of a boot image. -type bootImageConfig struct { - // If this image is an extension, the image that it extends. - extends *bootImageConfig - - // Image name (used in directory names and ninja rule names). - name string - - // Basename of the image: the resulting filenames are <stem>[-<jar>].{art,oat,vdex}. - stem string - - // Output directory for the image files. - dir android.OutputPath - - // Output directory for the image files with debug symbols. - symbolsDir android.OutputPath - - // Subdirectory where the image files are installed. - installDirOnHost string - - // Subdirectory where the image files on device are installed. - installDirOnDevice string - - // Install path of the boot image profile if it needs to be installed in the APEX, or empty if not - // needed. - profileInstallPathInApex string - - // A list of (location, jar) pairs for the Java modules in this image. - modules android.ConfiguredJarList - - // File paths to jars. - dexPaths android.WritablePaths // for this image - dexPathsDeps android.WritablePaths // for the dependency images and in this image - - // Map from module name (without prebuilt_ prefix) to the predefined build path. - dexPathsByModule map[string]android.WritablePath - - // File path to a zip archive with all image files (or nil, if not needed). - zip android.WritablePath - - // Rules which should be used in make to install the outputs. - profileInstalls android.RuleBuilderInstalls - - // Path to the license metadata file for the module that built the profile. - profileLicenseMetadataFile android.OptionalPath - - // Path to the image profile file on host (or empty, if profile is not generated). - profilePathOnHost android.Path - - // Target-dependent fields. - variants []*bootImageVariant - - // Path of the preloaded classes file. - preloadedClassesFile string -} - -// Target-dependent description of a boot image. -type bootImageVariant struct { - *bootImageConfig - - // Target for which the image is generated. - target android.Target - - // The "locations" of jars. - dexLocations []string // for this image - dexLocationsDeps []string // for the dependency images and in this image - - // Paths to image files. - imagePathOnHost android.OutputPath // first image file path on host - imagePathOnDevice string // first image file path on device - - // All the files that constitute this image variant, i.e. .art, .oat and .vdex files. - imagesDeps android.OutputPaths - - // The path to the primary image variant's imagePathOnHost field, where primary image variant - // means the image variant that this extends. - // - // This is only set for a variant of an image that extends another image. - primaryImages android.OutputPath - - // The paths to the primary image variant's imagesDeps field, where primary image variant - // means the image variant that this extends. - // - // This is only set for a variant of an image that extends another image. - primaryImagesDeps android.Paths - - // Rules which should be used in make to install the outputs on host. - installs android.RuleBuilderInstalls - vdexInstalls android.RuleBuilderInstalls - unstrippedInstalls android.RuleBuilderInstalls - - // Rules which should be used in make to install the outputs on device. - deviceInstalls android.RuleBuilderInstalls - - // Path to the license metadata file for the module that built the image. - licenseMetadataFile android.OptionalPath -} - -// Get target-specific boot image variant for the given boot image config and target. -func (image bootImageConfig) getVariant(target android.Target) *bootImageVariant { - for _, variant := range image.variants { - if variant.target.Os == target.Os && variant.target.Arch.ArchType == target.Arch.ArchType { - return variant - } - } - return nil -} - -// Return any (the first) variant which is for the device (as opposed to for the host). -func (image bootImageConfig) getAnyAndroidVariant() *bootImageVariant { - for _, variant := range image.variants { - if variant.target.Os == android.Android { - return variant - } - } - return nil -} - -// Return the name of a boot image module given a boot image config and a component (module) index. -// A module name is a combination of the Java library name, and the boot image stem (that is stored -// in the config). -func (image bootImageConfig) moduleName(ctx android.PathContext, idx int) string { - // The first module of the primary boot image is special: its module name has only the stem, but - // not the library name. All other module names are of the form <stem>-<library name> - m := image.modules.Jar(idx) - name := image.stem - if idx != 0 || image.extends != nil { - name += "-" + android.ModuleStem(m) - } - return name -} - -// Return the name of the first boot image module, or stem if the list of modules is empty. -func (image bootImageConfig) firstModuleNameOrStem(ctx android.PathContext) string { - if image.modules.Len() > 0 { - return image.moduleName(ctx, 0) - } else { - return image.stem - } -} - -// Return filenames for the given boot image component, given the output directory and a list of -// extensions. -func (image bootImageConfig) moduleFiles(ctx android.PathContext, dir android.OutputPath, exts ...string) android.OutputPaths { - ret := make(android.OutputPaths, 0, image.modules.Len()*len(exts)) - for i := 0; i < image.modules.Len(); i++ { - name := image.moduleName(ctx, i) - for _, ext := range exts { - ret = append(ret, dir.Join(ctx, name+ext)) - } - } - return ret -} - -// apexVariants returns a list of all *bootImageVariant that could be included in an apex. -func (image *bootImageConfig) apexVariants() []*bootImageVariant { - variants := []*bootImageVariant{} - for _, variant := range image.variants { - // We also generate boot images for host (for testing), but we don't need those in the apex. - // TODO(b/177892522) - consider changing this to check Os.OsClass = android.Device - if variant.target.Os == android.Android { - variants = append(variants, variant) - } - } - return variants -} - -// Returns true if the boot image should be installed in the APEX. -func (image *bootImageConfig) shouldInstallInApex() bool { - return strings.HasPrefix(image.installDirOnDevice, "apex/") -} - -// Return boot image locations (as a list of symbolic paths). -// -// The image "location" is a symbolic path that, with multiarchitecture support, doesn't really -// exist on the device. Typically it is /apex/com.android.art/javalib/boot.art and should be the -// same for all supported architectures on the device. The concrete architecture specific files -// actually end up in architecture-specific sub-directory such as arm, arm64, x86, or x86_64. -// -// For example a physical file /apex/com.android.art/javalib/x86/boot.art has "image location" -// /apex/com.android.art/javalib/boot.art (which is not an actual file). -// -// For a primary boot image the list of locations has a single element. -// -// For a boot image extension the list of locations contains a location for all dependency images -// (including the primary image) and the location of the extension itself. For example, for the -// Framework boot image extension that depends on the primary ART boot image the list contains two -// elements. -// -// The location is passed as an argument to the ART tools like dex2oat instead of the real path. -// ART tools will then reconstruct the architecture-specific real path. -// -func (image *bootImageVariant) imageLocations() (imageLocationsOnHost []string, imageLocationsOnDevice []string) { - if image.extends != nil { - imageLocationsOnHost, imageLocationsOnDevice = image.extends.getVariant(image.target).imageLocations() - } - return append(imageLocationsOnHost, dexpreopt.PathToLocation(image.imagePathOnHost, image.target.Arch.ArchType)), - append(imageLocationsOnDevice, dexpreopt.PathStringToLocation(image.imagePathOnDevice, image.target.Arch.ArchType)) -} - -func dexpreoptBootJarsFactory() android.SingletonModule { - m := &dexpreoptBootJars{} - android.InitAndroidModule(m) - return m -} - -func RegisterDexpreoptBootJarsComponents(ctx android.RegistrationContext) { - ctx.RegisterSingletonModuleType("dex_bootjars", dexpreoptBootJarsFactory) -} - -func SkipDexpreoptBootJars(ctx android.PathContext) bool { - return dexpreopt.GetGlobalConfig(ctx).DisablePreoptBootImages -} - -// Singleton module for generating boot image build rules. -type dexpreoptBootJars struct { - android.SingletonModuleBase - - // Default boot image config (currently always the Framework boot image extension). It should be - // noted that JIT-Zygote builds use ART APEX image instead of the Framework boot image extension, - // but the switch is handled not here, but in the makefiles (triggered with - // DEXPREOPT_USE_ART_IMAGE=true). - defaultBootImage *bootImageConfig - - // Build path to a config file that Soong writes for Make (to be used in makefiles that install - // the default boot image). - dexpreoptConfigForMake android.WritablePath -} - -// Provide paths to boot images for use by modules that depend upon them. -// -// The build rules are created in GenerateSingletonBuildActions(). -func (d *dexpreoptBootJars) GenerateAndroidBuildActions(ctx android.ModuleContext) { - // Placeholder for now. -} - -// Generate build rules for boot images. -func (d *dexpreoptBootJars) GenerateSingletonBuildActions(ctx android.SingletonContext) { - if SkipDexpreoptBootJars(ctx) { - return - } - if dexpreopt.GetCachedGlobalSoongConfig(ctx) == nil { - // No module has enabled dexpreopting, so we assume there will be no boot image to make. - return - } - - d.dexpreoptConfigForMake = android.PathForOutput(ctx, ctx.Config().DeviceName(), "dexpreopt.config") - writeGlobalConfigForMake(ctx, d.dexpreoptConfigForMake) - - global := dexpreopt.GetGlobalConfig(ctx) - if !shouldBuildBootImages(ctx.Config(), global) { - return - } - - defaultImageConfig := defaultBootImageConfig(ctx) - d.defaultBootImage = defaultImageConfig -} - -// shouldBuildBootImages determines whether boot images should be built. -func shouldBuildBootImages(config android.Config, global *dexpreopt.GlobalConfig) bool { - // Skip recompiling the boot image for the second sanitization phase. We'll get separate paths - // and invalidate first-stage artifacts which are crucial to SANITIZE_LITE builds. - // Note: this is technically incorrect. Compiled code contains stack checks which may depend - // on ASAN settings. - if len(config.SanitizeDevice()) == 1 && config.SanitizeDevice()[0] == "address" && global.SanitizeLite { - return false - } - return true -} - -// copyBootJarsToPredefinedLocations generates commands that will copy boot jars to predefined -// paths in the global config. -func copyBootJarsToPredefinedLocations(ctx android.ModuleContext, srcBootDexJarsByModule bootDexJarByModule, dstBootJarsByModule map[string]android.WritablePath) { - // Create the super set of module names. - names := []string{} - names = append(names, android.SortedStringKeys(srcBootDexJarsByModule)...) - names = append(names, android.SortedStringKeys(dstBootJarsByModule)...) - names = android.SortedUniqueStrings(names) - for _, name := range names { - src := srcBootDexJarsByModule[name] - dst := dstBootJarsByModule[name] - - if src == nil { - // A dex boot jar should be provided by the source java module. It needs to be installable or - // have compile_dex=true - cf. assignments to java.Module.dexJarFile. - // - // However, the source java module may be either replaced or overridden (using prefer:true) by - // a prebuilt java module with the same name. In that case the dex boot jar needs to be - // provided by the corresponding prebuilt APEX module. That APEX is the one that refers - // through a exported_(boot|systemserver)classpath_fragments property to a - // prebuilt_(boot|systemserver)classpath_fragment module, which in turn lists the prebuilt - // java module in the contents property. If that chain is broken then this dependency will - // fail. - if !ctx.Config().AllowMissingDependencies() { - ctx.ModuleErrorf("module %s does not provide a dex boot jar (see comment next to this message in Soong for details)", name) - } else { - ctx.AddMissingDependencies([]string{name}) - } - } else if dst == nil { - ctx.ModuleErrorf("module %s is not part of the boot configuration", name) - } else { - ctx.Build(pctx, android.BuildParams{ - Rule: android.Cp, - Input: src, - Output: dst, - }) - } - } -} - -// buildBootImageVariantsForAndroidOs generates rules to build the boot image variants for the -// android.Android OsType and returns a map from the architectures to the paths of the generated -// boot image files. -// -// The paths are returned because they are needed elsewhere in Soong, e.g. for populating an APEX. -func buildBootImageVariantsForAndroidOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) bootImageFilesByArch { - return buildBootImageForOsType(ctx, image, profile, android.Android) -} - -// buildBootImageVariantsForBuildOs generates rules to build the boot image variants for the -// config.BuildOS OsType, i.e. the type of OS on which the build is being running. -// -// The files need to be generated into their predefined location because they are used from there -// both within Soong and outside, e.g. for ART based host side testing and also for use by some -// cloud based tools. However, they are not needed by callers of this function and so the paths do -// not need to be returned from this func, unlike the buildBootImageVariantsForAndroidOs func. -func buildBootImageVariantsForBuildOs(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath) { - buildBootImageForOsType(ctx, image, profile, ctx.Config().BuildOS) -} - -// buildBootImageForOsType takes a bootImageConfig, a profile file and an android.OsType -// boot image files are required for and it creates rules to build the boot image -// files for all the required architectures for them. -// -// It returns a map from android.ArchType to the predefined paths of the boot image files. -func buildBootImageForOsType(ctx android.ModuleContext, image *bootImageConfig, profile android.WritablePath, requiredOsType android.OsType) bootImageFilesByArch { - filesByArch := bootImageFilesByArch{} - for _, variant := range image.variants { - if variant.target.Os == requiredOsType { - buildBootImageVariant(ctx, variant, profile) - filesByArch[variant.target.Arch.ArchType] = variant.imagesDeps.Paths() - } - } - - return filesByArch -} - -// buildBootImageZipInPredefinedLocation generates a zip file containing all the boot image files. -// -// The supplied filesByArch is nil when the boot image files have not been generated. Otherwise, it -// is a map from android.ArchType to the predefined locations. -func buildBootImageZipInPredefinedLocation(ctx android.ModuleContext, image *bootImageConfig, filesByArch bootImageFilesByArch) { - if filesByArch == nil { - return - } - - // Compute the list of files from all the architectures. - zipFiles := android.Paths{} - for _, archType := range android.ArchTypeList() { - zipFiles = append(zipFiles, filesByArch[archType]...) - } - - rule := android.NewRuleBuilder(pctx, ctx) - rule.Command(). - BuiltTool("soong_zip"). - FlagWithOutput("-o ", image.zip). - FlagWithArg("-C ", image.dir.Join(ctx, android.Android.String()).String()). - FlagWithInputList("-f ", zipFiles, " -f ") - - rule.Build("zip_"+image.name, "zip "+image.name+" image") -} - -// Generate boot image build rules for a specific target. -func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, profile android.Path) { - - globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) - global := dexpreopt.GetGlobalConfig(ctx) - - arch := image.target.Arch.ArchType - os := image.target.Os.String() // We need to distinguish host-x86 and device-x86. - symbolsDir := image.symbolsDir.Join(ctx, os, image.installDirOnHost, arch.String()) - symbolsFile := symbolsDir.Join(ctx, image.stem+".oat") - outputDir := image.dir.Join(ctx, os, image.installDirOnHost, arch.String()) - outputPath := outputDir.Join(ctx, image.stem+".oat") - oatLocation := dexpreopt.PathToLocation(outputPath, arch) - imagePath := outputPath.ReplaceExtension(ctx, "art") - - rule := android.NewRuleBuilder(pctx, ctx) - - rule.Command().Text("mkdir").Flag("-p").Flag(symbolsDir.String()) - rule.Command().Text("rm").Flag("-f"). - Flag(symbolsDir.Join(ctx, "*.art").String()). - Flag(symbolsDir.Join(ctx, "*.oat").String()). - Flag(symbolsDir.Join(ctx, "*.invocation").String()) - rule.Command().Text("rm").Flag("-f"). - Flag(outputDir.Join(ctx, "*.art").String()). - Flag(outputDir.Join(ctx, "*.oat").String()). - Flag(outputDir.Join(ctx, "*.invocation").String()) - - cmd := rule.Command() - - extraFlags := ctx.Config().Getenv("ART_BOOT_IMAGE_EXTRA_ARGS") - if extraFlags == "" { - // Use ANDROID_LOG_TAGS to suppress most logging by default... - cmd.Text(`ANDROID_LOG_TAGS="*:e"`) - } else { - // ...unless the boot image is generated specifically for testing, then allow all logging. - cmd.Text(`ANDROID_LOG_TAGS="*:v"`) - } - - invocationPath := outputPath.ReplaceExtension(ctx, "invocation") - - cmd.Tool(globalSoong.Dex2oat). - Flag("--avoid-storing-invocation"). - FlagWithOutput("--write-invocation-to=", invocationPath).ImplicitOutput(invocationPath). - Flag("--runtime-arg").FlagWithArg("-Xms", global.Dex2oatImageXms). - Flag("--runtime-arg").FlagWithArg("-Xmx", global.Dex2oatImageXmx) - - if profile != nil { - cmd.FlagWithInput("--profile-file=", profile) - } - - dirtyImageFile := "frameworks/base/config/dirty-image-objects" - dirtyImagePath := android.ExistentPathForSource(ctx, dirtyImageFile) - if dirtyImagePath.Valid() { - cmd.FlagWithInput("--dirty-image-objects=", dirtyImagePath.Path()) - } - - if image.extends != nil { - // It is a boot image extension, so it needs the boot image it depends on (in this case the - // primary ART APEX image). - artImage := image.primaryImages - cmd. - Flag("--runtime-arg").FlagWithInputList("-Xbootclasspath:", image.dexPathsDeps.Paths(), ":"). - Flag("--runtime-arg").FlagWithList("-Xbootclasspath-locations:", image.dexLocationsDeps, ":"). - // Add the path to the first file in the boot image with the arch specific directory removed, - // dex2oat will reconstruct the path to the actual file when it needs it. As the actual path - // to the file cannot be passed to the command make sure to add the actual path as an Implicit - // dependency to ensure that it is built before the command runs. - FlagWithArg("--boot-image=", dexpreopt.PathToLocation(artImage, arch)).Implicit(artImage). - // Similarly, the dex2oat tool will automatically find the paths to other files in the base - // boot image so make sure to add them as implicit dependencies to ensure that they are built - // before this command is run. - Implicits(image.primaryImagesDeps) - } else { - // It is a primary image, so it needs a base address. - cmd.FlagWithArg("--base=", ctx.Config().LibartImgDeviceBaseAddress()) - } - - // We always expect a preloaded classes file to be available. However, if we cannot find it, it's - // OK to not pass the flag to dex2oat. - preloadedClassesPath := android.ExistentPathForSource(ctx, image.preloadedClassesFile) - if preloadedClassesPath.Valid() { - cmd.FlagWithInput("--preloaded-classes=", preloadedClassesPath.Path()) - } - - cmd. - FlagForEachInput("--dex-file=", image.dexPaths.Paths()). - FlagForEachArg("--dex-location=", image.dexLocations). - Flag("--generate-debug-info"). - Flag("--generate-build-id"). - Flag("--image-format=lz4hc"). - FlagWithArg("--oat-symbols=", symbolsFile.String()). - Flag("--strip"). - FlagWithArg("--oat-file=", outputPath.String()). - FlagWithArg("--oat-location=", oatLocation). - FlagWithArg("--image=", imagePath.String()). - FlagWithArg("--instruction-set=", arch.String()). - FlagWithArg("--android-root=", global.EmptyDirectory). - FlagWithArg("--no-inline-from=", "core-oj.jar"). - Flag("--force-determinism"). - Flag("--abort-on-hard-verifier-error") - - // Use the default variant/features for host builds. - // The map below contains only device CPU info (which might be x86 on some devices). - if image.target.Os == android.Android { - cmd.FlagWithArg("--instruction-set-variant=", global.CpuVariant[arch]) - cmd.FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch]) - } - - if global.BootFlags != "" { - cmd.Flag(global.BootFlags) - } - - if extraFlags != "" { - cmd.Flag(extraFlags) - } - - cmd.Textf(`|| ( echo %s ; false )`, proptools.ShellEscape(failureMessage)) - - installDir := filepath.Join("/", image.installDirOnHost, arch.String()) - - var vdexInstalls android.RuleBuilderInstalls - var unstrippedInstalls android.RuleBuilderInstalls - var deviceInstalls android.RuleBuilderInstalls - - for _, artOrOat := range image.moduleFiles(ctx, outputDir, ".art", ".oat") { - cmd.ImplicitOutput(artOrOat) - - // Install the .oat and .art files - rule.Install(artOrOat, filepath.Join(installDir, artOrOat.Base())) - } - - for _, vdex := range image.moduleFiles(ctx, outputDir, ".vdex") { - cmd.ImplicitOutput(vdex) - - // Note that the vdex files are identical between architectures. - // Make rules will create symlinks to share them between architectures. - vdexInstalls = append(vdexInstalls, - android.RuleBuilderInstall{vdex, filepath.Join(installDir, vdex.Base())}) - } - - for _, unstrippedOat := range image.moduleFiles(ctx, symbolsDir, ".oat") { - cmd.ImplicitOutput(unstrippedOat) - - // Install the unstripped oat files. The Make rules will put these in $(TARGET_OUT_UNSTRIPPED) - unstrippedInstalls = append(unstrippedInstalls, - android.RuleBuilderInstall{unstrippedOat, filepath.Join(installDir, unstrippedOat.Base())}) - } - - if image.installDirOnHost != image.installDirOnDevice && !image.shouldInstallInApex() && !ctx.Config().UnbundledBuild() { - installDirOnDevice := filepath.Join("/", image.installDirOnDevice, arch.String()) - for _, file := range image.moduleFiles(ctx, outputDir, ".art", ".oat", ".vdex") { - deviceInstalls = append(deviceInstalls, - android.RuleBuilderInstall{file, filepath.Join(installDirOnDevice, file.Base())}) - } - } - - rule.Build(image.name+"JarsDexpreopt_"+image.target.String(), "dexpreopt "+image.name+" jars "+arch.String()) - - // save output and installed files for makevars - image.installs = rule.Installs() - image.vdexInstalls = vdexInstalls - image.unstrippedInstalls = unstrippedInstalls - image.deviceInstalls = deviceInstalls - image.licenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile()) -} - -const failureMessage = `ERROR: Dex2oat failed to compile a boot image. -It is likely that the boot classpath is inconsistent. -Rebuild with ART_BOOT_IMAGE_EXTRA_ARGS="--runtime-arg -verbose:verifier" to see verification errors.` - -func bootImageProfileRule(ctx android.ModuleContext, image *bootImageConfig) android.WritablePath { - globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) - global := dexpreopt.GetGlobalConfig(ctx) - - if global.DisableGenerateProfile { - return nil - } - - defaultProfile := "frameworks/base/config/boot-image-profile.txt" - - rule := android.NewRuleBuilder(pctx, ctx) - - var bootImageProfile android.Path - if len(global.BootImageProfiles) > 1 { - combinedBootImageProfile := image.dir.Join(ctx, "boot-image-profile.txt") - rule.Command().Text("cat").Inputs(global.BootImageProfiles).Text(">").Output(combinedBootImageProfile) - bootImageProfile = combinedBootImageProfile - } else if len(global.BootImageProfiles) == 1 { - bootImageProfile = global.BootImageProfiles[0] - } else if path := android.ExistentPathForSource(ctx, defaultProfile); path.Valid() { - bootImageProfile = path.Path() - } else { - // No profile (not even a default one, which is the case on some branches - // like master-art-host that don't have frameworks/base). - // Return nil and continue without profile. - return nil - } - - profile := image.dir.Join(ctx, "boot.prof") - - rule.Command(). - Text(`ANDROID_LOG_TAGS="*:e"`). - Tool(globalSoong.Profman). - Flag("--output-profile-type=boot"). - FlagWithInput("--create-profile-from=", bootImageProfile). - FlagForEachInput("--apk=", image.dexPathsDeps.Paths()). - FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps). - FlagWithOutput("--reference-profile-file=", profile) - - if image == defaultBootImageConfig(ctx) { - rule.Install(profile, "/system/etc/boot-image.prof") - image.profileInstalls = append(image.profileInstalls, rule.Installs()...) - image.profileLicenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile()) - } - - rule.Build("bootJarsProfile", "profile boot jars") - - image.profilePathOnHost = profile - - return profile -} - -// bootFrameworkProfileRule generates the rule to create the boot framework profile and -// returns a path to the generated file. -func bootFrameworkProfileRule(ctx android.ModuleContext, image *bootImageConfig) android.WritablePath { - globalSoong := dexpreopt.GetGlobalSoongConfig(ctx) - global := dexpreopt.GetGlobalConfig(ctx) - - if global.DisableGenerateProfile || ctx.Config().UnbundledBuild() { - return nil - } - - defaultProfile := "frameworks/base/config/boot-profile.txt" - bootFrameworkProfile := android.PathForSource(ctx, defaultProfile) - - profile := image.dir.Join(ctx, "boot.bprof") - - rule := android.NewRuleBuilder(pctx, ctx) - rule.Command(). - Text(`ANDROID_LOG_TAGS="*:e"`). - Tool(globalSoong.Profman). - Flag("--output-profile-type=bprof"). - FlagWithInput("--create-profile-from=", bootFrameworkProfile). - FlagForEachInput("--apk=", image.dexPathsDeps.Paths()). - FlagForEachArg("--dex-location=", image.getAnyAndroidVariant().dexLocationsDeps). - FlagWithOutput("--reference-profile-file=", profile) - - rule.Install(profile, "/system/etc/boot-image.bprof") - rule.Build("bootFrameworkProfile", "profile boot framework jars") - image.profileInstalls = append(image.profileInstalls, rule.Installs()...) - image.profileLicenseMetadataFile = android.OptionalPathForPath(ctx.LicenseMetadataFile()) - - return profile -} - -func dumpOatRules(ctx android.ModuleContext, image *bootImageConfig) { - var allPhonies android.Paths - for _, image := range image.variants { - arch := image.target.Arch.ArchType - suffix := arch.String() - // Host and target might both use x86 arch. We need to ensure the names are unique. - if image.target.Os.Class == android.Host { - suffix = "host-" + suffix - } - // Create a rule to call oatdump. - output := android.PathForOutput(ctx, "boot."+suffix+".oatdump.txt") - rule := android.NewRuleBuilder(pctx, ctx) - imageLocationsOnHost, _ := image.imageLocations() - rule.Command(). - BuiltTool("oatdump"). - FlagWithInputList("--runtime-arg -Xbootclasspath:", image.dexPathsDeps.Paths(), ":"). - FlagWithList("--runtime-arg -Xbootclasspath-locations:", image.dexLocationsDeps, ":"). - FlagWithArg("--image=", strings.Join(imageLocationsOnHost, ":")).Implicits(image.imagesDeps.Paths()). - FlagWithOutput("--output=", output). - FlagWithArg("--instruction-set=", arch.String()) - rule.Build("dump-oat-boot-"+suffix, "dump oat boot "+arch.String()) - - // Create a phony rule that depends on the output file and prints the path. - phony := android.PathForPhony(ctx, "dump-oat-boot-"+suffix) - rule = android.NewRuleBuilder(pctx, ctx) - rule.Command(). - Implicit(output). - ImplicitOutput(phony). - Text("echo").FlagWithArg("Output in ", output.String()) - rule.Build("phony-dump-oat-boot-"+suffix, "dump oat boot "+arch.String()) - - allPhonies = append(allPhonies, phony) - } - - phony := android.PathForPhony(ctx, "dump-oat-boot") - ctx.Build(pctx, android.BuildParams{ - Rule: android.Phony, - Output: phony, - Inputs: allPhonies, - Description: "dump-oat-boot", - }) -} - -func writeGlobalConfigForMake(ctx android.SingletonContext, path android.WritablePath) { - data := dexpreopt.GetGlobalConfigRawData(ctx) - - android.WriteFileRule(ctx, path, string(data)) -} - -// Define Make variables for boot image names, paths, etc. These variables are used in makefiles -// (make/core/dex_preopt_libart.mk) to generate install rules that copy boot image files to the -// correct output directories. -func (d *dexpreoptBootJars) MakeVars(ctx android.MakeVarsContext) { - if d.dexpreoptConfigForMake != nil { - ctx.Strict("DEX_PREOPT_CONFIG_FOR_MAKE", d.dexpreoptConfigForMake.String()) - ctx.Strict("DEX_PREOPT_SOONG_CONFIG_FOR_MAKE", android.PathForOutput(ctx, "dexpreopt_soong.config").String()) - } - - image := d.defaultBootImage - if image == nil { - return - } - - ctx.Strict("DEXPREOPT_IMAGE_PROFILE_BUILT_INSTALLED", image.profileInstalls.String()) - if image.profileLicenseMetadataFile.Valid() { - ctx.Strict("DEXPREOPT_IMAGE_PROFILE_LICENSE_METADATA", image.profileLicenseMetadataFile.String()) - } - - global := dexpreopt.GetGlobalConfig(ctx) - dexPaths, dexLocations := bcpForDexpreopt(ctx, global.PreoptWithUpdatableBcp) - ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_FILES", strings.Join(dexPaths.Strings(), " ")) - ctx.Strict("DEXPREOPT_BOOTCLASSPATH_DEX_LOCATIONS", strings.Join(dexLocations, " ")) - - for _, variant := range image.variants { - suffix := "" - if variant.target.Os.Class == android.Host { - suffix = "_host" - } - sfx := suffix + "_" + variant.target.Arch.ArchType.String() - ctx.Strict("DEXPREOPT_IMAGE_VDEX_BUILT_INSTALLED_"+sfx, variant.vdexInstalls.String()) - ctx.Strict("DEXPREOPT_IMAGE_"+sfx, variant.imagePathOnHost.String()) - ctx.Strict("DEXPREOPT_IMAGE_DEPS_"+sfx, strings.Join(variant.imagesDeps.Strings(), " ")) - ctx.Strict("DEXPREOPT_IMAGE_BUILT_INSTALLED_"+sfx, variant.installs.String()) - ctx.Strict("DEXPREOPT_IMAGE_UNSTRIPPED_BUILT_INSTALLED_"+sfx, variant.unstrippedInstalls.String()) - if variant.licenseMetadataFile.Valid() { - ctx.Strict("DEXPREOPT_IMAGE_LICENSE_METADATA_"+sfx, variant.licenseMetadataFile.String()) - } - } - imageLocationsOnHost, imageLocationsOnDevice := image.getAnyAndroidVariant().imageLocations() - ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_ON_HOST", strings.Join(imageLocationsOnHost, ":")) - ctx.Strict("DEXPREOPT_IMAGE_LOCATIONS_ON_DEVICE", strings.Join(imageLocationsOnDevice, ":")) - ctx.Strict("DEXPREOPT_IMAGE_ZIP", image.zip.String()) - - // There used to be multiple images for JIT-Zygote mode, not there's only one. - ctx.Strict("DEXPREOPT_IMAGE_NAMES", image.name) -} diff --git a/java/dexpreopt_config.go_v1 b/java/dexpreopt_config.go_v1 deleted file mode 100644 index d71e2bbfd..000000000 --- a/java/dexpreopt_config.go_v1 +++ /dev/null @@ -1,215 +0,0 @@ -// Copyright 2019 Google Inc. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package java - -import ( - "path/filepath" - "strings" - - "android/soong/android" - "android/soong/dexpreopt" -) - -// dexpreoptTargets returns the list of targets that are relevant to dexpreopting, which excludes architectures -// supported through native bridge. -func dexpreoptTargets(ctx android.PathContext) []android.Target { - var targets []android.Target - for _, target := range ctx.Config().Targets[android.Android] { - if target.NativeBridge == android.NativeBridgeDisabled { - targets = append(targets, target) - } - } - // We may also need the images on host in order to run host-based tests. - for _, target := range ctx.Config().Targets[ctx.Config().BuildOS] { - targets = append(targets, target) - } - - return targets -} - -var ( - bootImageConfigKey = android.NewOnceKey("bootImageConfig") - bootImageConfigRawKey = android.NewOnceKey("bootImageConfigRaw") - artBootImageName = "art" - frameworkBootImageName = "boot" -) - -func genBootImageConfigRaw(ctx android.PathContext) map[string]*bootImageConfig { - return ctx.Config().Once(bootImageConfigRawKey, func() interface{} { - global := dexpreopt.GetGlobalConfig(ctx) - - artModules := global.ArtApexJars - frameworkModules := global.BootJars.RemoveList(artModules) - - // ART config for the primary boot image in the ART apex. - // It includes the Core Libraries. - artCfg := bootImageConfig{ - name: artBootImageName, - stem: "boot", - installDirOnHost: "apex/art_boot_images/javalib", - installDirOnDevice: "system/framework", - profileInstallPathInApex: "etc/boot-image.prof", - modules: artModules, - preloadedClassesFile: "art/build/boot/preloaded-classes", - } - - // Framework config for the boot image extension. - // It includes framework libraries and depends on the ART config. - frameworkSubdir := "system/framework" - frameworkCfg := bootImageConfig{ - extends: &artCfg, - name: frameworkBootImageName, - stem: "boot", - installDirOnHost: frameworkSubdir, - installDirOnDevice: frameworkSubdir, - modules: frameworkModules, - preloadedClassesFile: "frameworks/base/config/preloaded-classes", - } - - return map[string]*bootImageConfig{ - artBootImageName: &artCfg, - frameworkBootImageName: &frameworkCfg, - } - }).(map[string]*bootImageConfig) -} - -// Construct the global boot image configs. -func genBootImageConfigs(ctx android.PathContext) map[string]*bootImageConfig { - return ctx.Config().Once(bootImageConfigKey, func() interface{} { - targets := dexpreoptTargets(ctx) - deviceDir := android.PathForOutput(ctx, ctx.Config().DeviceName()) - - configs := genBootImageConfigRaw(ctx) - artCfg := configs[artBootImageName] - frameworkCfg := configs[frameworkBootImageName] - - // common to all configs - for _, c := range configs { - c.dir = deviceDir.Join(ctx, "dex_"+c.name+"jars") - c.symbolsDir = deviceDir.Join(ctx, "dex_"+c.name+"jars_unstripped") - - // expands to <stem>.art for primary image and <stem>-<1st module>.art for extension - imageName := c.firstModuleNameOrStem(ctx) + ".art" - - // The path to bootclasspath dex files needs to be known at module - // GenerateAndroidBuildAction time, before the bootclasspath modules have been compiled. - // Set up known paths for them, the singleton rules will copy them there. - // TODO(b/143682396): use module dependencies instead - inputDir := deviceDir.Join(ctx, "dex_"+c.name+"jars_input") - c.dexPaths = c.modules.BuildPaths(ctx, inputDir) - c.dexPathsByModule = c.modules.BuildPathsByModule(ctx, inputDir) - c.dexPathsDeps = c.dexPaths - - // Create target-specific variants. - for _, target := range targets { - arch := target.Arch.ArchType - imageDir := c.dir.Join(ctx, target.Os.String(), c.installDirOnHost, arch.String()) - variant := &bootImageVariant{ - bootImageConfig: c, - target: target, - imagePathOnHost: imageDir.Join(ctx, imageName), - imagePathOnDevice: filepath.Join("/", c.installDirOnDevice, arch.String(), imageName), - imagesDeps: c.moduleFiles(ctx, imageDir, ".art", ".oat", ".vdex"), - dexLocations: c.modules.DevicePaths(ctx.Config(), target.Os), - } - variant.dexLocationsDeps = variant.dexLocations - c.variants = append(c.variants, variant) - } - - c.zip = c.dir.Join(ctx, c.name+".zip") - } - - // specific to the framework config - frameworkCfg.dexPathsDeps = append(artCfg.dexPathsDeps, frameworkCfg.dexPathsDeps...) - for i := range targets { - frameworkCfg.variants[i].primaryImages = artCfg.variants[i].imagePathOnHost - frameworkCfg.variants[i].primaryImagesDeps = artCfg.variants[i].imagesDeps.Paths() - frameworkCfg.variants[i].dexLocationsDeps = append(artCfg.variants[i].dexLocations, frameworkCfg.variants[i].dexLocationsDeps...) - } - - return configs - }).(map[string]*bootImageConfig) -} - -func defaultBootImageConfig(ctx android.PathContext) *bootImageConfig { - return genBootImageConfigs(ctx)[frameworkBootImageName] -} - -// Apex boot config allows to access build/install paths of apex boot jars without going -// through the usual trouble of registering dependencies on those modules and extracting build paths -// from those dependencies. -type apexBootConfig struct { - // A list of apex boot jars. - modules android.ConfiguredJarList - - // A list of predefined build paths to apex boot jars. They are configured very early, - // before the modules for these jars are processed and the actual paths are generated, and - // later on a singleton adds commands to copy actual jars to the predefined paths. - dexPaths android.WritablePaths - - // Map from module name (without prebuilt_ prefix) to the predefined build path. - dexPathsByModule map[string]android.WritablePath - - // A list of dex locations (a.k.a. on-device paths) to the boot jars. - dexLocations []string -} - -var updatableBootConfigKey = android.NewOnceKey("apexBootConfig") - -// Returns apex boot config. -func GetApexBootConfig(ctx android.PathContext) apexBootConfig { - return ctx.Config().Once(updatableBootConfigKey, func() interface{} { - apexBootJars := dexpreopt.GetGlobalConfig(ctx).ApexBootJars - - dir := android.PathForOutput(ctx, ctx.Config().DeviceName(), "apex_bootjars") - dexPaths := apexBootJars.BuildPaths(ctx, dir) - dexPathsByModuleName := apexBootJars.BuildPathsByModule(ctx, dir) - - dexLocations := apexBootJars.DevicePaths(ctx.Config(), android.Android) - - return apexBootConfig{apexBootJars, dexPaths, dexPathsByModuleName, dexLocations} - }).(apexBootConfig) -} - -// Returns a list of paths and a list of locations for the boot jars used in dexpreopt (to be -// passed in -Xbootclasspath and -Xbootclasspath-locations arguments for dex2oat). -func bcpForDexpreopt(ctx android.PathContext, withUpdatable bool) (android.WritablePaths, []string) { - // Non-updatable boot jars (they are used both in the boot image and in dexpreopt). - bootImage := defaultBootImageConfig(ctx) - dexPaths := bootImage.dexPathsDeps - // The dex locations for all Android variants are identical. - dexLocations := bootImage.getAnyAndroidVariant().dexLocationsDeps - - if withUpdatable { - // Apex boot jars (they are used only in dexpreopt, but not in the boot image). - apexBootConfig := GetApexBootConfig(ctx) - dexPaths = append(dexPaths, apexBootConfig.dexPaths...) - dexLocations = append(dexLocations, apexBootConfig.dexLocations...) - } - - return dexPaths, dexLocations -} - -var defaultBootclasspathKey = android.NewOnceKey("defaultBootclasspath") - -var copyOf = android.CopyOf - -func init() { - android.RegisterMakeVarsProvider(pctx, dexpreoptConfigMakevars) -} - -func dexpreoptConfigMakevars(ctx android.MakeVarsContext) { - ctx.Strict("DEXPREOPT_BOOT_JARS_MODULES", strings.Join(defaultBootImageConfig(ctx).modules.CopyOfApexJarPairs(), ":")) -} diff --git a/java/droiddoc.go b/java/droiddoc.go index 023d61912..96639220a 100644 --- a/java/droiddoc.go +++ b/java/droiddoc.go @@ -256,6 +256,10 @@ func (j *Javadoc) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec return j.SdkVersion(ctx) } +func (j *Javadoc) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { + return j.SdkVersion(ctx) +} + func (j *Javadoc) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return j.SdkVersion(ctx) } diff --git a/java/java.go b/java/java.go index cbdc2bd28..eaf82ad7a 100644 --- a/java/java.go +++ b/java/java.go @@ -513,6 +513,20 @@ func (v javaVersion) String() string { } } +func (v javaVersion) StringForKotlinc() string { + // $ ./external/kotlinc/bin/kotlinc -jvm-target foo + // error: unknown JVM target version: foo + // Supported versions: 1.6, 1.8, 9, 10, 11, 12, 13, 14, 15, 16, 17 + switch v { + case JAVA_VERSION_7: + return "1.6" + case JAVA_VERSION_9: + return "9" + default: + return v.String() + } +} + // Returns true if javac targeting this version uses system modules instead of a bootclasspath. func (v javaVersion) usesJavaModules() bool { return v >= 9 @@ -1445,6 +1459,10 @@ type ImportProperties struct { // specified. Min_sdk_version *string + // The max sdk version placeholder used to replace maxSdkVersion attributes on permission + // and uses-permission tags in manifest_fixer. + Replace_max_sdk_version_placeholder *string + Installable *bool // If not empty, classes are restricted to the specified packages and their sub-packages. @@ -1524,6 +1542,13 @@ func (j *Import) MinSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return j.SdkVersion(ctx) } +func (j *Import) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { + if j.properties.Replace_max_sdk_version_placeholder != nil { + return android.SdkSpecFrom(ctx, *j.properties.Replace_max_sdk_version_placeholder) + } + return android.SdkSpecFrom(ctx, "") +} + func (j *Import) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return j.SdkVersion(ctx) } diff --git a/java/kotlin.go b/java/kotlin.go index 903c6249b..9bff5ea01 100644 --- a/java/kotlin.go +++ b/java/kotlin.go @@ -119,9 +119,8 @@ func kotlinCompile(ctx android.ModuleContext, outputFile, headerOutputFile andro "srcJarDir": android.PathForModuleOut(ctx, "kotlinc", "srcJars").String(), "kotlinBuildFile": android.PathForModuleOut(ctx, "kotlinc-build.xml").String(), "emptyDir": android.PathForModuleOut(ctx, "kotlinc", "empty").String(), - // http://b/69160377 kotlinc only supports -jvm-target 1.6 and 1.8 - "kotlinJvmTarget": "1.8", - "name": kotlinName, + "kotlinJvmTarget": flags.javaVersion.StringForKotlinc(), + "name": kotlinName, }, }) } diff --git a/java/rro.go b/java/rro.go index be84afffc..7952c2cc4 100644 --- a/java/rro.go +++ b/java/rro.go @@ -173,6 +173,10 @@ func (r *RuntimeResourceOverlay) MinSdkVersion(ctx android.EarlyModuleContext) a return r.SdkVersion(ctx) } +func (r *RuntimeResourceOverlay) ReplaceMaxSdkVersionPlaceholder(ctx android.EarlyModuleContext) android.SdkSpec { + return android.SdkSpecFrom(ctx, "") +} + func (r *RuntimeResourceOverlay) TargetSdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return r.SdkVersion(ctx) } diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go index 79d2ee9f7..a2cd2619a 100644 --- a/java/systemserver_classpath_fragment.go +++ b/java/systemserver_classpath_fragment.go @@ -24,15 +24,7 @@ import ( func init() { registerSystemserverClasspathBuildComponents(android.InitRegistrationContext) - android.RegisterSdkMemberType(&systemServerClasspathFragmentMemberType{ - SdkMemberTypeBase: android.SdkMemberTypeBase{ - PropertyName: "systemserverclasspath_fragments", - SupportsSdk: true, - - // This was only added in Tiramisu. - SupportedBuildReleaseSpecification: "Tiramisu+", - }, - }) + android.RegisterSdkMemberType(SystemServerClasspathFragmentSdkMemberType) } func registerSystemserverClasspathBuildComponents(ctx android.RegistrationContext) { @@ -41,6 +33,17 @@ func registerSystemserverClasspathBuildComponents(ctx android.RegistrationContex ctx.RegisterModuleType("prebuilt_systemserverclasspath_fragment", prebuiltSystemServerClasspathModuleFactory) } +var SystemServerClasspathFragmentSdkMemberType = &systemServerClasspathFragmentMemberType{ + SdkMemberTypeBase: android.SdkMemberTypeBase{ + PropertyName: "systemserverclasspath_fragments", + SupportsSdk: true, + + // Support for adding systemserverclasspath_fragments to the sdk snapshot was only added in + // Tiramisu. + SupportedBuildReleaseSpecification: "Tiramisu+", + }, +} + type platformSystemServerClasspathModule struct { android.ModuleBase diff --git a/rust/config/global.go b/rust/config/global.go index 3ef0ecb18..9e48344b8 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -24,7 +24,7 @@ import ( var pctx = android.NewPackageContext("android/soong/rust/config") var ( - RustDefaultVersion = "1.61.0.p2" + RustDefaultVersion = "1.62.0" RustDefaultBase = "prebuilts/rust/" DefaultEdition = "2021" Stdlibs = []string{ diff --git a/scripts/Android.bp b/scripts/Android.bp index 4773579e3..814bd5753 100644 --- a/scripts/Android.bp +++ b/scripts/Android.bp @@ -84,6 +84,16 @@ python_binary_host { ], } +python_test_host { + name: "jsonmodify_test", + main: "jsonmodify_test.py", + srcs: [ + "jsonmodify_test.py", + "jsonmodify.py", + ], + test_suites: ["general-tests"], +} + python_binary_host { name: "test_config_fixer", main: "test_config_fixer.py", @@ -193,3 +203,9 @@ sh_binary_host { name: "list_image", src: "list_image.sh", } + +filegroup { + name: "rustfmt.toml", + srcs: ["rustfmt.toml"], + visibility: ["//visibility:public"], +} diff --git a/scripts/jsonmodify.py b/scripts/jsonmodify.py index ba1109e7a..8bd8d4556 100755 --- a/scripts/jsonmodify.py +++ b/scripts/jsonmodify.py @@ -59,6 +59,13 @@ class Replace(str): cur[key] = val +class ReplaceIfEqual(str): + def apply(self, obj, old_val, new_val): + cur, key = follow_path(obj, self) + if cur and cur[key] == int(old_val): + cur[key] = new_val + + class Remove(str): def apply(self, obj): cur, key = follow_path(obj, self) @@ -75,6 +82,14 @@ class AppendList(str): raise ValueError(self + " should be a array.") cur[key].extend(args) +# A JSONDecoder that supports line comments start with // +class JSONWithCommentsDecoder(json.JSONDecoder): + def __init__(self, **kw): + super().__init__(**kw) + + def decode(self, s: str): + s = '\n'.join(l for l in s.split('\n') if not l.lstrip(' ').startswith('//')) + return super().decode(s) def main(): parser = argparse.ArgumentParser() @@ -91,6 +106,11 @@ def main(): help='replace value of the key specified by path. If path doesn\'t exist, no op.', metavar=('path', 'value'), nargs=2, dest='patch', action='append') + parser.add_argument("-se", "--replace-if-equal", type=ReplaceIfEqual, + help='replace value of the key specified by path to new_value if it\'s equal to old_value.' + + 'If path doesn\'t exist or the value is not equal to old_value, no op.', + metavar=('path', 'old_value', 'new_value'), + nargs=3, dest='patch', action='append') parser.add_argument("-r", "--remove", type=Remove, help='remove the key specified by path. If path doesn\'t exist, no op.', metavar='path', @@ -103,9 +123,9 @@ def main(): if args.input: with open(args.input) as f: - obj = json.load(f, object_pairs_hook=collections.OrderedDict) + obj = json.load(f, object_pairs_hook=collections.OrderedDict, cls=JSONWithCommentsDecoder) else: - obj = json.load(sys.stdin, object_pairs_hook=collections.OrderedDict) + obj = json.load(sys.stdin, object_pairs_hook=collections.OrderedDict, cls=JSONWithCommentsDecoder) for p in args.patch: p[0].apply(obj, *p[1:]) diff --git a/scripts/jsonmodify_test.py b/scripts/jsonmodify_test.py new file mode 100644 index 000000000..6f0291dfb --- /dev/null +++ b/scripts/jsonmodify_test.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python +# +# Copyright (C) 2022 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +"""Tests for jsonmodify.""" + +import json +import jsonmodify +import unittest + + +class JsonmodifyTest(unittest.TestCase): + + def test_set_value(self): + obj = json.loads('{"field1": 111}') + field1 = jsonmodify.SetValue("field1") + field1.apply(obj, 222) + field2 = jsonmodify.SetValue("field2") + field2.apply(obj, 333) + expected = json.loads('{"field1": 222, "field2": 333}') + self.assertEqual(obj, expected) + + def test_replace(self): + obj = json.loads('{"field1": 111}') + field1 = jsonmodify.Replace("field1") + field1.apply(obj, 222) + field2 = jsonmodify.Replace("field2") + field2.apply(obj, 333) + expected = json.loads('{"field1": 222}') + self.assertEqual(obj, expected) + + def test_replace_if_equal(self): + obj = json.loads('{"field1": 111, "field2": 222}') + field1 = jsonmodify.ReplaceIfEqual("field1") + field1.apply(obj, 111, 333) + field2 = jsonmodify.ReplaceIfEqual("field2") + field2.apply(obj, 444, 555) + field3 = jsonmodify.ReplaceIfEqual("field3") + field3.apply(obj, 666, 777) + expected = json.loads('{"field1": 333, "field2": 222}') + self.assertEqual(obj, expected) + + def test_remove(self): + obj = json.loads('{"field1": 111, "field2": 222}') + field2 = jsonmodify.Remove("field2") + field2.apply(obj) + field3 = jsonmodify.Remove("field3") + field3.apply(obj) + expected = json.loads('{"field1": 111}') + self.assertEqual(obj, expected) + + def test_append_list(self): + obj = json.loads('{"field1": [111]}') + field1 = jsonmodify.AppendList("field1") + field1.apply(obj, 222, 333) + field2 = jsonmodify.AppendList("field2") + field2.apply(obj, 444, 555, 666) + expected = json.loads('{"field1": [111, 222, 333], "field2": [444, 555, 666]}') + self.assertEqual(obj, expected) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/scripts/manifest_fixer.py b/scripts/manifest_fixer.py index 2d3103b43..2da29ee91 100755 --- a/scripts/manifest_fixer.py +++ b/scripts/manifest_fixer.py @@ -39,6 +39,8 @@ def parse_args(): parser = argparse.ArgumentParser() parser.add_argument('--minSdkVersion', default='', dest='min_sdk_version', help='specify minSdkVersion used by the build system') + parser.add_argument('--replaceMaxSdkVersionPlaceholder', default='', dest='max_sdk_version', + help='specify maxSdkVersion used by the build system') parser.add_argument('--targetSdkVersion', default='', dest='target_sdk_version', help='specify targetSdkVersion used by the build system') parser.add_argument('--raise-min-sdk-version', dest='raise_min_sdk_version', action='store_true', @@ -342,6 +344,24 @@ def set_test_only_flag_to_true(doc): attr.value = 'true' application.setAttributeNode(attr) +def set_max_sdk_version(doc, max_sdk_version): + """Replace the maxSdkVersion attribute value for permission and + uses-permission tags if the value was originally set to 'current'. + Used for cts test cases where the maxSdkVersion should equal to + Build.SDK_INT. + + Args: + doc: The XML document. May be modified by this function. + max_sdk_version: The requested maxSdkVersion attribute. + """ + manifest = parse_manifest(doc) + for tag in ['permission', 'uses-permission']: + children = get_children_with_tag(manifest, tag) + for child in children: + max_attr = child.getAttributeNodeNS(android_ns, 'maxSdkVersion') + if max_attr and max_attr.value == 'current': + max_attr.value = max_sdk_version + def main(): """Program entry point.""" try: @@ -354,6 +374,9 @@ def main(): if args.raise_min_sdk_version: raise_min_sdk_version(doc, args.min_sdk_version, args.target_sdk_version, args.library) + if args.max_sdk_version: + set_max_sdk_version(doc, args.max_sdk_version) + if args.uses_libraries: add_uses_libraries(doc, args.uses_libraries, True) diff --git a/scripts/manifest_fixer_test.py b/scripts/manifest_fixer_test.py index 199b279cd..dad104a54 100755 --- a/scripts/manifest_fixer_test.py +++ b/scripts/manifest_fixer_test.py @@ -571,5 +571,77 @@ class AddTestOnlyApplicationTest(unittest.TestCase): output = self.run_test(manifest_input) self.assert_xml_equal(output, manifest_input) + +class SetMaxSdkVersionTest(unittest.TestCase): + """Unit tests for set_max_sdk_version function.""" + + def assert_xml_equal(self, output, expected): + self.assertEqual(ET.canonicalize(output), ET.canonicalize(expected)) + + def run_test(self, input_manifest, max_sdk_version): + doc = minidom.parseString(input_manifest) + manifest_fixer.set_max_sdk_version(doc, max_sdk_version) + output = io.StringIO() + manifest_fixer.write_xml(output, doc) + return output.getvalue() + + manifest_tmpl = ( + '<?xml version="1.0" encoding="utf-8"?>\n' + '<manifest xmlns:android="http://schemas.android.com/apk/res/android">\n' + '%s' + '</manifest>\n') + + def permission(self, max=None): + if max is None: + return ' <permission/>' + return ' <permission android:maxSdkVersion="%s"/>\n' % max + + def uses_permission(self, max=None): + if max is None: + return ' <uses-permission/>' + return ' <uses-permission android:maxSdkVersion="%s"/>\n' % max + + def test_permission_no_max_sdk_version(self): + """Tests if permission has no maxSdkVersion attribute""" + manifest_input = self.manifest_tmpl % self.permission() + expected = self.manifest_tmpl % self.permission() + output = self.run_test(manifest_input, '9000') + self.assert_xml_equal(output, expected) + + def test_permission_max_sdk_version_changed(self): + """Tests if permission maxSdkVersion attribute is set to current""" + manifest_input = self.manifest_tmpl % self.permission('current') + expected = self.manifest_tmpl % self.permission(9000) + output = self.run_test(manifest_input, '9000') + self.assert_xml_equal(output, expected) + + def test_permission_max_sdk_version_not_changed(self): + """Tests if permission maxSdkVersion attribute is not set to current""" + manifest_input = self.manifest_tmpl % self.permission(30) + expected = self.manifest_tmpl % self.permission(30) + output = self.run_test(manifest_input, '9000') + self.assert_xml_equal(output, expected) + + def test_uses_permission_no_max_sdk_version(self): + """Tests if uses-permission has no maxSdkVersion attribute""" + manifest_input = self.manifest_tmpl % self.uses_permission() + expected = self.manifest_tmpl % self.uses_permission() + output = self.run_test(manifest_input, '9000') + self.assert_xml_equal(output, expected) + + def test_uses_permission_max_sdk_version_changed(self): + """Tests if uses-permission maxSdkVersion attribute is set to current""" + manifest_input = self.manifest_tmpl % self.uses_permission('current') + expected = self.manifest_tmpl % self.uses_permission(9000) + output = self.run_test(manifest_input, '9000') + self.assert_xml_equal(output, expected) + + def test_uses_permission_max_sdk_version_not_changed(self): + """Tests if uses-permission maxSdkVersion attribute is not set to current""" + manifest_input = self.manifest_tmpl % self.uses_permission(30) + expected = self.manifest_tmpl % self.uses_permission(30) + output = self.run_test(manifest_input, '9000') + self.assert_xml_equal(output, expected) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index 93ad172ae..13ddbe768 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -190,7 +190,7 @@ func checkBootJarsPackageCheckRule(t *testing.T, result *android.TestResult, exp android.AssertStringDoesContain(t, "boot jars package check", command, expectedCommandArgs) } -func TestSnapshotWithBootClasspathFragment_Contents(t *testing.T) { +func testSnapshotWithBootClasspathFragment_Contents(t *testing.T, sdk string, copyRules string) { result := android.GroupFixturePreparers( prepareForSdkTestWithJava, java.PrepareForTestWithJavaDefaultModules, @@ -202,19 +202,7 @@ func TestSnapshotWithBootClasspathFragment_Contents(t *testing.T) { // Add a platform_bootclasspath that depends on the fragment. fixtureAddPlatformBootclasspathForBootclasspathFragment("myapex", "mybootclasspathfragment"), - android.FixtureWithRootAndroidBp(` - sdk { - name: "mysdk", - bootclasspath_fragments: ["mybootclasspathfragment"], - java_sdk_libs: [ - // This is not strictly needed as it should be automatically added to the sdk_snapshot as - // a java_sdk_libs module because it is used in the mybootclasspathfragment's - // api.stub_libs property. However, it is specified here to ensure that duplicates are - // correctly deduped. - "mysdklibrary", - ], - } - + android.FixtureWithRootAndroidBp(sdk+` apex { name: "myapex", key: "myapex.key", @@ -373,24 +361,7 @@ java_sdk_library_import { }, } `), - checkAllCopyRules(` -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv -.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv -.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar -.intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar -.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt -.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt -.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar -.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt -.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt -.intermediates/mycoreplatform.stubs/android_common/javac/mycoreplatform.stubs.jar -> sdk_library/public/mycoreplatform-stubs.jar -.intermediates/mycoreplatform.stubs.source/android_common/metalava/mycoreplatform.stubs.source_api.txt -> sdk_library/public/mycoreplatform.txt -.intermediates/mycoreplatform.stubs.source/android_common/metalava/mycoreplatform.stubs.source_removed.txt -> sdk_library/public/mycoreplatform-removed.txt -`), + checkAllCopyRules(copyRules), snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot), snapshotTestChecker(checkSnapshotWithoutSource, func(t *testing.T, result *android.TestResult) { module := result.ModuleForTests("platform-bootclasspath", "android_common") @@ -427,6 +398,89 @@ java_sdk_library_import { ) } +func TestSnapshotWithBootClasspathFragment_Contents(t *testing.T) { + t.Run("added-directly", func(t *testing.T) { + testSnapshotWithBootClasspathFragment_Contents(t, ` + sdk { + name: "mysdk", + bootclasspath_fragments: ["mybootclasspathfragment"], + java_sdk_libs: [ + // This is not strictly needed as it should be automatically added to the sdk_snapshot as + // a java_sdk_libs module because it is used in the mybootclasspathfragment's + // api.stub_libs property. However, it is specified here to ensure that duplicates are + // correctly deduped. + "mysdklibrary", + ], + } + `, ` +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv +.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar +.intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar +.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt +.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt +.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar +.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt +.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt +.intermediates/mycoreplatform.stubs/android_common/javac/mycoreplatform.stubs.jar -> sdk_library/public/mycoreplatform-stubs.jar +.intermediates/mycoreplatform.stubs.source/android_common/metalava/mycoreplatform.stubs.source_api.txt -> sdk_library/public/mycoreplatform.txt +.intermediates/mycoreplatform.stubs.source/android_common/metalava/mycoreplatform.stubs.source_removed.txt -> sdk_library/public/mycoreplatform-removed.txt +`) + }) + + copyBootclasspathFragmentFromApexVariantRules := ` +.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv +.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv +.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/index.csv -> hiddenapi/index.csv +.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/signature-patterns.csv -> hiddenapi/signature-patterns.csv +.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-stub-flags.csv -> hiddenapi/filtered-stub-flags.csv +.intermediates/mybootclasspathfragment/android_common_myapex/modular-hiddenapi/filtered-flags.csv -> hiddenapi/filtered-flags.csv +.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar +.intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar +.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt +.intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt +.intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar +.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt +.intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt +.intermediates/mycoreplatform.stubs/android_common/javac/mycoreplatform.stubs.jar -> sdk_library/public/mycoreplatform-stubs.jar +.intermediates/mycoreplatform.stubs.source/android_common/metalava/mycoreplatform.stubs.source_api.txt -> sdk_library/public/mycoreplatform.txt +.intermediates/mycoreplatform.stubs.source/android_common/metalava/mycoreplatform.stubs.source_removed.txt -> sdk_library/public/mycoreplatform-removed.txt +` + t.Run("added-via-apex", func(t *testing.T) { + testSnapshotWithBootClasspathFragment_Contents(t, ` + sdk { + name: "mysdk", + apexes: ["myapex"], + } + `, copyBootclasspathFragmentFromApexVariantRules) + }) + + t.Run("added-directly-and-indirectly", func(t *testing.T) { + testSnapshotWithBootClasspathFragment_Contents(t, ` + sdk { + name: "mysdk", + apexes: ["myapex"], + // This is not strictly needed as it should be automatically added to the sdk_snapshot as + // a bootclasspath_fragments module because it is used in the myapex's + // bootclasspath_fragments property. However, it is specified here to ensure that duplicates + // are correctly deduped. + bootclasspath_fragments: ["mybootclasspathfragment"], + java_sdk_libs: [ + // This is not strictly needed as it should be automatically added to the sdk_snapshot as + // a java_sdk_libs module because it is used in the mybootclasspathfragment's + // api.stub_libs property. However, it is specified here to ensure that duplicates are + // correctly deduped. + "mysdklibrary", + ], + } + `, copyBootclasspathFragmentFromApexVariantRules) + }) +} + // TestSnapshotWithBootClasspathFragment_Fragments makes sure that the fragments property of a // bootclasspath_fragment is correctly output to the sdk snapshot. func TestSnapshotWithBootClasspathFragment_Fragments(t *testing.T) { diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go index 1c84a7bba..1ac405d7d 100644 --- a/sdk/systemserverclasspath_fragment_sdk_test.go +++ b/sdk/systemserverclasspath_fragment_sdk_test.go @@ -22,7 +22,7 @@ import ( "android/soong/java" ) -func testSnapshotWithSystemServerClasspathFragment(t *testing.T, targetBuildRelease string, expectedSdkSnapshot string) { +func testSnapshotWithSystemServerClasspathFragment(t *testing.T, sdk string, targetBuildRelease string, expectedSdkSnapshot string) { result := android.GroupFixturePreparers( prepareForSdkTestWithJava, java.PrepareForTestWithJavaDefaultModules, @@ -30,23 +30,13 @@ func testSnapshotWithSystemServerClasspathFragment(t *testing.T, targetBuildRele java.FixtureWithLastReleaseApis("mysdklibrary"), dexpreopt.FixtureSetApexSystemServerJars("myapex:mylib", "myapex:mysdklibrary"), android.FixtureModifyEnv(func(env map[string]string) { - env["SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE"] = targetBuildRelease + if targetBuildRelease != "latest" { + env["SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE"] = targetBuildRelease + } }), prepareForSdkTestWithApex, - android.FixtureWithRootAndroidBp(` - sdk { - name: "mysdk", - systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], - java_sdk_libs: [ - // This is not strictly needed as it should be automatically added to the sdk_snapshot as - // a java_sdk_libs module because it is used in the mysystemserverclasspathfragment's - // contents property. However, it is specified here to ensure that duplicates are - // correctly deduped. - "mysdklibrary", - ], - } - + android.FixtureWithRootAndroidBp(sdk+` apex { name: "myapex", key: "myapex.key", @@ -91,8 +81,62 @@ func testSnapshotWithSystemServerClasspathFragment(t *testing.T, targetBuildRele } func TestSnapshotWithSystemServerClasspathFragment(t *testing.T) { + + commonSdk := ` +sdk { + name: "mysdk", + systemserverclasspath_fragments: ["mysystemserverclasspathfragment"], + java_sdk_libs: [ + // This is not strictly needed as it should be automatically added to the sdk_snapshot as + // a java_sdk_libs module because it is used in the mysystemserverclasspathfragment's + // contents property. However, it is specified here to ensure that duplicates are + // correctly deduped. + "mysdklibrary", + ], +} + ` + + expectedLatestSnapshot := ` +// This is auto-generated. DO NOT EDIT. + +java_sdk_library_import { + name: "mysdklibrary", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["myapex"], + shared_library: false, + public: { + jars: ["sdk_library/public/mysdklibrary-stubs.jar"], + stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"], + current_api: "sdk_library/public/mysdklibrary.txt", + removed_api: "sdk_library/public/mysdklibrary-removed.txt", + sdk_version: "current", + }, +} + +java_import { + name: "mylib", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["myapex"], + jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"], + permitted_packages: ["mylib"], +} + +prebuilt_systemserverclasspath_fragment { + name: "mysystemserverclasspathfragment", + prefer: false, + visibility: ["//visibility:public"], + apex_available: ["myapex"], + contents: [ + "mylib", + "mysdklibrary", + ], +} +` + t.Run("target-s", func(t *testing.T) { - testSnapshotWithSystemServerClasspathFragment(t, "S", ` + testSnapshotWithSystemServerClasspathFragment(t, commonSdk, "S", ` // This is auto-generated. DO NOT EDIT. java_sdk_library_import { @@ -113,7 +157,7 @@ java_sdk_library_import { }) t.Run("target-t", func(t *testing.T) { - testSnapshotWithSystemServerClasspathFragment(t, "Tiramisu", ` + testSnapshotWithSystemServerClasspathFragment(t, commonSdk, "Tiramisu", ` // This is auto-generated. DO NOT EDIT. java_sdk_library_import { @@ -152,4 +196,17 @@ prebuilt_systemserverclasspath_fragment { } `) }) + + t.Run("added-directly", func(t *testing.T) { + testSnapshotWithSystemServerClasspathFragment(t, commonSdk, `latest`, expectedLatestSnapshot) + }) + + t.Run("added-via-apex", func(t *testing.T) { + testSnapshotWithSystemServerClasspathFragment(t, ` + sdk { + name: "mysdk", + apexes: ["myapex"], + } + `, `latest`, expectedLatestSnapshot) + }) } diff --git a/sdk/update.go b/sdk/update.go index 8e4f9d4e2..b9ef3d0f4 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -433,6 +433,9 @@ be unnecessary as every module in the sdk already has its own licenses property. traits := s.gatherTraits() for _, member := range members { memberType := member.memberType + if !memberType.ArePrebuiltsRequired() { + continue + } name := member.name requiredTraits := traits[name] @@ -1319,6 +1322,119 @@ func (m multilibUsage) String() string { } } +// TODO(187910671): BEGIN - Remove once modules do not have an APEX and default variant. +// variantCoordinate contains the coordinates used to identify a variant of an SDK member. +type variantCoordinate struct { + // osType identifies the OS target of a variant. + osType android.OsType + // archId identifies the architecture and whether it is for the native bridge. + archId archId + // image is the image variant name. + image string + // linkType is the link type name. + linkType string +} + +func getVariantCoordinate(ctx *memberContext, variant android.Module) variantCoordinate { + linkType := "" + if len(ctx.MemberType().SupportedLinkages()) > 0 { + linkType = getLinkType(variant) + } + return variantCoordinate{ + osType: variant.Target().Os, + archId: archIdFromTarget(variant.Target()), + image: variant.ImageVariation().Variation, + linkType: linkType, + } +} + +// selectApexVariantsWhereAvailable filters the input list of variants by selecting the APEX +// specific variant for a specific variantCoordinate when there is both an APEX and default variant. +// +// There is a long-standing issue where a module that is added to an APEX has both an APEX and +// default/platform variant created even when the module does not require a platform variant. As a +// result an indirect dependency onto a module via the APEX will use the APEX variant, whereas a +// direct dependency onto the module will use the default/platform variant. That would result in a +// failure while attempting to optimize the properties for a member as it would have two variants +// when only one was expected. +// +// This function mitigates that problem by detecting when there are two variants that differ only +// by apex variant, where one is the default/platform variant and one is the APEX variant. In that +// case it picks the APEX variant. It picks the APEX variant because that is the behavior that would +// be expected +func selectApexVariantsWhereAvailable(ctx *memberContext, variants []android.SdkAware) []android.SdkAware { + moduleCtx := ctx.sdkMemberContext + + // Group the variants by coordinates. + variantsByCoord := make(map[variantCoordinate][]android.SdkAware) + for _, variant := range variants { + coord := getVariantCoordinate(ctx, variant) + variantsByCoord[coord] = append(variantsByCoord[coord], variant) + } + + toDiscard := make(map[android.SdkAware]struct{}) + for coord, list := range variantsByCoord { + count := len(list) + if count == 1 { + continue + } + + variantsByApex := make(map[string]android.SdkAware) + conflictDetected := false + for _, variant := range list { + apexInfo := moduleCtx.OtherModuleProvider(variant, android.ApexInfoProvider).(android.ApexInfo) + apexVariationName := apexInfo.ApexVariationName + // If there are two variants for a specific APEX variation then there is conflict. + if _, ok := variantsByApex[apexVariationName]; ok { + conflictDetected = true + break + } + variantsByApex[apexVariationName] = variant + } + + // If there are more than 2 apex variations or one of the apex variations is not the + // default/platform variation then there is a conflict. + if len(variantsByApex) != 2 { + conflictDetected = true + } else if _, ok := variantsByApex[""]; !ok { + conflictDetected = true + } + + // If there are no conflicts then add the default/platform variation to the list to remove. + if !conflictDetected { + toDiscard[variantsByApex[""]] = struct{}{} + continue + } + + // There are duplicate variants at this coordinate and they are not the default and APEX variant + // so fail. + variantDescriptions := []string{} + for _, m := range list { + variantDescriptions = append(variantDescriptions, fmt.Sprintf(" %s", m.String())) + } + + moduleCtx.ModuleErrorf("multiple conflicting variants detected for OsType{%s}, %s, Image{%s}, Link{%s}\n%s", + coord.osType, coord.archId.String(), coord.image, coord.linkType, + strings.Join(variantDescriptions, "\n")) + } + + // If there are any variants to discard then remove them from the list of variants, while + // preserving the order. + if len(toDiscard) > 0 { + filtered := []android.SdkAware{} + for _, variant := range variants { + if _, ok := toDiscard[variant]; !ok { + filtered = append(filtered, variant) + } + } + variants = filtered + } + + return variants +} + +// TODO(187910671): END - Remove once modules do not have an APEX and default variant. + type baseInfo struct { Properties android.SdkMemberProperties } @@ -1374,7 +1490,14 @@ func newOsTypeSpecificInfo(ctx android.SdkMemberContext, osType android.OsType, if commonVariants, ok := variantsByArchId[commonArchId]; ok { if len(osTypeVariants) != 1 { - panic(fmt.Errorf("Expected to only have 1 variant when arch type is common but found %d", len(osTypeVariants))) + variants := []string{} + for _, m := range osTypeVariants { + variants = append(variants, fmt.Sprintf(" %s", m.String())) + } + panic(fmt.Errorf("expected to only have 1 variant of %q when arch type is common but found %d\n%s", + ctx.Name(), + len(osTypeVariants), + strings.Join(variants, "\n"))) } // A common arch type only has one variant and its properties should be treated @@ -1854,7 +1977,8 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu memberType := member.memberType // Do not add the prefer property if the member snapshot module is a source module type. - config := ctx.sdkMemberContext.Config() + moduleCtx := ctx.sdkMemberContext + config := moduleCtx.Config() if !memberType.UsesSourceModuleTypeInSnapshot() { // Set the prefer based on the environment variable. This is a temporary work around to allow a // snapshot to be created that sets prefer: true. @@ -1879,9 +2003,10 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu } } + variants := selectApexVariantsWhereAvailable(ctx, member.variants) + // Group the variants by os type. variantsByOsType := make(map[android.OsType][]android.Module) - variants := member.Variants() for _, variant := range variants { osType := variant.Target().Os variantsByOsType[osType] = append(variantsByOsType[osType], variant) @@ -1927,7 +2052,7 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu } // Extract properties which are common across all architectures and os types. - extractCommonProperties(ctx.sdkMemberContext, commonValueExtractor, commonProperties, osSpecificPropertiesContainers) + extractCommonProperties(moduleCtx, commonValueExtractor, commonProperties, osSpecificPropertiesContainers) // Add the common properties to the module. addSdkMemberPropertiesToSet(ctx, commonProperties, bpModule) diff --git a/ui/build/Android.bp b/ui/build/Android.bp index 3dc87f584..cfcf8047a 100644 --- a/ui/build/Android.bp +++ b/ui/build/Android.bp @@ -34,15 +34,16 @@ bootstrap_go_package { deps: [ "blueprint", "blueprint-bootstrap", + "blueprint-microfactory", + "soong-finder", + "soong-remoteexec", + "soong-shared", "soong-ui-build-paths", "soong-ui-logger", "soong-ui-metrics", "soong-ui-status", "soong-ui-terminal", "soong-ui-tracer", - "soong-shared", - "soong-finder", - "blueprint-microfactory", ], srcs: [ "bazel.go", diff --git a/ui/build/config.go b/ui/build/config.go index 887420904..cbf198641 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -156,10 +156,15 @@ func checkTopDir(ctx Context) { // experiments system to control Soong features dynamically. func fetchEnvConfig(ctx Context, config *configImpl, envConfigName string) error { configName := envConfigName + "." + jsonSuffix - expConfigFetcher := &smpb.ExpConfigFetcher{} + expConfigFetcher := &smpb.ExpConfigFetcher{Filename: &configName} defer func() { ctx.Metrics.ExpConfigFetcher(expConfigFetcher) }() + if !config.GoogleProdCredsExist() { + status := smpb.ExpConfigFetcher_MISSING_GCERT + expConfigFetcher.Status = &status + return nil + } s, err := os.Stat(configFetcher) if err != nil { diff --git a/ui/build/rbe.go b/ui/build/rbe.go index 82fc15f91..6231e5269 100644 --- a/ui/build/rbe.go +++ b/ui/build/rbe.go @@ -21,6 +21,7 @@ import ( "runtime" "strings" + "android/soong/remoteexec" "android/soong/ui/metrics" ) @@ -54,11 +55,12 @@ func rbeCommand(ctx Context, config Config, rbeCmd string) string { func getRBEVars(ctx Context, config Config) map[string]string { vars := map[string]string{ - "RBE_log_dir": config.rbeProxyLogsDir(), - "RBE_re_proxy": config.rbeReproxy(), - "RBE_exec_root": config.rbeExecRoot(), - "RBE_output_dir": config.rbeProxyLogsDir(), + "RBE_log_dir": config.rbeProxyLogsDir(), + "RBE_re_proxy": config.rbeReproxy(), + "RBE_exec_root": config.rbeExecRoot(), + "RBE_output_dir": config.rbeProxyLogsDir(), "RBE_proxy_log_dir": config.rbeProxyLogsDir(), + "RBE_platform": "container-image=" + remoteexec.DefaultImage, } if config.StartRBE() { name, err := config.rbeSockAddr(absPath(ctx, config.TempDir())) diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go index 4bc713b84..2dd829990 100644 --- a/ui/metrics/metrics_proto/metrics.pb.go +++ b/ui/metrics/metrics_proto/metrics.pb.go @@ -220,9 +220,10 @@ func (ModuleTypeInfo_BuildSystem) EnumDescriptor() ([]byte, []int) { type ExpConfigFetcher_ConfigStatus int32 const ( - ExpConfigFetcher_NO_CONFIG ExpConfigFetcher_ConfigStatus = 0 - ExpConfigFetcher_CONFIG ExpConfigFetcher_ConfigStatus = 1 - ExpConfigFetcher_ERROR ExpConfigFetcher_ConfigStatus = 2 + ExpConfigFetcher_NO_CONFIG ExpConfigFetcher_ConfigStatus = 0 + ExpConfigFetcher_CONFIG ExpConfigFetcher_ConfigStatus = 1 + ExpConfigFetcher_ERROR ExpConfigFetcher_ConfigStatus = 2 + ExpConfigFetcher_MISSING_GCERT ExpConfigFetcher_ConfigStatus = 3 ) // Enum value maps for ExpConfigFetcher_ConfigStatus. @@ -231,11 +232,13 @@ var ( 0: "NO_CONFIG", 1: "CONFIG", 2: "ERROR", + 3: "MISSING_GCERT", } ExpConfigFetcher_ConfigStatus_value = map[string]int32{ - "NO_CONFIG": 0, - "CONFIG": 1, - "ERROR": 2, + "NO_CONFIG": 0, + "CONFIG": 1, + "ERROR": 2, + "MISSING_GCERT": 3, } ) @@ -1578,7 +1581,7 @@ var file_metrics_proto_rawDesc = []byte{ 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x5f, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x2e, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0f, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, - 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xc8, 0x01, 0x0a, 0x10, 0x45, 0x78, 0x70, 0x43, 0x6f, 0x6e, 0x66, + 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xdb, 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, @@ -1587,22 +1590,23 @@ var file_metrics_proto_rawDesc = []byte{ 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, + 0x04, 0x52, 0x06, 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x22, 0x47, 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, 0x22, - 0x91, 0x01, 0x0a, 0x0f, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x73, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x3d, 0x0a, 0x1b, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, - 0x6c, 0x64, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x18, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, - 0x75, 0x69, 0x6c, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, - 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x42, - 0x75, 0x69, 0x6c, 0x64, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, 0x64, 0x75, - 0x6c, 0x65, 0x73, 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, + 0x49, 0x47, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, + 0x11, 0x0a, 0x0d, 0x4d, 0x49, 0x53, 0x53, 0x49, 0x4e, 0x47, 0x5f, 0x47, 0x43, 0x45, 0x52, 0x54, + 0x10, 0x03, 0x22, 0x91, 0x01, 0x0a, 0x0f, 0x4d, 0x69, 0x78, 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, + 0x64, 0x73, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3d, 0x0a, 0x1b, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, + 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x18, 0x6d, 0x69, 0x78, + 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x73, 0x12, 0x3f, 0x0a, 0x1c, 0x6d, 0x69, 0x78, 0x65, 0x64, 0x5f, 0x62, + 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x5f, 0x6d, 0x6f, + 0x64, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x09, 0x52, 0x19, 0x6d, 0x69, 0x78, + 0x65, 0x64, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x4d, + 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x28, 0x5a, 0x26, 0x61, 0x6e, 0x64, 0x72, 0x6f, 0x69, + 0x64, 0x2f, 0x73, 0x6f, 0x6f, 0x6e, 0x67, 0x2f, 0x75, 0x69, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, + 0x63, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, } var ( diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto index 51dd523d2..4f8fe7f5c 100644 --- a/ui/metrics/metrics_proto/metrics.proto +++ b/ui/metrics/metrics_proto/metrics.proto @@ -251,6 +251,7 @@ message ExpConfigFetcher { NO_CONFIG = 0; CONFIG = 1; ERROR = 2; + MISSING_GCERT = 3; } // The result of the call to expconfigfetcher // NO_CONFIG - Not part of experiment |