Merge "Implement bp2build for linker_config"
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index b41bd1f..aa4363c 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -37,184 +37,186 @@
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{
@@ -255,6 +257,7 @@
"packages/apps/QuickSearchBox":/* recursive = */ true,
"packages/apps/WallpaperPicker":/* recursive = */ false,
+ "prebuilts/bazel":/* recursive = */ true,
"prebuilts/bundletool":/* recursive = */ true,
"prebuilts/gcc":/* recursive = */ true,
"prebuilts/build-tools":/* recursive = */ true,
diff --git a/android/androidmk.go b/android/androidmk.go
index 832c7df..d6fe06d 100644
--- a/android/androidmk.go
+++ b/android/androidmk.go
@@ -605,7 +605,7 @@
}
if len(base.noticeFiles) > 0 {
- a.SetString("LOCAL_NOTICE_FILE", strings.Join(base.noticeFiles.Strings(), " "))
+ a.AddStrings("LOCAL_NOTICE_FILE", strings.Join(base.noticeFiles.Strings(), " "))
}
if host {
diff --git a/android/arch.go b/android/arch.go
index e72614c..6acc8ad 100644
--- a/android/arch.go
+++ b/android/arch.go
@@ -655,7 +655,8 @@
prefer32 := os == Windows
// Determine the multilib selection for this module.
- multilib, extraMultilib := decodeMultilib(base, os)
+ ignorePrefer32OnDevice := mctx.Config().IgnorePrefer32OnDevice()
+ multilib, extraMultilib := decodeMultilib(base, os, ignorePrefer32OnDevice)
// Convert the multilib selection into a list of Targets.
targets, err := decodeMultilibTargets(multilib, osTargets, prefer32)
@@ -730,7 +731,7 @@
// multilib from the factory's call to InitAndroidArchModule if none was set. For modules that
// called InitAndroidMultiTargetsArchModule it always returns "common" for multilib, and returns
// the actual multilib in extraMultilib.
-func decodeMultilib(base *ModuleBase, os OsType) (multilib, extraMultilib string) {
+func decodeMultilib(base *ModuleBase, os OsType, ignorePrefer32OnDevice bool) (multilib, extraMultilib string) {
// First check the "android.compile_multilib" or "host.compile_multilib" properties.
switch os.Class {
case Device:
@@ -749,6 +750,13 @@
multilib = base.commonProperties.Default_multilib
}
+ // If a device is configured with multiple targets, this option
+ // force all device targets that prefer32 to be compiled only as
+ // the first target.
+ if ignorePrefer32OnDevice && os.Class == Device && (multilib == "prefer32" || multilib == "first_prefer32") {
+ multilib = "first"
+ }
+
if base.commonProperties.UseTargetVariants {
// Darwin has the concept of "universal binaries" which is implemented in Soong by
// building both x86_64 and arm64 variants, and having select module types know how to
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 3be9805..5e8a183 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -399,12 +399,6 @@
func (r *builtinBazelRunner) issueBazelCommand(paths *bazelPaths, runName bazel.RunName, command bazelCommand,
extraFlags ...string) (string, string, error) {
cmdFlags := []string{
- // --noautodetect_server_javabase has the practical consequence of preventing Bazel from
- // attempting to download rules_java, which is incompatible with
- // --experimental_repository_disable_download set further below.
- // rules_java is also not needed until mixed builds start building java targets.
- // TODO(b/197958133): Once rules_java is pulled into AOSP, remove this flag.
- "--noautodetect_server_javabase",
"--output_base=" + absolutePath(paths.outputBase),
command.command,
}
diff --git a/android/config.go b/android/config.go
index 47346fc..a5337d0 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1725,6 +1725,10 @@
return c.config.productVariables.GenerateAidlNdkPlatformBackend
}
+func (c *config) IgnorePrefer32OnDevice() bool {
+ return c.productVariables.IgnorePrefer32OnDevice
+}
+
// The ConfiguredJarList struct provides methods for handling a list of (apex, jar) pairs.
// Such lists are used in the build system for things like bootclasspath jars or system server jars.
// The apex part is either an apex name, or a special names "platform" or "system_ext". Jar is a
diff --git a/android/metrics.go b/android/metrics.go
index 1580f82..ecda026 100644
--- a/android/metrics.go
+++ b/android/metrics.go
@@ -32,8 +32,13 @@
Variants int
}
-func ReadSoongMetrics(config Config) SoongMetrics {
- return config.Get(soongMetricsOnceKey).(SoongMetrics)
+func readSoongMetrics(config Config) (SoongMetrics, bool) {
+ soongMetrics, ok := config.Peek(soongMetricsOnceKey)
+ if ok {
+ return soongMetrics.(SoongMetrics), true
+ } else {
+ return SoongMetrics{}, false
+ }
}
func init() {
@@ -60,9 +65,11 @@
func collectMetrics(config Config, eventHandler metrics.EventHandler) *soong_metrics_proto.SoongBuildMetrics {
metrics := &soong_metrics_proto.SoongBuildMetrics{}
- soongMetrics := ReadSoongMetrics(config)
- metrics.Modules = proto.Uint32(uint32(soongMetrics.Modules))
- metrics.Variants = proto.Uint32(uint32(soongMetrics.Variants))
+ soongMetrics, ok := readSoongMetrics(config)
+ if ok {
+ metrics.Modules = proto.Uint32(uint32(soongMetrics.Modules))
+ metrics.Variants = proto.Uint32(uint32(soongMetrics.Variants))
+ }
memStats := runtime.MemStats{}
runtime.ReadMemStats(&memStats)
diff --git a/android/module.go b/android/module.go
index 2925081..7173c0d 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2328,14 +2328,6 @@
}
if optPath.Valid() {
m.noticeFiles = append(m.noticeFiles, optPath.Path())
- } else {
- for _, notice = range []string{"LICENSE", "LICENCE", "NOTICE"} {
- noticePath := filepath.Join(ctx.ModuleDir(), notice)
- optPath = ExistentPathForSource(ctx, noticePath)
- if optPath.Valid() {
- m.noticeFiles = append(m.noticeFiles, optPath.Path())
- }
- }
}
licensesPropertyFlattener(ctx)
diff --git a/android/neverallow.go b/android/neverallow.go
index aa47bca..357cae5 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -58,6 +58,7 @@
AddNeverAllowRules(createMakefileGoalRules()...)
AddNeverAllowRules(createInitFirstStageRules()...)
AddNeverAllowRules(createProhibitFrameworkAccessRules()...)
+ AddNeverAllowRules(createNoticeDeprecationRules()...)
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -238,6 +239,15 @@
}
}
+func createNoticeDeprecationRules() []Rule {
+ return []Rule{
+ NeverAllow().
+ WithMatcher("notice", isSetMatcherInstance).
+ NotIn("vendor/linaro/linux-firmware/").
+ Because("notice has been replaced by licenses/default_applicable_licenses"),
+ }
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
diff --git a/android/onceper.go b/android/onceper.go
index 481cdea..fa415d1 100644
--- a/android/onceper.go
+++ b/android/onceper.go
@@ -79,6 +79,17 @@
return once.maybeWaitFor(key, v)
}
+// Peek returns the value previously computed with Once for a given key. If Once has not
+// been called for the given key Peek will return ok == false.
+func (once *OncePer) Peek(key OnceKey) (interface{}, bool) {
+ v, ok := once.values.Load(key)
+ if !ok {
+ return nil, false
+ }
+
+ return once.maybeWaitFor(key, v), true
+}
+
// OnceStringSlice is the same as Once, but returns the value cast to a []string
func (once *OncePer) OnceStringSlice(key OnceKey, value func() []string) []string {
return once.Once(key, func() interface{} { return value() }).([]string)
diff --git a/android/paths.go b/android/paths.go
index d5cec9a..f8e7018 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -1474,7 +1474,7 @@
// PathForVndkRefAbiDump returns an OptionalPath representing the path of the
// reference abi dump for the given module. This is not guaranteed to be valid.
func PathForVndkRefAbiDump(ctx ModuleInstallPathContext, version, fileName string,
- isNdk, isLlndkOrVndk, isGzip bool) OptionalPath {
+ isNdk, isVndk, isGzip bool) OptionalPath {
currentArchType := ctx.Arch().ArchType
primaryArchType := ctx.Config().DevicePrimaryArchType()
@@ -1486,7 +1486,7 @@
var dirName string
if isNdk {
dirName = "ndk"
- } else if isLlndkOrVndk {
+ } else if isVndk {
dirName = "vndk"
} else {
dirName = "platform" // opt-in libs
diff --git a/android/sdk.go b/android/sdk.go
index 07b94b2..a71f7f2 100644
--- a/android/sdk.go
+++ b/android/sdk.go
@@ -985,6 +985,10 @@
// RequiresTrait returns true if this member is expected to provide the specified trait.
RequiresTrait(trait SdkMemberTrait) bool
+
+ // IsTargetBuildBeforeTiramisu return true if the target build release for which this snapshot is
+ // being generated is before Tiramisu, i.e. S.
+ IsTargetBuildBeforeTiramisu() bool
}
// ExportedComponentsInfo contains information about the components that this module exports to an
diff --git a/android/sdk_version.go b/android/sdk_version.go
index 2004c92..c188c48 100644
--- a/android/sdk_version.go
+++ b/android/sdk_version.go
@@ -28,6 +28,9 @@
// 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/android/variable.go b/android/variable.go
index 50fc304..874b69d 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -447,6 +447,8 @@
SepolicyFreezeTestExtraPrebuiltDirs []string `json:",omitempty"`
GenerateAidlNdkPlatformBackend bool `json:",omitempty"`
+
+ IgnorePrefer32OnDevice bool `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 7b6707c..6313d20 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -639,7 +639,7 @@
fsTag = &dependencyTag{name: "filesystem", payload: 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}
+ compatConfigTag = &dependencyTag{name: "compatConfig", payload: true, sourceOnly: true, memberType: java.CompatConfigSdkMemberType}
javaLibTag = &dependencyTag{name: "javaLib", payload: true}
jniLibTag = &dependencyTag{name: "jniLib", payload: true}
keyTag = &dependencyTag{name: "key"}
diff --git a/apex/apex_test.go b/apex/apex_test.go
index dbe9180..69205f8 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -619,7 +619,7 @@
java_libs: ["myjar"],
apps: ["AppFoo"],
rros: ["rro"],
- bpfs: ["bpf", "netd_test"],
+ bpfs: ["bpf", "netdTest"],
updatable: false,
}
@@ -673,8 +673,8 @@
}
bpf {
- name: "netd_test",
- srcs: ["netd_test.c"],
+ name: "netdTest",
+ srcs: ["netdTest.c"],
sub_dir: "netd",
}
@@ -687,7 +687,7 @@
"overlay/blue/rro.apk",
"etc/bpf/bpf.o",
"etc/bpf/bpf2.o",
- "etc/bpf/netd/netd_test.o",
+ "etc/bpf/netd/netdTest.o",
})
}
@@ -949,8 +949,10 @@
// mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
// ensureNotContains(t, mylib2Cflags, "-include ")
- // Ensure that genstub is invoked with --apex
- ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"])
+ // Ensure that genstub for platform-provided lib is invoked with --systemapi
+ ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_3").Rule("genStubSrc").Args["flags"], "--systemapi")
+ // Ensure that genstub for apex-provided lib is invoked with --apex
+ ensureContains(t, ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_shared_12").Rule("genStubSrc").Args["flags"], "--apex")
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"lib64/mylib.so",
@@ -1134,8 +1136,8 @@
mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("cc").Args["cFlags"]
ensureNotContains(t, mylib2Cflags, "-include ")
- // Ensure that genstub is invoked with --apex
- ensureContains(t, "--apex", ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"])
+ // Ensure that genstub is invoked with --systemapi
+ ensureContains(t, ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_shared_29").Rule("genStubSrc").Args["flags"], "--systemapi")
ensureExactContents(t, ctx, "myapex", "android_common_myapex_image", []string{
"lib64/mylib.so",
@@ -6151,7 +6153,7 @@
name: "override_myapex",
base: "myapex",
apps: ["override_app"],
- bpfs: ["override_bpf"],
+ bpfs: ["overrideBpf"],
prebuilts: ["override_myetc"],
bootclasspath_fragments: ["override_bootclasspath_fragment"],
systemserverclasspath_fragments: ["override_systemserverclasspath_fragment"],
@@ -6201,8 +6203,8 @@
}
bpf {
- name: "override_bpf",
- srcs: ["override_bpf.c"],
+ name: "overrideBpf",
+ srcs: ["overrideBpf.c"],
}
prebuilt_etc {
@@ -6305,7 +6307,7 @@
ensureContains(t, copyCmds, "image.apex/app/override_app@TEST.BUILD_ID/override_app.apk")
ensureNotContains(t, copyCmds, "image.apex/etc/bpf/bpf.o")
- ensureContains(t, copyCmds, "image.apex/etc/bpf/override_bpf.o")
+ ensureContains(t, copyCmds, "image.apex/etc/bpf/overrideBpf.o")
ensureNotContains(t, copyCmds, "image.apex/etc/myetc")
ensureContains(t, copyCmds, "image.apex/etc/override_myetc")
@@ -6339,7 +6341,7 @@
data.Custom(&builder, name, "TARGET_", "", data)
androidMk := builder.String()
ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex")
- ensureContains(t, androidMk, "LOCAL_MODULE := override_bpf.o.override_myapex")
+ ensureContains(t, androidMk, "LOCAL_MODULE := overrideBpf.o.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE := override_bcplib.override_myapex")
ensureContains(t, androidMk, "LOCAL_MODULE := override_systemserverlib.override_myapex")
diff --git a/apex/builder.go b/apex/builder.go
index e3c4476..1956b44 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -76,16 +76,12 @@
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 @@
`--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 @@
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 @@
`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 @@
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 @@
"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 @@
"image_dir": imageDir.String(),
"copy_commands": strings.Join(copyCommands, " && "),
"manifest": a.manifestPbOut.String(),
- "apex_version": defaultManifestVersion,
},
})
}
diff --git a/bp2build/bp2build.go b/bp2build/bp2build.go
index b0c3899..5bff956 100644
--- a/bp2build/bp2build.go
+++ b/bp2build/bp2build.go
@@ -40,7 +40,7 @@
fmt.Printf("ERROR: Encountered %d error(s): \nERROR: %s", len(errs), strings.Join(errMsgs, "\n"))
os.Exit(1)
}
- bp2buildFiles := CreateBazelFiles(nil, res.buildFileToTargets, ctx.mode)
+ bp2buildFiles := CreateBazelFiles(ctx.Config(), nil, res.buildFileToTargets, ctx.mode)
writeFiles(ctx, bp2buildDir, bp2buildFiles)
soongInjectionDir := android.PathForOutput(ctx, bazel.SoongInjectionDirName)
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index f3345a6..6cb9509 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -189,7 +189,7 @@
content: "irrelevant",
},
}
- files := CreateBazelFiles(ruleShims, make(map[string]BazelTargets), QueryView)
+ files := CreateBazelFiles(android.NullConfig("out", "out/soong"), ruleShims, make(map[string]BazelTargets), QueryView)
var actualSoongModuleBzl BazelFile
for _, f := range files {
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index be09616..74729e4 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -569,3 +569,58 @@
},
})
}
+
+func TestCcLibrarySharedClangUnknownFlags(t *testing.T) {
+ runCcLibrarySharedTestCase(t, bp2buildTestCase{
+ blueprint: soongCcProtoPreamble + `cc_library_shared {
+ name: "foo",
+ conlyflags: ["-a", "-finline-functions"],
+ cflags: ["-b","-finline-functions"],
+ cppflags: ["-c", "-finline-functions"],
+ ldflags: ["-d","-finline-functions", "-e"],
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "conlyflags": `["-a"]`,
+ "copts": `["-b"]`,
+ "cppflags": `["-c"]`,
+ "linkopts": `[
+ "-d",
+ "-e",
+ ]`,
+ }),
+ },
+ })
+}
+
+func TestCCLibraryFlagSpaceSplitting(t *testing.T) {
+ runCcLibrarySharedTestCase(t, bp2buildTestCase{
+ blueprint: soongCcProtoPreamble + `cc_library_shared {
+ name: "foo",
+ conlyflags: [ "-include header.h"],
+ cflags: ["-include header.h"],
+ cppflags: ["-include header.h"],
+ version_script: "version_script",
+ include_build_directory: false,
+}`,
+ expectedBazelTargets: []string{
+ makeBazelTarget("cc_library_shared", "foo", attrNameToString{
+ "additional_linker_inputs": `["version_script"]`,
+ "conlyflags": `[
+ "-include",
+ "header.h",
+ ]`,
+ "copts": `[
+ "-include",
+ "header.h",
+ ]`,
+ "cppflags": `[
+ "-include",
+ "header.h",
+ ]`,
+ "linkopts": `["-Wl,--version-script,$(location version_script)"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/conversion.go b/bp2build/conversion.go
index 4b013d9..4246f7d 100644
--- a/bp2build/conversion.go
+++ b/bp2build/conversion.go
@@ -50,6 +50,7 @@
}
func CreateBazelFiles(
+ cfg android.Config,
ruleShims map[string]RuleShim,
buildToTargets map[string]BazelTargets,
mode CodegenMode) []BazelFile {
@@ -74,16 +75,19 @@
files = append(files, newFile(bazelRulesSubDir, "soong_module.bzl", generateSoongModuleBzl(ruleShims)))
}
- files = append(files, createBuildFiles(buildToTargets, mode)...)
+ files = append(files, createBuildFiles(cfg, buildToTargets, mode)...)
return files
}
-func createBuildFiles(buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
+func createBuildFiles(cfg android.Config, buildToTargets map[string]BazelTargets, mode CodegenMode) []BazelFile {
files := make([]BazelFile, 0, len(buildToTargets))
+ warnNotWriting := cfg.IsEnvTrue("BP2BUILD_VERBOSE")
for _, dir := range android.SortedStringKeys(buildToTargets) {
if mode == Bp2Build && android.ShouldKeepExistingBuildFileForDir(dir) {
- fmt.Printf("[bp2build] Not writing generated BUILD file for dir: '%s'\n", dir)
+ if warnNotWriting {
+ fmt.Printf("[bp2build] Not writing generated BUILD file for dir: '%s'\n", dir)
+ }
continue
}
targets := buildToTargets[dir]
diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go
index e49d855..b0d0740 100644
--- a/bp2build/conversion_test.go
+++ b/bp2build/conversion_test.go
@@ -27,7 +27,8 @@
}
func TestCreateBazelFiles_QueryView_AddsTopLevelFiles(t *testing.T) {
- files := CreateBazelFiles(map[string]RuleShim{}, map[string]BazelTargets{}, QueryView)
+ files := CreateBazelFiles(android.NullConfig("out", "out/soong"),
+ map[string]RuleShim{}, map[string]BazelTargets{}, QueryView)
expectedFilePaths := []bazelFilepath{
{
dir: "",
diff --git a/bp2build/metrics.go b/bp2build/metrics.go
index 04fac44..3a21c34 100644
--- a/bp2build/metrics.go
+++ b/bp2build/metrics.go
@@ -116,8 +116,6 @@
}
if _, err := os.Stat(metricsFile); err != nil {
fail(err, "MISSING BP2BUILD METRICS OUTPUT: Failed to `stat` %s", metricsFile)
- } else {
- fmt.Printf("\nWrote bp2build metrics to: %s\n", metricsFile)
}
}
diff --git a/bp2build/symlink_forest.go b/bp2build/symlink_forest.go
index 818d7ae..c5075e5 100644
--- a/bp2build/symlink_forest.go
+++ b/bp2build/symlink_forest.go
@@ -1,6 +1,7 @@
package bp2build
import (
+ "android/soong/android"
"fmt"
"io/ioutil"
"os"
@@ -114,7 +115,7 @@
// contain every file in buildFilesDir and srcDir excluding the files in
// exclude. Collects every directory encountered during the traversal of srcDir
// into acc.
-func plantSymlinkForestRecursive(topdir string, forestDir string, buildFilesDir string, srcDir string, exclude *node, acc *[]string, okay *bool) {
+func plantSymlinkForestRecursive(cfg android.Config, topdir string, forestDir string, buildFilesDir string, srcDir string, exclude *node, acc *[]string, okay *bool) {
if exclude != nil && exclude.excluded {
// This directory is not needed, bail out
return
@@ -179,7 +180,7 @@
if bDir && excludeChild != nil {
// Not in the source tree, but we have to exclude something from under
// this subtree, so descend
- plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
+ plantSymlinkForestRecursive(cfg, topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
} else {
// Not in the source tree, symlink BUILD file
symlinkIntoForest(topdir, forestChild, buildFilesChild)
@@ -188,19 +189,21 @@
if sDir && excludeChild != nil {
// Not in the build file tree, but we have to exclude something from
// under this subtree, so descend
- plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
+ plantSymlinkForestRecursive(cfg, topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
} else {
// Not in the build file tree, symlink source tree, carry on
symlinkIntoForest(topdir, forestChild, srcChild)
}
} else if sDir && bDir {
// Both are directories. Descend.
- plantSymlinkForestRecursive(topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
+ plantSymlinkForestRecursive(cfg, topdir, forestChild, buildFilesChild, srcChild, excludeChild, acc, okay)
} else if !sDir && !bDir {
// Neither is a directory. Prioritize BUILD files generated by bp2build
// over any BUILD file imported into external/.
- fmt.Fprintf(os.Stderr, "Both '%s' and '%s' exist, symlinking the former to '%s'\n",
- buildFilesChild, srcChild, forestChild)
+ if cfg.IsEnvTrue("BP2BUILD_VERBOSE") {
+ fmt.Fprintf(os.Stderr, "Both '%s' and '%s' exist, symlinking the former to '%s'\n",
+ buildFilesChild, srcChild, forestChild)
+ }
symlinkIntoForest(topdir, forestChild, buildFilesChild)
} else {
// Both exist and one is a file. This is an error.
@@ -216,12 +219,12 @@
// "srcDir" while excluding paths listed in "exclude". Returns the set of paths
// under srcDir on which readdir() had to be called to produce the symlink
// forest.
-func PlantSymlinkForest(topdir string, forest string, buildFiles string, srcDir string, exclude []string) []string {
+func PlantSymlinkForest(cfg android.Config, topdir string, forest string, buildFiles string, srcDir string, exclude []string) []string {
deps := make([]string, 0)
os.RemoveAll(shared.JoinPath(topdir, forest))
excludeTree := treeFromExcludePathList(exclude)
okay := true
- plantSymlinkForestRecursive(topdir, forest, buildFiles, srcDir, excludeTree, &deps, &okay)
+ plantSymlinkForestRecursive(cfg, topdir, forest, buildFiles, srcDir, excludeTree, &deps, &okay)
if !okay {
os.Exit(1)
}
diff --git a/bpf/bpf.go b/bpf/bpf.go
index 14b2d84..5d2533f 100644
--- a/bpf/bpf.go
+++ b/bpf/bpf.go
@@ -17,6 +17,7 @@
import (
"fmt"
"io"
+ "path/filepath"
"strings"
"android/soong/android"
@@ -154,6 +155,9 @@
srcs := android.PathsForModuleSrc(ctx, bpf.properties.Srcs)
for _, src := range srcs {
+ if strings.ContainsRune(filepath.Base(src.String()), '_') {
+ ctx.ModuleErrorf("invalid character '_' in source name")
+ }
obj := android.ObjPathWithExt(ctx, "unstripped", src, "o")
ctx.Build(pctx, android.BuildParams{
diff --git a/bpf/bpf_test.go b/bpf/bpf_test.go
index 51fbc15..6e39096 100644
--- a/bpf/bpf_test.go
+++ b/bpf/bpf_test.go
@@ -30,8 +30,9 @@
cc.PrepareForTestWithCcDefaultModules,
android.FixtureMergeMockFs(
map[string][]byte{
- "bpf.c": nil,
- "BpfTest.cpp": nil,
+ "bpf.c": nil,
+ "bpf_invalid_name.c": nil,
+ "BpfTest.cpp": nil,
},
),
PrepareForTestWithBpf,
@@ -58,3 +59,15 @@
// value is not available for testing from this package.
// TODO(jungjw): Add a check for data or move this test to the cc package.
}
+
+func TestBpfSourceName(t *testing.T) {
+ bp := `
+ bpf {
+ name: "bpf_invalid_name.o",
+ srcs: ["bpf_invalid_name.c"],
+ }
+ `
+ prepareForBpfTest.ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(
+ `\QAndroid.bp:2:3: module "bpf_invalid_name.o" variant "android_common": invalid character '_' in source name\E`)).
+ RunTestWithBp(t, bp)
+}
diff --git a/cc/bp2build.go b/cc/bp2build.go
index fa30d09..6cd6733 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -20,6 +20,7 @@
"android/soong/android"
"android/soong/bazel"
+ "android/soong/cc/config"
"github.com/google/blueprint"
@@ -156,7 +157,7 @@
attrs := staticOrSharedAttributes{}
setAttrs := func(axis bazel.ConfigurationAxis, config string, props StaticOrSharedProperties) {
- attrs.Copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag))
+ attrs.Copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, true, filterOutStdFlag))
attrs.Srcs.SetSelectValue(axis, config, android.BazelLabelForModuleSrc(ctx, props.Srcs))
attrs.System_dynamic_deps.SetSelectValue(axis, config, bazelLabelForSharedDeps(ctx, props.System_shared_libs))
@@ -326,16 +327,39 @@
return strings.HasPrefix(flag, "-std=")
}
-func parseCommandLineFlags(soongFlags []string, filterOut filterOutFn) []string {
+func filterOutClangUnknownCflags(flag string) bool {
+ for _, f := range config.ClangUnknownCflags {
+ if f == flag {
+ return true
+ }
+ }
+ return false
+}
+
+func parseCommandLineFlags(soongFlags []string, noCoptsTokenization bool, filterOut ...filterOutFn) []string {
var result []string
for _, flag := range soongFlags {
- if filterOut != nil && filterOut(flag) {
+ skipFlag := false
+ for _, filter := range filterOut {
+ if filter != nil && filter(flag) {
+ skipFlag = true
+ }
+ }
+ if skipFlag {
continue
}
// Soong's cflags can contain spaces, like `-include header.h`. For
// Bazel's copts, split them up to be compatible with the
// no_copts_tokenization feature.
- result = append(result, strings.Split(flag, " ")...)
+ if noCoptsTokenization {
+ result = append(result, strings.Split(flag, " ")...)
+ } else {
+ // Soong's Version Script and Dynamic List Properties are added as flags
+ // to Bazel's linkopts using "($location label)" syntax.
+ // Splitting on spaces would separate this into two different flags
+ // "($ location" and "label)"
+ result = append(result, flag)
+ }
}
return result
}
@@ -362,10 +386,10 @@
// overridden. In Bazel we always allow overriding, via flags; however, this can cause
// incompatibilities, so we remove "-std=" flags from Cflag properties while leaving it in other
// cases.
- ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, filterOutStdFlag))
- ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags, nil))
- ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags, nil))
- ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags, nil))
+ ca.copts.SetSelectValue(axis, config, parseCommandLineFlags(props.Cflags, true, filterOutStdFlag, filterOutClangUnknownCflags))
+ ca.asFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Asflags, true, nil))
+ ca.conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Conlyflags, true, filterOutClangUnknownCflags))
+ ca.cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(props.Cppflags, true, filterOutClangUnknownCflags))
ca.rtti.SetSelectValue(axis, config, props.Rtti)
}
@@ -721,7 +745,7 @@
linkerFlags = append(linkerFlags, fmt.Sprintf("-Wl,--dynamic-list,$(location %s)", label.Label))
}
- la.linkopts.SetSelectValue(axis, config, linkerFlags)
+ la.linkopts.SetSelectValue(axis, config, parseCommandLineFlags(linkerFlags, false, filterOutClangUnknownCflags))
la.useLibcrt.SetSelectValue(axis, config, props.libCrt())
if axis == bazel.NoConfigAxis {
diff --git a/cc/builder.go b/cc/builder.go
index 70bbd6a..ab2b80a 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -63,10 +63,10 @@
ld, ldRE = pctx.RemoteStaticRules("ld",
blueprint.RuleParams{
Command: "$reTemplate$ldCmd ${crtBegin} @${out}.rsp " +
- "${libFlags} ${crtEnd} -o ${out} ${ldFlags} ${extraLibFlags}",
+ "${crtEnd} -o ${out} ${ldFlags} ${extraLibFlags}",
CommandDeps: []string{"$ldCmd"},
Rspfile: "${out}.rsp",
- RspfileContent: "${in}",
+ RspfileContent: "${in} ${libFlags}",
// clang -Wl,--out-implib doesn't update its output file if it hasn't changed.
Restat: true,
},
diff --git a/cc/cc.go b/cc/cc.go
index f04b6f0..bc95813 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -61,6 +61,9 @@
ctx.TopDown("sanitize_runtime_deps", sanitizerRuntimeDepsMutator).Parallel()
ctx.BottomUp("sanitize_runtime", sanitizerRuntimeMutator).Parallel()
+ ctx.TopDown("fuzz_deps", fuzzMutatorDeps)
+ ctx.BottomUp("fuzz", fuzzMutator)
+
ctx.BottomUp("coverage", coverageMutator).Parallel()
ctx.TopDown("afdo_deps", afdoDepsMutator)
@@ -838,6 +841,7 @@
stl *stl
sanitize *sanitize
coverage *coverage
+ fuzzer *fuzzer
sabi *sabi
vndkdep *vndkdep
lto *lto
@@ -1163,6 +1167,9 @@
if c.coverage != nil {
c.AddProperties(c.coverage.props()...)
}
+ if c.fuzzer != nil {
+ c.AddProperties(c.fuzzer.props()...)
+ }
if c.sabi != nil {
c.AddProperties(c.sabi.props()...)
}
@@ -1680,6 +1687,7 @@
module.stl = &stl{}
module.sanitize = &sanitize{}
module.coverage = &coverage{}
+ module.fuzzer = &fuzzer{}
module.sabi = &sabi{}
module.vndkdep = &vndkdep{}
module.lto = <o{}
@@ -1901,6 +1909,9 @@
if c.coverage != nil {
flags, deps = c.coverage.flags(ctx, flags, deps)
}
+ if c.fuzzer != nil {
+ flags = c.fuzzer.flags(ctx, flags)
+ }
if c.lto != nil {
flags = c.lto.flags(ctx, flags)
}
diff --git a/cc/cc_test.go b/cc/cc_test.go
index b6d196c..24732bf 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -3342,6 +3342,125 @@
`)
}
+func TestAFLFuzzTarget(t *testing.T) {
+ ctx := testCc(t, `
+ cc_afl_fuzz {
+ name: "test_afl_fuzz_target",
+ srcs: ["foo.c"],
+ host_supported: true,
+ static_libs: [
+ "afl_fuzz_static_lib",
+ ],
+ shared_libs: [
+ "afl_fuzz_shared_lib",
+ ],
+ }
+ cc_fuzz {
+ name: "test_fuzz_target",
+ srcs: ["foo.c"],
+ static_libs: [
+ "afl_fuzz_static_lib",
+ "libfuzzer_only_static_lib",
+ ],
+ shared_libs: [
+ "afl_fuzz_shared_lib",
+ ],
+ }
+ cc_library {
+ name: "afl_fuzz_static_lib",
+ host_supported: true,
+ srcs: ["static_file.c"],
+ }
+ cc_library {
+ name: "libfuzzer_only_static_lib",
+ host_supported: true,
+ srcs: ["static_file.c"],
+ }
+ cc_library {
+ name: "afl_fuzz_shared_lib",
+ host_supported: true,
+ srcs: ["shared_file.c"],
+ static_libs: [
+ "second_static_lib",
+ ],
+ }
+ cc_library_headers {
+ name: "libafl_headers",
+ vendor_available: true,
+ host_supported: true,
+ export_include_dirs: [
+ "include",
+ "instrumentation",
+ ],
+ }
+ cc_object {
+ name: "afl-compiler-rt",
+ vendor_available: true,
+ host_supported: true,
+ cflags: [
+ "-fPIC",
+ ],
+ srcs: [
+ "instrumentation/afl-compiler-rt.o.c",
+ ],
+ }
+ cc_library {
+ name: "second_static_lib",
+ host_supported: true,
+ srcs: ["second_file.c"],
+ }
+ filegroup {
+ name: "aflpp_driver",
+ srcs: [
+ "aflpp_driver.c",
+ ],
+ }`)
+
+ checkPcGuardFlag := func(
+ modName string, variantName string, shouldHave bool) {
+ cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
+
+ cFlags, ok := cc.Args["cFlags"]
+ if !ok {
+ t.Errorf("Could not find cFlags for module %s and variant %s",
+ modName, variantName)
+ }
+
+ if strings.Contains(
+ cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
+ t.Errorf("Flag was found: %t. Expected to find flag: %t. "+
+ "Test failed for module %s and variant %s",
+ !shouldHave, shouldHave, modName, variantName)
+ }
+ }
+
+ for _, vnt := range ctx.ModuleVariantsForTests("libfuzzer_only_static_lib") {
+ if strings.Contains(vnt, "fuzzer_afl") {
+ t.Errorf("libfuzzer_only_static_lib has afl variant and should not")
+ }
+ }
+
+ moduleName := "test_afl_fuzz_target"
+ variantName := "android_arm64_armv8-a_fuzzer_afl"
+ checkPcGuardFlag(moduleName, variantName, true)
+
+ moduleName = "afl_fuzz_static_lib"
+ variantName = "android_arm64_armv8-a_static"
+ checkPcGuardFlag(moduleName, variantName, false)
+ checkPcGuardFlag(moduleName, variantName+"_fuzzer", false)
+ checkPcGuardFlag(moduleName, variantName+"_fuzzer_afl", true)
+
+ moduleName = "second_static_lib"
+ checkPcGuardFlag(moduleName, variantName, false)
+ checkPcGuardFlag(moduleName, variantName+"_fuzzer", false)
+ checkPcGuardFlag(moduleName, variantName+"_fuzzer_afl", true)
+
+ ctx.ModuleForTests("afl_fuzz_shared_lib",
+ "android_arm64_armv8-a_shared").Rule("cc")
+ ctx.ModuleForTests("afl_fuzz_shared_lib",
+ "android_arm64_armv8-a_shared_fuzzer_afl").Rule("cc")
+}
+
// Simple smoke test for the cc_fuzz target that ensures the rule compiles
// correctly.
func TestFuzzTarget(t *testing.T) {
diff --git a/cc/config/global.go b/cc/config/global.go
index c5fde55..26d93ab 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -228,7 +228,6 @@
// New warnings to be fixed after clang-r383902.
"-Wno-deprecated-copy", // http://b/153746672
"-Wno-range-loop-construct", // http://b/153747076
- "-Wno-misleading-indentation", // http://b/153746954
"-Wno-zero-as-null-pointer-constant", // http://b/68236239
"-Wno-deprecated-anon-enum-enum-conversion", // http://b/153746485
"-Wno-pessimizing-move", // http://b/154270751
@@ -239,6 +238,8 @@
// New warnings to be fixed after clang-r433403
"-Wno-error=unused-but-set-variable", // http://b/197240255
"-Wno-error=unused-but-set-parameter", // http://b/197240255
+ // New warnings to be fixed after clang-r458507
+ "-Wno-error=unqualified-std-cast-call", // http://b/239662094
}
noOverrideExternalGlobalCflags = []string{
@@ -247,6 +248,8 @@
"-Wno-unused-but-set-parameter",
// http://b/215753485
"-Wno-bitwise-instead-of-logical",
+ // http://b/232926688
+ "-Wno-misleading-indentation",
}
// Extra cflags for external third-party projects to disable warnings that
@@ -278,6 +281,12 @@
// http://b/175068488
"-Wno-string-concatenation",
+
+ // http://b/239661264
+ "-Wno-deprecated-non-prototype",
+ }
+
+ llvmNextExtraCommonGlobalCflags = []string{
}
IllegalFlags = []string{
@@ -291,8 +300,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r450784e"
- ClangDefaultShortVersion = "14.0.7"
+ ClangDefaultVersion = "clang-r458507"
+ ClangDefaultShortVersion = "15.0.1"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
@@ -361,6 +370,15 @@
if ctx.Config().IsEnvTrue("USE_CCACHE") {
flags = append(flags, "-Wno-unused-command-line-argument")
}
+
+ if ctx.Config().IsEnvTrue("LLVM_NEXT") {
+ flags = append(flags, llvmNextExtraCommonGlobalCflags...)
+ }
+
+ if ctx.Config().IsEnvTrue("ALLOW_UNKNOWN_WARNING_OPTION") {
+ flags = append(flags, "-Wno-error=unknown-warning-option")
+ }
+
return strings.Join(flags, " ")
})
diff --git a/cc/fuzz.go b/cc/fuzz.go
index 23d81d6..d6af97f 100644
--- a/cc/fuzz.go
+++ b/cc/fuzz.go
@@ -27,29 +27,113 @@
)
func init() {
- android.RegisterModuleType("cc_fuzz", FuzzFactory)
+ android.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory)
+ android.RegisterModuleType("cc_fuzz", LibFuzzFactory)
android.RegisterSingletonType("cc_fuzz_packaging", fuzzPackagingFactory)
+ android.RegisterSingletonType("cc_afl_fuzz_packaging", fuzzAFLPackagingFactory)
+}
+
+type FuzzProperties struct {
+ AFLEnabled bool `blueprint:"mutated"`
+ AFLAddFlags bool `blueprint:"mutated"`
+}
+
+type fuzzer struct {
+ Properties FuzzProperties
+}
+
+func (fuzzer *fuzzer) flags(ctx ModuleContext, flags Flags) Flags {
+ if fuzzer.Properties.AFLAddFlags {
+ flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-coverage=trace-pc-guard")
+ }
+
+ return flags
+}
+
+func (fuzzer *fuzzer) props() []interface{} {
+ return []interface{}{&fuzzer.Properties}
+}
+
+func fuzzMutatorDeps(mctx android.TopDownMutatorContext) {
+ currentModule, ok := mctx.Module().(*Module)
+ if !ok {
+ return
+ }
+
+ if currentModule.fuzzer == nil || !currentModule.fuzzer.Properties.AFLEnabled {
+ return
+ }
+
+ mctx.WalkDeps(func(child android.Module, parent android.Module) bool {
+ c, ok := child.(*Module)
+ if !ok {
+ return false
+ }
+
+ if c.sanitize == nil {
+ return false
+ }
+
+ isFuzzerPointer := c.sanitize.getSanitizerBoolPtr(Fuzzer)
+ if isFuzzerPointer == nil || !*isFuzzerPointer {
+ return false
+ }
+
+ if c.fuzzer == nil {
+ return false
+ }
+
+ c.fuzzer.Properties.AFLEnabled = true
+ c.fuzzer.Properties.AFLAddFlags = true
+ return true
+ })
+}
+
+func fuzzMutator(mctx android.BottomUpMutatorContext) {
+ if c, ok := mctx.Module().(*Module); ok && c.fuzzer != nil {
+ if !c.fuzzer.Properties.AFLEnabled {
+ return
+ }
+
+ if c.Binary() {
+ m := mctx.CreateVariations("afl")
+ m[0].(*Module).fuzzer.Properties.AFLEnabled = true
+ m[0].(*Module).fuzzer.Properties.AFLAddFlags = true
+ } else {
+ m := mctx.CreateVariations("", "afl")
+ m[0].(*Module).fuzzer.Properties.AFLEnabled = false
+ m[0].(*Module).fuzzer.Properties.AFLAddFlags = false
+
+ m[1].(*Module).fuzzer.Properties.AFLEnabled = true
+ m[1].(*Module).fuzzer.Properties.AFLAddFlags = true
+ }
+ }
}
// cc_fuzz creates a host/device fuzzer binary. Host binaries can be found at
// $ANDROID_HOST_OUT/fuzz/, and device binaries can be found at /data/fuzz on
// your device, or $ANDROID_PRODUCT_OUT/data/fuzz in your build tree.
-func FuzzFactory() android.Module {
- module := NewFuzz(android.HostAndDeviceSupported)
+func LibFuzzFactory() android.Module {
+ module := NewFuzzer(android.HostAndDeviceSupported, fuzz.Cc)
return module.Init()
}
-func NewFuzzInstaller() *baseInstaller {
- return NewBaseInstaller("fuzz", "fuzz", InstallInData)
+// cc_afl_fuzz creates a host/device AFL++ fuzzer binary.
+// AFL++ is an open source framework used to fuzz libraries
+// Host binaries can be found at $ANDROID_HOST_OUT/afl_fuzz/ and device
+// binaries can be found at $ANDROID_PRODUCT_OUT/data/afl_fuzz in your
+// build tree
+func AFLFuzzFactory() android.Module {
+ module := NewFuzzer(android.HostAndDeviceSupported, fuzz.AFL)
+ return module.Init()
}
type fuzzBinary struct {
*binaryDecorator
*baseCompiler
-
- fuzzPackagedModule fuzz.FuzzPackagedModule
-
+ fuzzPackagedModule fuzz.FuzzPackagedModule
installedSharedDeps []string
+ fuzzType fuzz.FuzzType
}
func (fuzz *fuzzBinary) fuzzBinary() bool {
@@ -66,11 +150,17 @@
fuzz.binaryDecorator.linkerInit(ctx)
}
-func (fuzz *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
- deps.StaticLibs = append(deps.StaticLibs,
- config.LibFuzzerRuntimeLibrary(ctx.toolchain()))
- deps = fuzz.binaryDecorator.linkerDeps(ctx, deps)
- return deps
+func (fuzzBin *fuzzBinary) linkerDeps(ctx DepsContext, deps Deps) Deps {
+ if fuzzBin.fuzzType == fuzz.AFL {
+ deps.HeaderLibs = append(deps.HeaderLibs, "libafl_headers")
+ deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps)
+ return deps
+
+ } else {
+ deps.StaticLibs = append(deps.StaticLibs, config.LibFuzzerRuntimeLibrary(ctx.toolchain()))
+ deps = fuzzBin.binaryDecorator.linkerDeps(ctx, deps)
+ return deps
+ }
}
func (fuzz *fuzzBinary) linkerFlags(ctx ModuleContext, flags Flags) Flags {
@@ -80,6 +170,7 @@
// target packages.
flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/../lib`)
flags.Local.LdFlags = append(flags.Local.LdFlags, `-Wl,-rpath,\$$ORIGIN/lib`)
+
return flags
}
@@ -149,63 +240,68 @@
}
func sharedLibraryInstallLocation(
- libraryPath android.Path, isHost bool, archString string) string {
+ libraryPath android.Path, isHost bool, fuzzDir string, archString string) string {
installLocation := "$(PRODUCT_OUT)/data"
if isHost {
installLocation = "$(HOST_OUT)"
}
installLocation = filepath.Join(
- installLocation, "fuzz", archString, "lib", libraryPath.Base())
+ installLocation, fuzzDir, archString, "lib", libraryPath.Base())
return installLocation
}
// Get the device-only shared library symbols install directory.
-func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, archString string) string {
- return filepath.Join("$(PRODUCT_OUT)/symbols/data/fuzz/", archString, "/lib/", libraryPath.Base())
+func sharedLibrarySymbolsInstallLocation(libraryPath android.Path, fuzzDir string, archString string) string {
+ return filepath.Join("$(PRODUCT_OUT)/symbols/data/", fuzzDir, archString, "/lib/", libraryPath.Base())
}
-func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) {
- fuzz.binaryDecorator.baseInstaller.dir = filepath.Join(
- "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
- fuzz.binaryDecorator.baseInstaller.dir64 = filepath.Join(
- "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
- fuzz.binaryDecorator.baseInstaller.install(ctx, file)
+func (fuzzBin *fuzzBinary) install(ctx ModuleContext, file android.Path) {
+ installBase := "fuzz"
+ if fuzzBin.fuzzType == fuzz.AFL {
+ installBase = "afl_fuzz"
+ }
- fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus)
+ fuzzBin.binaryDecorator.baseInstaller.dir = filepath.Join(
+ installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
+ fuzzBin.binaryDecorator.baseInstaller.dir64 = filepath.Join(
+ installBase, ctx.Target().Arch.ArchType.String(), ctx.ModuleName())
+ fuzzBin.binaryDecorator.baseInstaller.install(ctx, file)
+
+ fuzzBin.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Corpus)
builder := android.NewRuleBuilder(pctx, ctx)
intermediateDir := android.PathForModuleOut(ctx, "corpus")
- for _, entry := range fuzz.fuzzPackagedModule.Corpus {
+ for _, entry := range fuzzBin.fuzzPackagedModule.Corpus {
builder.Command().Text("cp").
Input(entry).
Output(intermediateDir.Join(ctx, entry.Base()))
}
builder.Build("copy_corpus", "copy corpus")
- fuzz.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir
+ fuzzBin.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir
- fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data)
+ fuzzBin.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzzBin.fuzzPackagedModule.FuzzProperties.Data)
builder = android.NewRuleBuilder(pctx, ctx)
intermediateDir = android.PathForModuleOut(ctx, "data")
- for _, entry := range fuzz.fuzzPackagedModule.Data {
+ for _, entry := range fuzzBin.fuzzPackagedModule.Data {
builder.Command().Text("cp").
Input(entry).
Output(intermediateDir.Join(ctx, entry.Rel()))
}
builder.Build("copy_data", "copy data")
- fuzz.fuzzPackagedModule.DataIntermediateDir = intermediateDir
+ fuzzBin.fuzzPackagedModule.DataIntermediateDir = intermediateDir
- if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
- fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary)
- if fuzz.fuzzPackagedModule.Dictionary.Ext() != ".dict" {
+ if fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary != nil {
+ fuzzBin.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzzBin.fuzzPackagedModule.FuzzProperties.Dictionary)
+ if fuzzBin.fuzzPackagedModule.Dictionary.Ext() != ".dict" {
ctx.PropertyErrorf("dictionary",
"Fuzzer dictionary %q does not have '.dict' extension",
- fuzz.fuzzPackagedModule.Dictionary.String())
+ fuzzBin.fuzzPackagedModule.Dictionary.String())
}
}
- if fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
+ if fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil {
configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json")
- android.WriteFileRule(ctx, configPath, fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
- fuzz.fuzzPackagedModule.Config = configPath
+ android.WriteFileRule(ctx, configPath, fuzzBin.fuzzPackagedModule.FuzzProperties.Fuzz_config.String())
+ fuzzBin.fuzzPackagedModule.Config = configPath
}
// Grab the list of required shared libraries.
@@ -225,31 +321,36 @@
})
for _, lib := range sharedLibraries {
- fuzz.installedSharedDeps = append(fuzz.installedSharedDeps,
+ fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
sharedLibraryInstallLocation(
- lib, ctx.Host(), ctx.Arch().ArchType.String()))
+ lib, ctx.Host(), installBase, ctx.Arch().ArchType.String()))
// Also add the dependency on the shared library symbols dir.
if !ctx.Host() {
- fuzz.installedSharedDeps = append(fuzz.installedSharedDeps,
- sharedLibrarySymbolsInstallLocation(lib, ctx.Arch().ArchType.String()))
+ fuzzBin.installedSharedDeps = append(fuzzBin.installedSharedDeps,
+ sharedLibrarySymbolsInstallLocation(lib, installBase, ctx.Arch().ArchType.String()))
}
}
}
-func NewFuzz(hod android.HostOrDeviceSupported) *Module {
+func NewFuzzer(hod android.HostOrDeviceSupported, fuzzType fuzz.FuzzType) *Module {
module, binary := newBinary(hod, false)
+ baseInstallerPath := "fuzz"
+ if fuzzType == fuzz.AFL {
+ baseInstallerPath = "afl_fuzz"
+ }
- binary.baseInstaller = NewFuzzInstaller()
+ binary.baseInstaller = NewBaseInstaller(baseInstallerPath, baseInstallerPath, InstallInData)
module.sanitize.SetSanitizer(Fuzzer, true)
- fuzz := &fuzzBinary{
+ fuzzBin := &fuzzBinary{
binaryDecorator: binary,
baseCompiler: NewBaseCompiler(),
+ fuzzType: fuzzType,
}
- module.compiler = fuzz
- module.linker = fuzz
- module.installer = fuzz
+ module.compiler = fuzzBin
+ module.linker = fuzzBin
+ module.installer = fuzzBin
// The fuzzer runtime is not present for darwin host modules, disable cc_fuzz modules when targeting darwin.
android.AddLoadHook(module, func(ctx android.LoadHookContext) {
@@ -268,6 +369,17 @@
ctx.AppendProperties(&disableDarwinAndLinuxBionic)
})
+ if fuzzType == fuzz.AFL {
+ // Add cc_objects to Srcs
+ fuzzBin.baseCompiler.Properties.Srcs = append(fuzzBin.baseCompiler.Properties.Srcs, ":aflpp_driver", ":afl-compiler-rt")
+ module.fuzzer.Properties.AFLEnabled = true
+ module.compiler.appendCflags([]string{
+ "-Wno-unused-result",
+ "-Wno-unused-parameter",
+ "-Wno-unused-function",
+ })
+ }
+
return module
}
@@ -275,10 +387,30 @@
// their architecture & target/host specific zip file.
type ccFuzzPackager struct {
fuzz.FuzzPackager
+ fuzzPackagingArchModules string
+ fuzzTargetSharedDepsInstallPairs string
+ allFuzzTargetsName string
}
func fuzzPackagingFactory() android.Singleton {
- return &ccFuzzPackager{}
+
+ fuzzPackager := &ccFuzzPackager{
+ fuzzPackagingArchModules: "SOONG_FUZZ_PACKAGING_ARCH_MODULES",
+ fuzzTargetSharedDepsInstallPairs: "FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
+ allFuzzTargetsName: "ALL_FUZZ_TARGETS",
+ }
+ fuzzPackager.FuzzType = fuzz.Cc
+ return fuzzPackager
+}
+
+func fuzzAFLPackagingFactory() android.Singleton {
+ fuzzPackager := &ccFuzzPackager{
+ fuzzPackagingArchModules: "SOONG_AFL_FUZZ_PACKAGING_ARCH_MODULES",
+ fuzzTargetSharedDepsInstallPairs: "AFL_FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
+ allFuzzTargetsName: "ALL_AFL_FUZZ_TARGETS",
+ }
+ fuzzPackager.FuzzType = fuzz.AFL
+ return fuzzPackager
}
func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) {
@@ -306,8 +438,9 @@
return
}
+ sharedLibsInstallDirPrefix := "lib"
fuzzModule, ok := ccModule.compiler.(*fuzzBinary)
- if !ok {
+ if !ok || fuzzModule.fuzzType != s.FuzzType {
return
}
@@ -316,8 +449,18 @@
hostOrTargetString = "host"
}
+ fpm := fuzz.FuzzPackagedModule{}
+ if ok {
+ fpm = fuzzModule.fuzzPackagedModule
+ }
+
+ intermediatePath := "fuzz"
+ if s.FuzzType == fuzz.AFL {
+ intermediatePath = "afl_fuzz"
+ }
+
archString := ccModule.Arch().ArchType.String()
- archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString)
+ archDir := android.PathForIntermediates(ctx, intermediatePath, hostOrTargetString, archString)
archOs := fuzz.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()}
// Grab the list of required shared libraries.
@@ -327,22 +470,21 @@
builder := android.NewRuleBuilder(pctx, ctx)
// Package the corpus, data, dict and config into a zipfile.
- files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder)
+ files = s.PackageArtifacts(ctx, module, fpm, archDir, builder)
// Package shared libraries
- files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...)
+ files = append(files, GetSharedLibsToZip(sharedLibraries, ccModule, &s.FuzzPackager, archString, sharedLibsInstallDirPrefix, &sharedLibraryInstalled)...)
// The executable.
files = append(files, fuzz.FileToZip{ccModule.UnstrippedOutputFile(), ""})
- archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
+ archDirs[archOs], ok = s.BuildZipFile(ctx, module, fpm, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok {
return
}
})
- s.CreateFuzzPackage(ctx, archDirs, fuzz.Cc, pctx)
-
+ s.CreateFuzzPackage(ctx, archDirs, s.FuzzType, pctx)
}
func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) {
@@ -353,27 +495,34 @@
// ready to handle phony targets created in Soong. In the meantime, this
// exports the phony 'fuzz' target and dependencies on packages to
// core/main.mk so that we can use dist-for-goals.
- ctx.Strict("SOONG_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " "))
- ctx.Strict("FUZZ_TARGET_SHARED_DEPS_INSTALL_PAIRS",
+
+ ctx.Strict(s.fuzzPackagingArchModules, strings.Join(packages, " "))
+
+ ctx.Strict(s.fuzzTargetSharedDepsInstallPairs,
strings.Join(s.FuzzPackager.SharedLibInstallStrings, " "))
// Preallocate the slice of fuzz targets to minimise memory allocations.
- s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS")
+ s.PreallocateSlice(ctx, s.allFuzzTargetsName)
}
// GetSharedLibsToZip finds and marks all the transiently-dependent shared libraries for
// packaging.
-func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip {
+func GetSharedLibsToZip(sharedLibraries android.Paths, module LinkableInterface, s *fuzz.FuzzPackager, archString string, destinationPathPrefix string, sharedLibraryInstalled *map[string]bool) []fuzz.FileToZip {
var files []fuzz.FileToZip
+ fuzzDir := "fuzz"
+ if s.FuzzType == fuzz.AFL {
+ fuzzDir = "afl_fuzz"
+ }
+
for _, library := range sharedLibraries {
- files = append(files, fuzz.FileToZip{library, "lib"})
+ files = append(files, fuzz.FileToZip{library, destinationPathPrefix})
// For each architecture-specific shared library dependency, we need to
// install it to the output directory. Setup the install destination here,
// which will be used by $(copy-many-files) in the Make backend.
installDestination := sharedLibraryInstallLocation(
- library, module.Host(), archString)
+ library, module.Host(), fuzzDir, archString)
if (*sharedLibraryInstalled)[installDestination] {
continue
}
@@ -391,7 +540,7 @@
// we want symbolization tools (like `stack`) to be able to find the symbols
// in $ANDROID_PRODUCT_OUT/symbols automagically.
if !module.Host() {
- symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, archString)
+ symbolsInstallDestination := sharedLibrarySymbolsInstallLocation(library, fuzzDir, archString)
symbolsInstallDestination = strings.ReplaceAll(symbolsInstallDestination, "$", "$$")
s.SharedLibInstallStrings = append(s.SharedLibInstallStrings,
library.String()+":"+symbolsInstallDestination)
diff --git a/cc/image.go b/cc/image.go
index 3a0857b..921b2bb 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -533,7 +533,7 @@
}
} else {
// This is either in /system (or similar: /data), or is a
- // modules built with the NDK. Modules built with the NDK
+ // module built with the NDK. Modules built with the NDK
// will be restricted using the existing link type checks.
coreVariantNeeded = true
}
diff --git a/cc/library.go b/cc/library.go
index c445a42..bd6ccb5 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -1032,9 +1032,19 @@
ctx.PropertyErrorf("symbol_file", "%q doesn't have .map.txt suffix", symbolFile)
return Objects{}
}
+ // b/239274367 --apex and --systemapi filters symbols tagged with # apex and #
+ // systemapi, respectively. The former is for symbols defined in platform libraries
+ // and the latter is for symbols defined in APEXes.
+ var flag string
+ if ctx.Module().(android.ApexModule).NotInPlatform() {
+ flag = "--apex"
+ } else {
+ // TODO(b/239274367) drop --apex when #apex is replaced with #systemapi
+ // in the map.txt files of platform libraries
+ flag = "--systemapi --apex"
+ }
nativeAbiResult := parseNativeAbiDefinition(ctx, symbolFile,
- android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion),
- "--apex")
+ android.ApiLevelOrPanic(ctx, library.MutatedProperties.StubsVersion), flag)
objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
library.versionScriptPath = android.OptionalPathForPath(
nativeAbiResult.versionScript)
@@ -1584,10 +1594,10 @@
func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path {
// The logic must be consistent with classifySourceAbiDump.
isNdk := ctx.isNdk(ctx.Config())
- isLlndkOrVndk := ctx.IsLlndkPublic() || (ctx.useVndk() && ctx.isVndk())
+ isVndk := ctx.useVndk() && ctx.isVndk()
- refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, false)
- refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isLlndkOrVndk, true)
+ refAbiDumpTextFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isVndk, false)
+ refAbiDumpGzipFile := android.PathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isVndk, true)
if refAbiDumpTextFile.Valid() {
if refAbiDumpGzipFile.Valid() {
diff --git a/cc/ndk_api_coverage_parser/__init__.py b/cc/ndk_api_coverage_parser/__init__.py
index 8b9cd66..752f7d4 100755
--- a/cc/ndk_api_coverage_parser/__init__.py
+++ b/cc/ndk_api_coverage_parser/__init__.py
@@ -23,6 +23,7 @@
from xml.etree.ElementTree import Element, SubElement, tostring
from symbolfile import (
ALL_ARCHITECTURES,
+ Filter,
FUTURE_API_LEVEL,
MultiplyDefinedSymbolError,
SymbolFileParser,
@@ -139,9 +140,8 @@
with open(args.symbol_file) as symbol_file:
try:
- versions = SymbolFileParser(
- symbol_file, api_map, "", FUTURE_API_LEVEL, True, True
- ).parse()
+ filt = Filter("", FUTURE_API_LEVEL, True, True, True)
+ versions = SymbolFileParser(symbol_file, api_map, filt).parse()
except MultiplyDefinedSymbolError as ex:
sys.exit('{}: error: {}'.format(args.symbol_file, ex))
diff --git a/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py b/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
index 141059c..7c6ef68 100644
--- a/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
+++ b/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
@@ -20,7 +20,7 @@
import unittest
from xml.etree.ElementTree import fromstring
-from symbolfile import FUTURE_API_LEVEL, SymbolFileParser
+from symbolfile import Filter, FUTURE_API_LEVEL, SymbolFileParser
import ndk_api_coverage_parser as nparser
@@ -78,9 +78,8 @@
"""
)
)
- parser = SymbolFileParser(
- input_file, {}, "", FUTURE_API_LEVEL, True, True
- )
+ filt = Filter("", FUTURE_API_LEVEL, True, True, True)
+ parser = SymbolFileParser(input_file, {}, filt)
generator = nparser.XmlGenerator(io.StringIO())
result = generator.convertToXml(parser.parse())
expected = fromstring(
diff --git a/cc/ndkstubgen/__init__.py b/cc/ndkstubgen/__init__.py
index 5e6b8f5..f893d41 100755
--- a/cc/ndkstubgen/__init__.py
+++ b/cc/ndkstubgen/__init__.py
@@ -29,15 +29,12 @@
class Generator:
"""Output generator that writes stub source files and version scripts."""
def __init__(self, src_file: TextIO, version_script: TextIO,
- symbol_list: TextIO, arch: Arch, api: int, llndk: bool,
- apex: bool) -> None:
+ symbol_list: TextIO, filt: symbolfile.Filter) -> None:
self.src_file = src_file
self.version_script = version_script
self.symbol_list = symbol_list
- self.arch = arch
- self.api = api
- self.llndk = llndk
- self.apex = apex
+ self.filter = filt
+ self.api = filt.api
def write(self, versions: Iterable[Version]) -> None:
"""Writes all symbol data to the output files."""
@@ -47,8 +44,7 @@
def write_version(self, version: Version) -> None:
"""Writes a single version block's data to the output files."""
- if symbolfile.should_omit_version(version, self.arch, self.api,
- self.llndk, self.apex):
+ if self.filter.should_omit_version(version):
return
section_versioned = symbolfile.symbol_versioned_in_api(
@@ -56,8 +52,7 @@
version_empty = True
pruned_symbols = []
for symbol in version.symbols:
- if symbolfile.should_omit_symbol(symbol, self.arch, self.api,
- self.llndk, self.apex):
+ if self.filter.should_omit_symbol(symbol):
continue
if symbolfile.symbol_versioned_in_api(symbol.tags, self.api):
@@ -110,12 +105,12 @@
parser.add_argument(
'--apex',
action='store_true',
- help='Use the APEX variant. Note: equivalent to --system-api.')
+ help='Use the APEX variant.')
parser.add_argument(
- '--system-api',
+ '--systemapi',
action='store_true',
- dest='apex',
- help='Use the SystemAPI variant. Note: equivalent to --apex.')
+ dest='systemapi',
+ help='Use the SystemAPI variant.')
parser.add_argument('--api-map',
type=resolved_path,
@@ -152,11 +147,10 @@
verbosity = 2
logging.basicConfig(level=verbose_map[verbosity])
+ filt = symbolfile.Filter(args.arch, api, args.llndk, args.apex, args.systemapi)
with args.symbol_file.open() as symbol_file:
try:
- versions = symbolfile.SymbolFileParser(symbol_file, api_map,
- args.arch, api, args.llndk,
- args.apex).parse()
+ versions = symbolfile.SymbolFileParser(symbol_file, api_map, filt).parse()
except symbolfile.MultiplyDefinedSymbolError as ex:
sys.exit(f'{args.symbol_file}: error: {ex}')
@@ -164,7 +158,7 @@
with args.version_script.open('w') as version_script:
with args.symbol_list.open('w') as symbol_list:
generator = Generator(src_file, version_script, symbol_list,
- args.arch, api, args.llndk, args.apex)
+ filt)
generator.write(versions)
diff --git a/cc/ndkstubgen/test_ndkstubgen.py b/cc/ndkstubgen/test_ndkstubgen.py
index c8cd056..450719b 100755
--- a/cc/ndkstubgen/test_ndkstubgen.py
+++ b/cc/ndkstubgen/test_ndkstubgen.py
@@ -18,6 +18,7 @@
import io
import textwrap
import unittest
+from copy import copy
import symbolfile
from symbolfile import Arch, Tags
@@ -29,6 +30,9 @@
class GeneratorTest(unittest.TestCase):
+ def setUp(self) -> None:
+ self.filter = symbolfile.Filter(Arch('arm'), 9, False, False)
+
def test_omit_version(self) -> None:
# Thorough testing of the cases involved here is handled by
# OmitVersionTest, PrivateVersionTest, and SymbolPresenceTest.
@@ -37,7 +41,7 @@
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
- Arch('arm'), 9, False, False)
+ self.filter)
version = symbolfile.Version('VERSION_PRIVATE', None, Tags(), [
symbolfile.Symbol('foo', Tags()),
@@ -70,7 +74,7 @@
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
- Arch('arm'), 9, False, False)
+ self.filter)
version = symbolfile.Version('VERSION_1', None, Tags(), [
symbolfile.Symbol('foo', Tags.from_strs(['x86'])),
@@ -106,7 +110,7 @@
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
- Arch('arm'), 9, False, False)
+ self.filter)
versions = [
symbolfile.Version('VERSION_1', None, Tags(), [
@@ -162,6 +166,9 @@
class IntegrationTest(unittest.TestCase):
+ def setUp(self) -> None:
+ self.filter = symbolfile.Filter(Arch('arm'), 9, False, False)
+
def test_integration(self) -> None:
api_map = {
'O': 9000,
@@ -199,8 +206,7 @@
wobble;
} VERSION_4;
"""))
- parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
- 9, False, False)
+ parser = symbolfile.SymbolFileParser(input_file, api_map, self.filter)
versions = parser.parse()
src_file = io.StringIO()
@@ -208,7 +214,7 @@
symbol_list_file = io.StringIO()
generator = ndkstubgen.Generator(src_file,
version_file, symbol_list_file,
- Arch('arm'), 9, False, False)
+ self.filter)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -263,16 +269,18 @@
*;
};
"""))
- parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
- 9001, False, False)
+ f = copy(self.filter)
+ f.api = 9001
+ parser = symbolfile.SymbolFileParser(input_file, api_map, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
+ f = copy(self.filter)
+ f.api = 9001
generator = ndkstubgen.Generator(src_file,
- version_file, symbol_list_file,
- Arch('arm'), 9001, False, False)
+ version_file, symbol_list_file, f)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -322,8 +330,9 @@
} VERSION_2;
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ f = copy(self.filter)
+ f.api = 16
+ parser = symbolfile.SymbolFileParser(input_file, {}, f)
with self.assertRaises(
symbolfile.MultiplyDefinedSymbolError) as ex_context:
@@ -370,16 +379,18 @@
wobble;
} VERSION_4;
"""))
- parser = symbolfile.SymbolFileParser(input_file, api_map, Arch('arm'),
- 9, False, True)
+ f = copy(self.filter)
+ f.apex = True
+ parser = symbolfile.SymbolFileParser(input_file, api_map, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
+ f = copy(self.filter)
+ f.apex = True
generator = ndkstubgen.Generator(src_file,
- version_file, symbol_list_file,
- Arch('arm'), 9, False, True)
+ version_file, symbol_list_file, f)
generator.write(versions)
expected_src = textwrap.dedent("""\
@@ -428,20 +439,19 @@
*;
};
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
- 9, llndk=False, apex=True)
+ f = copy(self.filter)
+ f.apex = True
+ parser = symbolfile.SymbolFileParser(input_file, {}, f)
versions = parser.parse()
src_file = io.StringIO()
version_file = io.StringIO()
symbol_list_file = io.StringIO()
+ f = copy(self.filter)
+ f.apex = True
generator = ndkstubgen.Generator(src_file,
version_file,
- symbol_list_file,
- Arch('arm'),
- 9,
- llndk=False,
- apex=True)
+ symbol_list_file, f)
generator.write(versions)
self.assertEqual('', src_file.getvalue())
diff --git a/cc/symbolfile/__init__.py b/cc/symbolfile/__init__.py
index f8d1841..471a12f 100644
--- a/cc/symbolfile/__init__.py
+++ b/cc/symbolfile/__init__.py
@@ -78,12 +78,17 @@
@property
def has_mode_tags(self) -> bool:
"""Returns True if any mode tags (apex, llndk, etc) are set."""
- return self.has_apex_tags or self.has_llndk_tags
+ return self.has_apex_tags or self.has_llndk_tags or self.has_systemapi_tags
@property
def has_apex_tags(self) -> bool:
"""Returns True if any APEX tags are set."""
- return 'apex' in self.tags or 'systemapi' in self.tags
+ return 'apex' in self.tags
+
+ @property
+ def has_systemapi_tags(self) -> bool:
+ """Returns True if any APEX tags are set."""
+ return 'systemapi' in self.tags
@property
def has_llndk_tags(self) -> bool:
@@ -198,50 +203,57 @@
"""
return split_tag(tag)[1]
-
-def _should_omit_tags(tags: Tags, arch: Arch, api: int, llndk: bool,
- apex: bool) -> bool:
- """Returns True if the tagged object should be omitted.
-
- This defines the rules shared between version tagging and symbol tagging.
+class Filter:
+ """A filter encapsulates a condition that tells whether a version or a
+ symbol should be omitted or not
"""
- # The apex and llndk tags will only exclude APIs from other modes. If in
- # APEX or LLNDK mode and neither tag is provided, we fall back to the
- # default behavior because all NDK symbols are implicitly available to APEX
- # and LLNDK.
- if tags.has_mode_tags:
- if not apex and not llndk:
+
+ def __init__(self, arch: Arch, api: int, llndk: bool = False, apex: bool = False, systemapi: bool = False):
+ self.arch = arch
+ self.api = api
+ self.llndk = llndk
+ self.apex = apex
+ self.systemapi = systemapi
+
+ def _should_omit_tags(self, tags: Tags) -> bool:
+ """Returns True if the tagged object should be omitted.
+
+ This defines the rules shared between version tagging and symbol tagging.
+ """
+ # The apex and llndk tags will only exclude APIs from other modes. If in
+ # APEX or LLNDK mode and neither tag is provided, we fall back to the
+ # default behavior because all NDK symbols are implicitly available to
+ # APEX and LLNDK.
+ if tags.has_mode_tags:
+ if self.apex and tags.has_apex_tags:
+ return False
+ if self.llndk and tags.has_llndk_tags:
+ return False
+ if self.systemapi and tags.has_systemapi_tags:
+ return False
return True
- if apex and not tags.has_apex_tags:
+ if not symbol_in_arch(tags, self.arch):
return True
- if llndk and not tags.has_llndk_tags:
+ if not symbol_in_api(tags, self.arch, self.api):
return True
- if not symbol_in_arch(tags, arch):
- return True
- if not symbol_in_api(tags, arch, api):
- return True
- return False
+ return False
+ def should_omit_version(self, version: Version) -> bool:
+ """Returns True if the version section should be omitted.
-def should_omit_version(version: Version, arch: Arch, api: int, llndk: bool,
- apex: bool) -> bool:
- """Returns True if the version section should be omitted.
+ We want to omit any sections that do not have any symbols we'll have in
+ the stub library. Sections that contain entirely future symbols or only
+ symbols for certain architectures.
+ """
+ if version.is_private:
+ return True
+ if version.tags.has_platform_only_tags:
+ return True
+ return self._should_omit_tags(version.tags)
- We want to omit any sections that do not have any symbols we'll have in the
- stub library. Sections that contain entirely future symbols or only symbols
- for certain architectures.
- """
- if version.is_private:
- return True
- if version.tags.has_platform_only_tags:
- return True
- return _should_omit_tags(version.tags, arch, api, llndk, apex)
-
-
-def should_omit_symbol(symbol: Symbol, arch: Arch, api: int, llndk: bool,
- apex: bool) -> bool:
- """Returns True if the symbol should be omitted."""
- return _should_omit_tags(symbol.tags, arch, api, llndk, apex)
+ def should_omit_symbol(self, symbol: Symbol) -> bool:
+ """Returns True if the symbol should be omitted."""
+ return self._should_omit_tags(symbol.tags)
def symbol_in_arch(tags: Tags, arch: Arch) -> bool:
@@ -316,14 +328,10 @@
class SymbolFileParser:
"""Parses NDK symbol files."""
- def __init__(self, input_file: TextIO, api_map: ApiMap, arch: Arch,
- api: int, llndk: bool, apex: bool) -> None:
+ def __init__(self, input_file: TextIO, api_map: ApiMap, filt: Filter) -> None:
self.input_file = input_file
self.api_map = api_map
- self.arch = arch
- self.api = api
- self.llndk = llndk
- self.apex = apex
+ self.filter = filt
self.current_line: Optional[str] = None
def parse(self) -> List[Version]:
@@ -352,13 +360,11 @@
symbol_names = set()
multiply_defined_symbols = set()
for version in versions:
- if should_omit_version(version, self.arch, self.api, self.llndk,
- self.apex):
+ if self.filter.should_omit_version(version):
continue
for symbol in version.symbols:
- if should_omit_symbol(symbol, self.arch, self.api, self.llndk,
- self.apex):
+ if self.filter.should_omit_symbol(symbol):
continue
if symbol.name in symbol_names:
diff --git a/cc/symbolfile/test_symbolfile.py b/cc/symbolfile/test_symbolfile.py
index c1e8219..e17a8d0 100644
--- a/cc/symbolfile/test_symbolfile.py
+++ b/cc/symbolfile/test_symbolfile.py
@@ -19,7 +19,8 @@
import unittest
import symbolfile
-from symbolfile import Arch, Tag, Tags, Version
+from symbolfile import Arch, Tag, Tags, Version, Symbol, Filter
+from copy import copy
# pylint: disable=missing-docstring
@@ -202,178 +203,188 @@
class OmitVersionTest(unittest.TestCase):
+ def setUp(self) -> None:
+ self.filter = Filter(arch = Arch('arm'), api = 9)
+ self.version = Version('foo', None, Tags(), [])
+
+ def assertOmit(self, f: Filter, v: Version) -> None:
+ self.assertTrue(f.should_omit_version(v))
+
+ def assertInclude(self, f: Filter, v: Version) -> None:
+ self.assertFalse(f.should_omit_version(v))
+
def test_omit_private(self) -> None:
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
- False, False))
+ f = self.filter
+ v = self.version
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo_PRIVATE', None, Tags(), []),
- Arch('arm'), 9, False, False))
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo_PLATFORM', None, Tags(), []),
- Arch('arm'), 9, False, False))
+ self.assertInclude(f, v)
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None,
- Tags.from_strs(['platform-only']), []),
- Arch('arm'), 9, False, False))
+ v.name = 'foo_PRIVATE'
+ self.assertOmit(f, v)
+
+ v.name = 'foo_PLATFORM'
+ self.assertOmit(f, v)
+
+ v.name = 'foo'
+ v.tags = Tags.from_strs(['platform-only'])
+ self.assertOmit(f, v)
def test_omit_llndk(self) -> None:
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
- Arch('arm'), 9, False, False))
+ f = self.filter
+ v = self.version
+ v_llndk = copy(v)
+ v_llndk.tags = Tags.from_strs(['llndk'])
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
- True, False))
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags.from_strs(['llndk']), []),
- Arch('arm'), 9, True, False))
+ self.assertOmit(f, v_llndk)
+
+ f.llndk = True
+ self.assertInclude(f, v)
+ self.assertInclude(f, v_llndk)
def test_omit_apex(self) -> None:
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
- Arch('arm'), 9, False, False))
+ f = self.filter
+ v = self.version
+ v_apex = copy(v)
+ v_apex.tags = Tags.from_strs(['apex'])
+ v_systemapi = copy(v)
+ v_systemapi.tags = Tags.from_strs(['systemapi'])
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
- False, True))
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags.from_strs(['apex']), []),
- Arch('arm'), 9, False, True))
+ self.assertOmit(f, v_apex)
+
+ f.apex = True
+ self.assertInclude(f, v)
+ self.assertInclude(f, v_apex)
+ self.assertOmit(f, v_systemapi)
def test_omit_systemapi(self) -> None:
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
- []), Arch('arm'), 9, False, False))
+ f = self.filter
+ v = self.version
+ v_apex = copy(v)
+ v_apex.tags = Tags.from_strs(['apex'])
+ v_systemapi = copy(v)
+ v_systemapi.tags = Tags.from_strs(['systemapi'])
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
- False, True))
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags.from_strs(['systemapi']),
- []), Arch('arm'), 9, False, True))
+ self.assertOmit(f, v_systemapi)
+
+ f.systemapi = True
+ self.assertInclude(f, v)
+ self.assertInclude(f, v_systemapi)
+ self.assertOmit(f, v_apex)
def test_omit_arch(self) -> None:
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
- False, False))
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags.from_strs(['arm']), []),
- Arch('arm'), 9, False, False))
+ f_arm = self.filter
+ v_none = self.version
+ self.assertInclude(f_arm, v_none)
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags.from_strs(['x86']), []),
- Arch('arm'), 9, False, False))
+ v_arm = copy(v_none)
+ v_arm.tags = Tags.from_strs(['arm'])
+ self.assertInclude(f_arm, v_arm)
+
+ v_x86 = copy(v_none)
+ v_x86.tags = Tags.from_strs(['x86'])
+ self.assertOmit(f_arm, v_x86)
def test_omit_api(self) -> None:
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None, Tags(), []), Arch('arm'), 9,
- False, False))
- self.assertFalse(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None,
- Tags.from_strs(['introduced=9']), []),
- Arch('arm'), 9, False, False))
+ f_api9 = self.filter
+ v_none = self.version
+ self.assertInclude(f_api9, v_none)
- self.assertTrue(
- symbolfile.should_omit_version(
- symbolfile.Version('foo', None,
- Tags.from_strs(['introduced=14']), []),
- Arch('arm'), 9, False, False))
+ v_api9 = copy(v_none)
+ v_api9.tags = Tags.from_strs(['introduced=9'])
+ self.assertInclude(f_api9, v_api9)
+
+ v_api14 = copy(v_none)
+ v_api14.tags = Tags.from_strs(['introduced=14'])
+ self.assertOmit(f_api9, v_api14)
class OmitSymbolTest(unittest.TestCase):
- def test_omit_llndk(self) -> None:
- self.assertTrue(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
- Arch('arm'), 9, False, False))
+ def setUp(self) -> None:
+ self.filter = Filter(arch = Arch('arm'), api = 9)
- self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
- Arch('arm'), 9, True, False))
- self.assertFalse(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['llndk'])),
- Arch('arm'), 9, True, False))
+ def assertOmit(self, f: Filter, s: Symbol) -> None:
+ self.assertTrue(f.should_omit_symbol(s))
+
+ def assertInclude(self, f: Filter, s: Symbol) -> None:
+ self.assertFalse(f.should_omit_symbol(s))
+
+ def test_omit_llndk(self) -> None:
+ f_none = self.filter
+ f_llndk = copy(f_none)
+ f_llndk.llndk = True
+
+ s_none = Symbol('foo', Tags())
+ s_llndk = Symbol('foo', Tags.from_strs(['llndk']))
+
+ self.assertOmit(f_none, s_llndk)
+ self.assertInclude(f_llndk, s_none)
+ self.assertInclude(f_llndk, s_llndk)
def test_omit_apex(self) -> None:
- self.assertTrue(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
- Arch('arm'), 9, False, False))
+ f_none = self.filter
+ f_apex = copy(f_none)
+ f_apex.apex = True
- self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
- Arch('arm'), 9, False, True))
- self.assertFalse(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['apex'])),
- Arch('arm'), 9, False, True))
+ s_none = Symbol('foo', Tags())
+ s_apex = Symbol('foo', Tags.from_strs(['apex']))
+ s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
+
+ self.assertOmit(f_none, s_apex)
+ self.assertInclude(f_apex, s_none)
+ self.assertInclude(f_apex, s_apex)
+ self.assertOmit(f_apex, s_systemapi)
def test_omit_systemapi(self) -> None:
- self.assertTrue(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
- Arch('arm'), 9, False, False))
+ f_none = self.filter
+ f_systemapi = copy(f_none)
+ f_systemapi.systemapi = True
- self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
- Arch('arm'), 9, False, True))
- self.assertFalse(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['systemapi'])),
- Arch('arm'), 9, False, True))
+ s_none = Symbol('foo', Tags())
+ s_apex = Symbol('foo', Tags.from_strs(['apex']))
+ s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
+
+ self.assertOmit(f_none, s_systemapi)
+ self.assertInclude(f_systemapi, s_none)
+ self.assertInclude(f_systemapi, s_systemapi)
+ self.assertOmit(f_systemapi, s_apex)
+
+ def test_omit_apex_and_systemapi(self) -> None:
+ f = self.filter
+ f.systemapi = True
+ f.apex = True
+
+ s_none = Symbol('foo', Tags())
+ s_apex = Symbol('foo', Tags.from_strs(['apex']))
+ s_systemapi = Symbol('foo', Tags.from_strs(['systemapi']))
+ self.assertInclude(f, s_none)
+ self.assertInclude(f, s_apex)
+ self.assertInclude(f, s_systemapi)
def test_omit_arch(self) -> None:
- self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
- Arch('arm'), 9, False, False))
- self.assertFalse(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['arm'])), Arch('arm'),
- 9, False, False))
+ f_arm = self.filter
+ s_none = Symbol('foo', Tags())
+ s_arm = Symbol('foo', Tags.from_strs(['arm']))
+ s_x86 = Symbol('foo', Tags.from_strs(['x86']))
- self.assertTrue(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['x86'])), Arch('arm'),
- 9, False, False))
+ self.assertInclude(f_arm, s_none)
+ self.assertInclude(f_arm, s_arm)
+ self.assertOmit(f_arm, s_x86)
def test_omit_api(self) -> None:
- self.assertFalse(
- symbolfile.should_omit_symbol(symbolfile.Symbol('foo', Tags()),
- Arch('arm'), 9, False, False))
- self.assertFalse(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['introduced=9'])),
- Arch('arm'), 9, False, False))
+ f_api9 = self.filter
+ s_none = Symbol('foo', Tags())
+ s_api9 = Symbol('foo', Tags.from_strs(['introduced=9']))
+ s_api14 = Symbol('foo', Tags.from_strs(['introduced=14']))
- self.assertTrue(
- symbolfile.should_omit_symbol(
- symbolfile.Symbol('foo', Tags.from_strs(['introduced=14'])),
- Arch('arm'), 9, False, False))
+ self.assertInclude(f_api9, s_none)
+ self.assertInclude(f_api9, s_api9)
+ self.assertOmit(f_api9, s_api14)
class SymbolFileParseTest(unittest.TestCase):
+ def setUp(self) -> None:
+ self.filter = Filter(arch = Arch('arm'), api = 16)
+
def test_next_line(self) -> None:
input_file = io.StringIO(textwrap.dedent("""\
foo
@@ -382,8 +393,7 @@
# baz
qux
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
self.assertIsNone(parser.current_line)
self.assertEqual('foo', parser.next_line().strip())
@@ -409,8 +419,7 @@
VERSION_2 {
} VERSION_1; # asdf
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
version = parser.parse_version()
@@ -419,8 +428,8 @@
self.assertEqual(Tags.from_strs(['foo', 'bar']), version.tags)
expected_symbols = [
- symbolfile.Symbol('baz', Tags()),
- symbolfile.Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
+ Symbol('baz', Tags()),
+ Symbol('qux', Tags.from_strs(['woodly', 'doodly'])),
]
self.assertEqual(expected_symbols, version.symbols)
@@ -434,8 +443,7 @@
input_file = io.StringIO(textwrap.dedent("""\
VERSION_1 {
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@@ -446,8 +454,7 @@
foo:
}
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@@ -457,8 +464,7 @@
foo;
bar; # baz qux
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
symbol = parser.parse_symbol()
@@ -476,8 +482,7 @@
*;
};
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@@ -489,8 +494,7 @@
*;
};
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
version = parser.parse_version()
self.assertEqual([], version.symbols)
@@ -501,8 +505,7 @@
foo
};
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.next_line()
with self.assertRaises(symbolfile.ParseError):
parser.parse_version()
@@ -510,8 +513,7 @@
def test_parse_fails_invalid_input(self) -> None:
with self.assertRaises(symbolfile.ParseError):
input_file = io.StringIO('foo')
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'),
- 16, False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
parser.parse()
def test_parse(self) -> None:
@@ -532,19 +534,18 @@
qwerty;
} VERSION_1;
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, False)
+ parser = symbolfile.SymbolFileParser(input_file, {}, self.filter)
versions = parser.parse()
expected = [
symbolfile.Version('VERSION_1', None, Tags(), [
- symbolfile.Symbol('foo', Tags()),
- symbolfile.Symbol('bar', Tags.from_strs(['baz'])),
+ Symbol('foo', Tags()),
+ Symbol('bar', Tags.from_strs(['baz'])),
]),
symbolfile.Version(
'VERSION_2', 'VERSION_1', Tags.from_strs(['wasd']), [
- symbolfile.Symbol('woodly', Tags()),
- symbolfile.Symbol('doodly', Tags.from_strs(['asdf'])),
+ Symbol('woodly', Tags()),
+ Symbol('doodly', Tags.from_strs(['asdf'])),
]),
]
@@ -559,8 +560,9 @@
qux; # apex
};
"""))
- parser = symbolfile.SymbolFileParser(input_file, {}, Arch('arm'), 16,
- False, True)
+ f = copy(self.filter)
+ f.llndk = True
+ parser = symbolfile.SymbolFileParser(input_file, {}, f)
parser.next_line()
version = parser.parse_version()
@@ -568,10 +570,10 @@
self.assertIsNone(version.base)
expected_symbols = [
- symbolfile.Symbol('foo', Tags()),
- symbolfile.Symbol('bar', Tags.from_strs(['llndk'])),
- symbolfile.Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
- symbolfile.Symbol('qux', Tags.from_strs(['apex'])),
+ Symbol('foo', Tags()),
+ Symbol('bar', Tags.from_strs(['llndk'])),
+ Symbol('baz', Tags.from_strs(['llndk', 'apex'])),
+ Symbol('qux', Tags.from_strs(['apex'])),
]
self.assertEqual(expected_symbols, version.symbols)
diff --git a/cc/testing.go b/cc/testing.go
index 077fcda..6b858d5 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -534,7 +534,8 @@
android.PrepareForTestWithAndroidBuildComponents,
android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
- ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
+ ctx.RegisterModuleType("cc_fuzz", LibFuzzFactory)
+ ctx.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory)
ctx.RegisterModuleType("cc_test", TestFactory)
ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
@@ -648,7 +649,8 @@
func CreateTestContext(config android.Config) *android.TestContext {
ctx := android.NewTestArchContext(config)
genrule.RegisterGenruleBuildComponents(ctx)
- ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
+ ctx.RegisterModuleType("cc_fuzz", LibFuzzFactory)
+ ctx.RegisterModuleType("cc_afl_fuzz", AFLFuzzFactory)
ctx.RegisterModuleType("cc_test", TestFactory)
ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index 8a3d6e0..53422cd 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -220,7 +220,7 @@
// doChosenActivity runs Soong for a specific activity, like bp2build, queryview
// or the actual Soong build for the build.ninja file. Returns the top level
// output file of the specific activity.
-func doChosenActivity(configuration android.Config, extraNinjaDeps []string, logDir string) string {
+func doChosenActivity(ctx *android.Context, configuration android.Config, extraNinjaDeps []string, logDir string) string {
mixedModeBuild := configuration.BazelContext.BazelEnabled()
generateBazelWorkspace := bp2buildMarker != ""
generateQueryView := bazelQueryViewDir != ""
@@ -236,7 +236,6 @@
blueprintArgs := cmdlineArgs
- ctx := newContext(configuration)
if mixedModeBuild {
runMixedModeBuild(configuration, ctx, extraNinjaDeps)
} else {
@@ -284,7 +283,6 @@
}
}
- writeMetrics(configuration, *ctx.EventHandler, logDir)
return cmdlineArgs.OutFile
}
@@ -344,7 +342,13 @@
// change between every CI build, so tracking it would require re-running Soong for every build.
logDir := availableEnv["LOG_DIR"]
- finalOutputFile := doChosenActivity(configuration, extraNinjaDeps, logDir)
+ ctx := newContext(configuration)
+ ctx.EventHandler.Begin("soong_build")
+
+ finalOutputFile := doChosenActivity(ctx, configuration, extraNinjaDeps, logDir)
+
+ ctx.EventHandler.End("soong_build")
+ writeMetrics(configuration, *ctx.EventHandler, logDir)
writeUsedEnvironmentFile(configuration, finalOutputFile)
}
@@ -552,7 +556,7 @@
excludes = append(excludes, getTemporaryExcludes()...)
symlinkForestDeps := bp2build.PlantSymlinkForest(
- topDir, workspaceRoot, generatedRoot, ".", excludes)
+ configuration, topDir, workspaceRoot, generatedRoot, ".", excludes)
ninjaDeps = append(ninjaDeps, codegenContext.AdditionalNinjaDeps()...)
ninjaDeps = append(ninjaDeps, symlinkForestDeps...)
@@ -566,7 +570,9 @@
// Only report metrics when in bp2build mode. The metrics aren't relevant
// for queryview, since that's a total repo-wide conversion and there's a
// 1:1 mapping for each module.
- metrics.Print()
+ if configuration.IsEnvTrue("BP2BUILD_VERBOSE") {
+ metrics.Print()
+ }
writeBp2BuildMetrics(&metrics, configuration, eventHandler)
}
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index d63ded5..983dbf0 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -32,7 +32,8 @@
panic(err)
}
- filesToWrite := bp2build.CreateBazelFiles(ruleShims, res.BuildDirToTargets(), bp2build.QueryView)
+ filesToWrite := bp2build.CreateBazelFiles(ctx.Config(), ruleShims, res.BuildDirToTargets(),
+ bp2build.QueryView)
for _, f := range filesToWrite {
if err := writeReadOnlyFile(bazelQueryViewDir, f); err != nil {
return err
diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go
index 700cdf0..1a87b30 100644
--- a/fuzz/fuzz_common.go
+++ b/fuzz/fuzz_common.go
@@ -18,6 +18,7 @@
import (
"encoding/json"
+ "fmt"
"sort"
"strings"
@@ -26,12 +27,13 @@
"android/soong/android"
)
-type Lang string
+type FuzzType string
const (
- Cc Lang = ""
- Rust Lang = "rust"
- Java Lang = "java"
+ Cc FuzzType = ""
+ Rust FuzzType = "rust"
+ Java FuzzType = "java"
+ AFL FuzzType = "AFL"
)
var BoolDefault = proptools.BoolDefault
@@ -46,6 +48,7 @@
Packages android.Paths
FuzzTargets map[string]bool
SharedLibInstallStrings []string
+ FuzzType FuzzType
}
type FileToZip struct {
@@ -59,9 +62,65 @@
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.
@@ -157,7 +216,7 @@
}
// Additional fuzz config.
- if fuzzModule.Config != nil {
+ if fuzzModule.Config != nil && IsValidConfig(fuzzModule, module.Name()) {
files = append(files, FileToZip{fuzzModule.Config, ""})
}
@@ -208,7 +267,7 @@
return string(b)
}
-func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, lang Lang, pctx android.PackageContext) {
+func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, fuzzType FuzzType, pctx android.PackageContext) {
var archOsList []ArchOs
for archOs := range archDirs {
archOsList = append(archOsList, archOs)
@@ -221,12 +280,15 @@
hostOrTarget := archOs.HostOrTarget
builder := android.NewRuleBuilder(pctx, ctx)
zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip"
- if lang == Rust {
+ if fuzzType == Rust {
zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip"
}
- if lang == Java {
+ if fuzzType == Java {
zipFileName = "fuzz-java-" + hostOrTarget + "-" + arch + ".zip"
}
+ if fuzzType == AFL {
+ zipFileName = "fuzz-afl-" + hostOrTarget + "-" + arch + ".zip"
+ }
outputFile := android.PathForOutput(ctx, zipFileName)
s.Packages = append(s.Packages, outputFile)
@@ -237,7 +299,6 @@
Flag("-L 0") // No need to try and re-compress the zipfiles.
for _, fileToZip := range filesToZip {
-
if fileToZip.DestinationPathPrefix != "" {
command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix)
} else {
@@ -256,6 +317,7 @@
for target, _ := range s.FuzzTargets {
fuzzTargets = append(fuzzTargets, target)
}
+
sort.Strings(fuzzTargets)
ctx.Strict(targets, strings.Join(fuzzTargets, " "))
}
diff --git a/java/aar.go b/java/aar.go
index 00ff7e7..dadfc6a 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -678,6 +678,10 @@
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)
}
@@ -889,7 +893,7 @@
return nil
}
-var _ android.PrebuiltInterface = (*Import)(nil)
+var _ android.PrebuiltInterface = (*AARImport)(nil)
// android_library_import imports an `.aar` file into the build graph as if it was built with android_library.
//
diff --git a/java/android_manifest.go b/java/android_manifest.go
index a297b2c..c61823d 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -136,6 +136,11 @@
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 @@
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 a391f64..94daf37 100644
--- a/java/base.go
+++ b/java/base.go
@@ -204,6 +204,10 @@
// 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 @@
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
}
@@ -1072,13 +1081,6 @@
kotlincFlags := j.properties.Kotlincflags
CheckKotlincFlags(ctx, kotlincFlags)
- // This is needed for code that depends on libraries that use @JvmDefault
- // -Xjvm-default=all will be the default in a future version of kotlin
- // according to https://blog.jetbrains.com/kotlin/2020/07/kotlin-1-4-m3-generating-default-methods-in-interfaces/
- if flags.javaVersion >= JAVA_VERSION_8 {
- kotlincFlags = append(kotlincFlags, "-Xjvm-default=all")
- }
-
// Workaround for KT-46512
kotlincFlags = append(kotlincFlags, "-Xsam-conversions=class")
diff --git a/java/dexpreopt.go_v1 b/java/dexpreopt.go_v1
deleted file mode 100644
index 0adaf99..0000000
--- 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 7c4da3e..b4cd07a 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -785,24 +785,26 @@
}
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 07a357b..0000000
--- 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 d71e2bb..0000000
--- 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 023d619..9663922 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -256,6 +256,10 @@
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 6e05159..dae69dc 100644
--- a/java/java.go
+++ b/java/java.go
@@ -118,6 +118,16 @@
copyEverythingToSnapshot,
}
+ snapshotRequiresImplementationJar = func(ctx android.SdkMemberContext) bool {
+ // In the S build the build will break if updatable-media does not provide a full implementation
+ // jar. That issue was fixed in Tiramisu by b/229932396.
+ if ctx.IsTargetBuildBeforeTiramisu() && ctx.Name() == "updatable-media" {
+ return true
+ }
+
+ return false
+ }
+
// Supports adding java boot libraries to module_exports and sdk.
//
// The build has some implicit dependencies (via the boot jars configuration) on a number of
@@ -135,13 +145,21 @@
SupportsSdk: true,
},
func(ctx android.SdkMemberContext, j *Library) android.Path {
+ if snapshotRequiresImplementationJar(ctx) {
+ return exportImplementationClassesJar(ctx, j)
+ }
+
// Java boot libs are only provided in the SDK to provide access to their dex implementation
// jar for use by dexpreopting and boot jars package check. They do not need to provide an
// actual implementation jar but the java_import will need a file that exists so just copy an
// empty file. Any attempt to use that file as a jar will cause a build error.
return ctx.SnapshotBuilder().EmptyFile()
},
- func(osPrefix, name string) string {
+ func(ctx android.SdkMemberContext, osPrefix, name string) string {
+ if snapshotRequiresImplementationJar(ctx) {
+ return sdkSnapshotFilePathForJar(ctx, osPrefix, name)
+ }
+
// Create a special name for the implementation jar to try and provide some useful information
// to a developer that attempts to compile against this.
// TODO(b/175714559): Provide a proper error message in Soong not ninja.
@@ -175,7 +193,7 @@
// file. Any attempt to use that file as a jar will cause a build error.
return ctx.SnapshotBuilder().EmptyFile()
},
- func(osPrefix, name string) string {
+ func(_ android.SdkMemberContext, osPrefix, name string) string {
// Create a special name for the implementation jar to try and provide some useful information
// to a developer that attempts to compile against this.
// TODO(b/175714559): Provide a proper error message in Soong not ninja.
@@ -672,7 +690,7 @@
)
// path to the jar file of a java library. Relative to <sdk_root>/<api_dir>
-func sdkSnapshotFilePathForJar(osPrefix, name string) string {
+func sdkSnapshotFilePathForJar(_ android.SdkMemberContext, osPrefix, name string) string {
return sdkSnapshotFilePathForMember(osPrefix, name, jarFileSuffix)
}
@@ -689,7 +707,7 @@
// Function to compute the snapshot relative path to which the named library's
// jar should be copied.
- snapshotPathGetter func(osPrefix, name string) string
+ snapshotPathGetter func(ctx android.SdkMemberContext, osPrefix, name string) string
// True if only the jar should be copied to the snapshot, false if the jar plus any additional
// files like aidl files should also be copied.
@@ -747,7 +765,7 @@
exportedJar := p.JarToExport
if exportedJar != nil {
// Delegate the creation of the snapshot relative path to the member type.
- snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(p.OsPrefix(), ctx.Name())
+ snapshotRelativeJavaLibPath := memberType.snapshotPathGetter(ctx, p.OsPrefix(), ctx.Name())
// Copy the exported jar to the snapshot.
builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
@@ -1213,7 +1231,7 @@
exportedJar := p.JarToExport
if exportedJar != nil {
- snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(p.OsPrefix(), ctx.Name())
+ snapshotRelativeJavaLibPath := sdkSnapshotFilePathForJar(ctx, p.OsPrefix(), ctx.Name())
builder.CopyToSnapshot(exportedJar, snapshotRelativeJavaLibPath)
propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
@@ -1459,6 +1477,10 @@
// 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.
@@ -1538,6 +1560,13 @@
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/lint.go b/java/lint.go
index e276345..c27ca98 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -338,6 +338,14 @@
ctx.PropertyErrorf("lint.disabled_checks",
"Can't disable %v checks if min_sdk_version is different from sdk_version.", filtered)
}
+
+ // TODO(b/238784089): Remove this workaround when the NewApi issues have been addressed in PermissionController
+ if ctx.ModuleName() == "PermissionController" {
+ l.extraMainlineLintErrors = android.FilterListPred(l.extraMainlineLintErrors, func(s string) bool {
+ return s != "NewApi"
+ })
+ l.properties.Lint.Warning_checks = append(l.properties.Lint.Warning_checks, "NewApi")
+ }
}
extraLintCheckModules := ctx.GetDirectDepsWithTag(extraLintCheckTag)
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index 1eee354..e99cb05 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -6,6 +6,7 @@
--disable_check AnimatorKeep
--disable_check AppBundleLocaleChanges
+--disable_check AppCompatCustomView
--disable_check BlockedPrivateApi
--disable_check CustomSplashScreen
--disable_check CustomX509TrustManager
@@ -22,6 +23,7 @@
--disable_check PrivateApi
--disable_check ProtectedPermissions
--disable_check QueryPermissionsNeeded
+--disable_check ReservedSystemPermission
--disable_check ScopedStorage
--disable_check ServiceCast
--disable_check SoonBlockedPrivateApi
@@ -99,7 +101,10 @@
--warning_check WrongViewCast # 1 occurences in 1 modules
--warning_check CoarseFineLocation
+--warning_check ExtraText
--warning_check IntentFilterExportedReceiver
+--warning_check MissingInflatedId
+--warning_check NotificationPermission
--warning_check QueryAllPackagesPermission
--warning_check RemoteViewLayout
--warning_check SupportAnnotationUsage
diff --git a/java/platform_compat_config.go b/java/platform_compat_config.go
index f442ddf..1c42495 100644
--- a/java/platform_compat_config.go
+++ b/java/platform_compat_config.go
@@ -26,12 +26,14 @@
func init() {
registerPlatformCompatConfigBuildComponents(android.InitRegistrationContext)
- android.RegisterSdkMemberType(&compatConfigMemberType{
- SdkMemberTypeBase: android.SdkMemberTypeBase{
- PropertyName: "compat_configs",
- SupportsSdk: true,
- },
- })
+ android.RegisterSdkMemberType(CompatConfigSdkMemberType)
+}
+
+var CompatConfigSdkMemberType = &compatConfigMemberType{
+ SdkMemberTypeBase: android.SdkMemberTypeBase{
+ PropertyName: "compat_configs",
+ SupportsSdk: true,
+ },
}
func registerPlatformCompatConfigBuildComponents(ctx android.RegistrationContext) {
diff --git a/java/rro.go b/java/rro.go
index be84aff..7952c2c 100644
--- a/java/rro.go
+++ b/java/rro.go
@@ -173,6 +173,10 @@
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/rust/OWNERS b/rust/OWNERS
index ddaebc5..b595511 100644
--- a/rust/OWNERS
+++ b/rust/OWNERS
@@ -1,5 +1,2 @@
# Additional owner/reviewers for rust rules, including parent directory owners.
per-file * = chiw@google.com, chriswailes@google.com, ivanlozano@google.com, jeffv@google.com, mmaurer@google.com, srhines@google.com
-
-# Limited owners/reviewers of the allowed list.
-per-file allowed_list.go = chiw@google.com, chriswailes@google.com, ivanlozano@google.com, jeffv@google.com, mmaurer@google.com, srhines@google.com
diff --git a/rust/bindgen.go b/rust/bindgen.go
index 4d723d6..72cc894 100644
--- a/rust/bindgen.go
+++ b/rust/bindgen.go
@@ -239,6 +239,11 @@
cflags = append(cflags, "-x c")
}
+ // LLVM_NEXT may contain flags that bindgen doesn't recognise. Turn off unknown flags warning.
+ if ctx.Config().IsEnvTrue("LLVM_NEXT") {
+ cflags = append(cflags, "-Wno-unknown-warning-option")
+ }
+
outputFile := android.PathForModuleOut(ctx, b.BaseSourceProvider.getStem(ctx)+".rs")
var cmd, cmdDesc string
diff --git a/rust/config/Android.bp b/rust/config/Android.bp
index ba40cb0..be73d69 100644
--- a/rust/config/Android.bp
+++ b/rust/config/Android.bp
@@ -16,7 +16,6 @@
"global.go",
"lints.go",
"toolchain.go",
- "allowed_list.go",
"darwin_host.go",
"x86_linux_bionic_host.go",
"x86_linux_host.go",
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
deleted file mode 100644
index 9129b0e..0000000
--- a/rust/config/allowed_list.go
+++ /dev/null
@@ -1,79 +0,0 @@
-package config
-
-var (
- // When adding a new path below, add a rustfmt.toml file at the root of
- // the repository and enable the rustfmt repo hook. See aosp/1458238
- // for an example.
- // TODO(b/160223496): enable rustfmt globally.
- RustAllowedPaths = []string{
- "device/google/cuttlefish",
- "external/adhd",
- "external/boringssl",
- "external/crosvm",
- "external/libchromeos-rs",
- "external/minijail",
- "external/open-dice",
- "external/rust",
- "external/selinux/libselinux",
- "external/uwb",
- "external/vm_tools/p9",
- "frameworks/native/libs/binder/rust",
- "frameworks/proto_logging/stats",
- "hardware/interfaces/security",
- "hardware/interfaces/uwb",
- "packages/modules/Bluetooth",
- "packages/modules/DnsResolver",
- "packages/modules/Uwb",
- "packages/modules/Virtualization",
- "platform_testing/tests/codecoverage/native/rust",
- "prebuilts/rust",
- "system/core/debuggerd/rust",
- "system/core/libstats/pull_rust",
- "system/core/trusty/libtrusty-rs",
- "system/core/trusty/keymint",
- "system/extras/profcollectd",
- "system/extras/simpleperf",
- "system/hardware/interfaces/keystore2",
- "system/keymint",
- "system/librustutils",
- "system/logging/liblog",
- "system/logging/rust",
- "system/nfc",
- "system/security",
- "system/tools/aidl",
- "tools/security/fuzzing/example_rust_fuzzer",
- "tools/security/fuzzing/orphans",
- "tools/security/remote_provisioning/cert_validator",
- "tools/vendor",
- "vendor/",
- }
-
- DownstreamRustAllowedPaths = []string{
- // Add downstream allowed Rust paths here.
- }
-
- RustModuleTypes = []string{
- // Don't add rust_bindgen or rust_protobuf as these are code generation modules
- // and can be expected to be in paths without Rust code.
- "rust_benchmark",
- "rust_benchmark_host",
- "rust_binary",
- "rust_binary_host",
- "rust_library",
- "rust_library_dylib",
- "rust_library_rlib",
- "rust_ffi",
- "rust_ffi_shared",
- "rust_ffi_static",
- "rust_fuzz",
- "rust_library_host",
- "rust_library_host_dylib",
- "rust_library_host_rlib",
- "rust_ffi_host",
- "rust_ffi_host_shared",
- "rust_ffi_host_static",
- "rust_proc_macro",
- "rust_test",
- "rust_test_host",
- }
-)
diff --git a/rust/config/global.go b/rust/config/global.go
index 3ef0ecb..9acbfb3 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -24,7 +24,7 @@
var pctx = android.NewPackageContext("android/soong/rust/config")
var (
- RustDefaultVersion = "1.61.0.p2"
+ RustDefaultVersion = "1.62.0.p1"
RustDefaultBase = "prebuilts/rust/"
DefaultEdition = "2021"
Stdlibs = []string{
diff --git a/rust/fuzz.go b/rust/fuzz.go
index 55921ba..586095c 100644
--- a/rust/fuzz.go
+++ b/rust/fuzz.go
@@ -153,7 +153,7 @@
sharedLibraries := fuzz.CollectAllSharedDependencies(ctx, module, cc.UnstrippedOutputFile, cc.IsValidSharedDependency)
// Package shared libraries
- files = append(files, cc.GetSharedLibsToZip(sharedLibraries, rustModule, &s.FuzzPackager, archString, &sharedLibraryInstalled)...)
+ files = append(files, cc.GetSharedLibsToZip(sharedLibraries, rustModule, &s.FuzzPackager, archString, "lib", &sharedLibraryInstalled)...)
archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs)
if !ok {
diff --git a/rust/rust.go b/rust/rust.go
index d5d4929..4d9fe4c 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -33,13 +33,6 @@
var pctx = android.NewPackageContext("android/soong/rust")
func init() {
- // Only allow rust modules to be defined for certain projects
-
- android.AddNeverAllowRules(
- android.NeverAllow().
- NotIn(append(config.RustAllowedPaths, config.DownstreamRustAllowedPaths...)...).
- ModuleType(config.RustModuleTypes...))
-
android.RegisterModuleType("rust_defaults", defaultsFactory)
android.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
ctx.BottomUp("rust_libraries", LibraryMutator).Parallel()
diff --git a/scripts/Android.bp b/scripts/Android.bp
index 4773579..814bd57 100644
--- a/scripts/Android.bp
+++ b/scripts/Android.bp
@@ -84,6 +84,16 @@
],
}
+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 @@
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 ba1109e..8bd8d45 100755
--- a/scripts/jsonmodify.py
+++ b/scripts/jsonmodify.py
@@ -59,6 +59,13 @@
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 @@
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 @@
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 @@
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 0000000..6f0291d
--- /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 2d3103b..2da29ee 100755
--- a/scripts/manifest_fixer.py
+++ b/scripts/manifest_fixer.py
@@ -39,6 +39,8 @@
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 @@
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 @@
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 199b279..dad104a 100755
--- a/scripts/manifest_fixer_test.py
+++ b/scripts/manifest_fixer_test.py
@@ -571,5 +571,77 @@
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/build_release.go b/sdk/build_release.go
index 4c2277e..0494a28 100644
--- a/sdk/build_release.go
+++ b/sdk/build_release.go
@@ -24,18 +24,22 @@
// buildRelease represents the version of a build system used to create a specific release.
//
-// The name of the release, is the same as the code for the dessert release, e.g. S, T, etc.
+// The name of the release, is the same as the code for the dessert release, e.g. S, Tiramisu, etc.
type buildRelease struct {
- // The name of the release, e.g. S, T, etc.
+ // The name of the release, e.g. S, Tiramisu, etc.
name string
// The index of this structure within the buildReleases list.
ordinal int
}
+func (br *buildRelease) EarlierThan(other *buildRelease) bool {
+ return br.ordinal < other.ordinal
+}
+
// String returns the name of the build release.
-func (s *buildRelease) String() string {
- return s.name
+func (br *buildRelease) String() string {
+ return br.name
}
// buildReleaseSet represents a set of buildRelease objects.
diff --git a/sdk/compat_config_sdk_test.go b/sdk/compat_config_sdk_test.go
index d166add..45e8e0e 100644
--- a/sdk/compat_config_sdk_test.go
+++ b/sdk/compat_config_sdk_test.go
@@ -21,16 +21,12 @@
"android/soong/java"
)
-func TestSnapshotWithCompatConfig(t *testing.T) {
+func testSnapshotWithCompatConfig(t *testing.T, sdk string) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
java.PrepareForTestWithPlatformCompatConfig,
- ).RunTestWithBp(t, `
- sdk {
- name: "mysdk",
- compat_configs: ["myconfig"],
- }
-
+ prepareForSdkTestWithApex,
+ ).RunTestWithBp(t, sdk+`
platform_compat_config {
name: "myconfig",
}
@@ -73,3 +69,28 @@
}),
)
}
+
+func TestSnapshotWithCompatConfig(t *testing.T) {
+ testSnapshotWithCompatConfig(t, `
+ sdk {
+ name: "mysdk",
+ compat_configs: ["myconfig"],
+ }
+`)
+}
+
+func TestSnapshotWithCompatConfig_Apex(t *testing.T) {
+ testSnapshotWithCompatConfig(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ min_sdk_version: "2",
+ compat_configs: ["myconfig"],
+ }
+
+ sdk {
+ name: "mysdk",
+ apexes: ["myapex"],
+ }
+`)
+}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index d25138f..7ab5285 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -15,6 +15,7 @@
package sdk
import (
+ "fmt"
"testing"
"android/soong/android"
@@ -257,8 +258,8 @@
android.FixtureAddFile("aidl", nil),
android.FixtureAddFile("resource.txt", nil),
).RunTestWithBp(t, `
- module_exports {
- name: "myexports",
+ sdk {
+ name: "mysdk",
java_boot_libs: ["myjavalib"],
}
@@ -278,7 +279,7 @@
}
`)
- CheckSnapshot(t, result, "myexports", "",
+ CheckSnapshot(t, result, "mysdk", "",
checkAndroidBpContents(`
// This is auto-generated. DO NOT EDIT.
@@ -292,11 +293,65 @@
}
`),
checkAllCopyRules(`
-.intermediates/myexports/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar
`),
)
}
+func TestSnapshotWithJavaBootLibrary_UpdatableMedia(t *testing.T) {
+ runTest := func(t *testing.T, targetBuildRelease, expectedJarPath, expectedCopyRule string) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ android.FixtureMergeEnv(map[string]string{
+ "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": targetBuildRelease,
+ }),
+ ).RunTestWithBp(t, `
+ sdk {
+ name: "mysdk",
+ java_boot_libs: ["updatable-media"],
+ }
+
+ java_library {
+ name: "updatable-media",
+ srcs: ["Test.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ permitted_packages: ["pkg.media"],
+ apex_available: ["com.android.media"],
+ }
+ `)
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkAndroidBpContents(fmt.Sprintf(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "updatable-media",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["com.android.media"],
+ jars: ["%s"],
+ permitted_packages: ["pkg.media"],
+}
+`, expectedJarPath)),
+ checkAllCopyRules(expectedCopyRule),
+ )
+ }
+
+ t.Run("updatable-media in S", func(t *testing.T) {
+ runTest(t, "S", "java/updatable-media.jar", `
+.intermediates/updatable-media/android_common/package-check/updatable-media.jar -> java/updatable-media.jar
+`)
+ })
+
+ t.Run("updatable-media in T", func(t *testing.T) {
+ runTest(t, "Tiramisu", "java_boot_libs/snapshot/jars/are/invalid/updatable-media.jar", `
+.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/updatable-media.jar
+`)
+ })
+}
+
func TestSnapshotWithJavaSystemserverLibrary(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
@@ -1284,9 +1339,9 @@
.intermediates/myjavalib.stubs.source.module_lib/android_common/metalava/myjavalib.stubs.source.module_lib_removed.txt -> sdk_library/module-lib/myjavalib-removed.txt
`),
checkMergeZips(
+ ".intermediates/mysdk/common_os/tmp/sdk_library/module-lib/myjavalib_stub_sources.zip",
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
".intermediates/mysdk/common_os/tmp/sdk_library/system/myjavalib_stub_sources.zip",
- ".intermediates/mysdk/common_os/tmp/sdk_library/module-lib/myjavalib_stub_sources.zip",
),
)
}
diff --git a/sdk/update.go b/sdk/update.go
index b9ef3d0..c555ddc 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -108,7 +108,7 @@
mergeZips = pctx.AndroidStaticRule("SnapshotMergeZips",
blueprint.RuleParams{
- Command: `${config.MergeZipsCmd} $out $in`,
+ Command: `${config.MergeZipsCmd} -s $out $in`,
CommandDeps: []string{
"${config.MergeZipsCmd}",
},
@@ -481,7 +481,7 @@
// Copy the build number file into the snapshot.
builder.CopyToSnapshot(ctx.Config().BuildNumberFile(ctx), BUILD_NUMBER_FILE)
- filesToZip := builder.filesToZip
+ filesToZip := android.SortedUniquePaths(builder.filesToZip)
// zip them all
zipPath := fmt.Sprintf("%s%s.zip", ctx.ModuleName(), snapshotFileSuffix)
@@ -517,7 +517,7 @@
Description: outputDesc,
Rule: mergeZips,
Input: zipFile,
- Inputs: builder.zipsToMerge,
+ Inputs: android.SortedUniquePaths(builder.zipsToMerge),
Output: outputZipFile,
})
}
@@ -1972,6 +1972,12 @@
return m.requiredTraits.Contains(trait)
}
+func (m *memberContext) IsTargetBuildBeforeTiramisu() bool {
+ return m.builder.targetBuildRelease.EarlierThan(buildReleaseT)
+}
+
+var _ android.SdkMemberContext = (*memberContext)(nil)
+
func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModule *bpModule) {
memberType := member.memberType
diff --git a/ui/build/Android.bp b/ui/build/Android.bp
index 3dc87f5..cfcf804 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -34,15 +34,16 @@
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/cleanbuild.go b/ui/build/cleanbuild.go
index 1c80cff..fd60177 100644
--- a/ui/build/cleanbuild.go
+++ b/ui/build/cleanbuild.go
@@ -167,6 +167,7 @@
productOut("debug_ramdisk"),
productOut("vendor_ramdisk"),
productOut("vendor_debug_ramdisk"),
+ productOut("vendor_kernel_ramdisk"),
productOut("test_harness_ramdisk"),
productOut("recovery"),
productOut("root"),
diff --git a/ui/build/rbe.go b/ui/build/rbe.go
index 82fc15f..6231e52 100644
--- a/ui/build/rbe.go
+++ b/ui/build/rbe.go
@@ -21,6 +21,7 @@
"runtime"
"strings"
+ "android/soong/remoteexec"
"android/soong/ui/metrics"
)
@@ -54,11 +55,12 @@
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/terminal/simple_status.go b/ui/terminal/simple_status.go
index cef3b5d..9e9ffc0 100644
--- a/ui/terminal/simple_status.go
+++ b/ui/terminal/simple_status.go
@@ -22,30 +22,24 @@
)
type simpleStatusOutput struct {
- writer io.Writer
- formatter formatter
- keepANSI bool
- outputLevel status.MsgLevel
+ writer io.Writer
+ formatter formatter
+ keepANSI bool
}
// NewSimpleStatusOutput returns a StatusOutput that represents the
// current build status similarly to Ninja's built-in terminal
// output.
-func NewSimpleStatusOutput(w io.Writer, formatter formatter, keepANSI bool, quietBuild bool) status.StatusOutput {
- level := status.StatusLvl
- if quietBuild {
- level = status.PrintLvl
- }
+func NewSimpleStatusOutput(w io.Writer, formatter formatter, keepANSI bool) status.StatusOutput {
return &simpleStatusOutput{
- writer: w,
- formatter: formatter,
- keepANSI: keepANSI,
- outputLevel: level,
+ writer: w,
+ formatter: formatter,
+ keepANSI: keepANSI,
}
}
func (s *simpleStatusOutput) Message(level status.MsgLevel, message string) {
- if level >= s.outputLevel {
+ if level >= status.StatusLvl {
output := s.formatter.message(level, message)
if !s.keepANSI {
output = string(stripAnsiEscapes([]byte(output)))
@@ -54,13 +48,10 @@
}
}
-func (s *simpleStatusOutput) StartAction(_ *status.Action, _ status.Counts) {
+func (s *simpleStatusOutput) StartAction(action *status.Action, counts status.Counts) {
}
func (s *simpleStatusOutput) FinishAction(result status.ActionResult, counts status.Counts) {
- if s.outputLevel > status.StatusLvl {
- return
- }
str := result.Description
if str == "" {
str = result.Command
diff --git a/ui/terminal/status.go b/ui/terminal/status.go
index ff0af47..2ad174f 100644
--- a/ui/terminal/status.go
+++ b/ui/terminal/status.go
@@ -29,9 +29,9 @@
func NewStatusOutput(w io.Writer, statusFormat string, forceSimpleOutput, quietBuild, forceKeepANSI bool) status.StatusOutput {
formatter := newFormatter(statusFormat, quietBuild)
- if forceSimpleOutput || quietBuild || !isSmartTerminal(w) {
- return NewSimpleStatusOutput(w, formatter, forceKeepANSI, quietBuild)
- } else {
+ if !forceSimpleOutput && isSmartTerminal(w) {
return NewSmartStatusOutput(w, formatter)
+ } else {
+ return NewSimpleStatusOutput(w, formatter, forceKeepANSI)
}
}