Merge "Revert "Disable hiddenapi check for building from prebuilts."" into main
diff --git a/README.md b/README.md
index 22daa95..5e9e04a 100644
--- a/README.md
+++ b/README.md
@@ -648,8 +648,8 @@
SOONG_DELVE=2345 SOONG_DELVE_STEPS='build,modulegraph' m
```
results in only `build` (main build step) and `modulegraph` being run in the debugger.
-The allowed step names are `api_bp2build`, `bp2build_files`, `bp2build_workspace`,
-`build`, `modulegraph`, `queryview`, `soong_docs`.
+The allowed step names are `bp2build_files`, `bp2build_workspace`, `build`,
+`modulegraph`, `queryview`, `soong_docs`.
Note setting or unsetting `SOONG_DELVE` causes a recompilation of `soong_build`. This
is because in order to debug the binary, it needs to be built with debug
diff --git a/aconfig/java_aconfig_library.go b/aconfig/java_aconfig_library.go
index 4db0ef7..48cfb76 100644
--- a/aconfig/java_aconfig_library.go
+++ b/aconfig/java_aconfig_library.go
@@ -15,10 +15,13 @@
package aconfig
import (
- "android/soong/android"
- "android/soong/java"
"fmt"
+
+ "android/soong/android"
+ "android/soong/bazel"
+ "android/soong/java"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
type declarationsTagType struct {
@@ -32,7 +35,7 @@
Aconfig_declarations string
// whether to generate test mode version of the library
- Test bool
+ Test *bool
}
type JavaAconfigDeclarationsLibraryCallbacks struct {
@@ -68,7 +71,7 @@
// Generate the action to build the srcjar
srcJarPath := android.PathForModuleGen(ctx, ctx.ModuleName()+".srcjar")
var mode string
- if callbacks.properties.Test {
+ if proptools.Bool(callbacks.properties.Test) {
mode = "test"
} else {
mode = "production"
@@ -89,3 +92,39 @@
return srcJarPath
}
+
+type bazelJavaAconfigLibraryAttributes struct {
+ Aconfig_declarations bazel.LabelAttribute
+ Test *bool
+ Sdk_version *string
+}
+
+func (callbacks *JavaAconfigDeclarationsLibraryCallbacks) Bp2build(ctx android.Bp2buildMutatorContext, module *java.GeneratedJavaLibraryModule) {
+ if ctx.ModuleType() != "java_aconfig_library" {
+ return
+ }
+
+ // By default, soong builds the aconfig java library with private_current, however
+ // bazel currently doesn't support it so we default it to system_current. One reason
+ // is that the dependency of all java_aconfig_library aconfig-annotations-lib is
+ // built with system_current. For the java aconfig library itself it doesn't really
+ // matter whether it uses private API or system API because the only module it uses
+ // is DeviceConfig which is in system, and the rdeps of the java aconfig library
+ // won't change its sdk version either, so this should be fine.
+ // Ideally we should only use the default value if it is not set by the user, but
+ // bazel only supports a limited sdk versions, for example, the java_aconfig_library
+ // modules in framework/base use core_platform which is not supported by bazel yet.
+ // TODO(b/302148527): change soong to default to system_current as well.
+ sdkVersion := "system_current"
+ attrs := bazelJavaAconfigLibraryAttributes{
+ Aconfig_declarations: *bazel.MakeLabelAttribute(android.BazelLabelForModuleDepSingle(ctx, callbacks.properties.Aconfig_declarations).Label),
+ Test: callbacks.properties.Test,
+ Sdk_version: &sdkVersion,
+ }
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "java_aconfig_library",
+ Bzl_load_location: "//build/bazel/rules/java:java_aconfig_library.bzl",
+ }
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: ctx.ModuleName()}, &attrs)
+}
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index 4d1b3b0..7077f56 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -75,14 +75,17 @@
"build/soong/cc/libbuildversion": Bp2BuildDefaultTrue, // Skip tests subdir
"build/soong/cc/ndkstubgen": Bp2BuildDefaultTrue,
"build/soong/cc/symbolfile": Bp2BuildDefaultTrue,
+ "build/soong/jar": Bp2BuildDefaultTrue,
"build/soong/licenses": Bp2BuildDefaultTrue,
"build/soong/linkerconfig": Bp2BuildDefaultTrueRecursively,
+ "build/soong/response": Bp2BuildDefaultTrue,
"build/soong/scripts": Bp2BuildDefaultTrueRecursively,
+ "build/soong/third_party/zip": Bp2BuildDefaultTrue,
"cts/common/device-side/nativetesthelper/jni": Bp2BuildDefaultTrueRecursively,
- "cts/libs/json": Bp2BuildDefaultTrueRecursively,
- "cts/tests/tests/gesture": Bp2BuildDefaultTrueRecursively,
- "platform_testing/libraries/annotations": Bp2BuildDefaultTrueRecursively,
+ "cts/flags/cc_tests": Bp2BuildDefaultTrueRecursively,
+ "cts/libs/json": Bp2BuildDefaultTrueRecursively,
+ "cts/tests/tests/gesture": Bp2BuildDefaultTrueRecursively,
"dalvik/tools/dexdeps": Bp2BuildDefaultTrueRecursively,
@@ -139,6 +142,7 @@
"external/bzip2": Bp2BuildDefaultTrueRecursively,
"external/clang/lib": Bp2BuildDefaultTrue,
"external/conscrypt": Bp2BuildDefaultTrue,
+ "external/dexmaker": Bp2BuildDefaultTrueRecursively,
"external/e2fsprogs": Bp2BuildDefaultTrueRecursively,
"external/eigen": Bp2BuildDefaultTrueRecursively,
"external/erofs-utils": Bp2BuildDefaultTrueRecursively,
@@ -191,6 +195,7 @@
"external/lzma/C": Bp2BuildDefaultTrueRecursively,
"external/mdnsresponder": Bp2BuildDefaultTrueRecursively,
"external/minijail": Bp2BuildDefaultTrueRecursively,
+ "external/mockito": Bp2BuildDefaultTrueRecursively,
"external/musl": Bp2BuildDefaultTrueRecursively,
"external/objenesis": Bp2BuildDefaultTrueRecursively,
"external/openscreen": Bp2BuildDefaultTrueRecursively,
@@ -213,6 +218,7 @@
"external/tinyalsa": Bp2BuildDefaultTrueRecursively,
"external/tinyalsa_new": Bp2BuildDefaultTrueRecursively,
"external/toybox": Bp2BuildDefaultTrueRecursively,
+ "external/xz-java": Bp2BuildDefaultTrueRecursively,
"external/zlib": Bp2BuildDefaultTrueRecursively,
"external/zopfli": Bp2BuildDefaultTrueRecursively,
"external/zstd": Bp2BuildDefaultTrueRecursively,
@@ -230,9 +236,11 @@
"frameworks/av/services/minijail": Bp2BuildDefaultTrueRecursively,
"frameworks/base/apex/jobscheduler/service/jni": Bp2BuildDefaultTrueRecursively,
"frameworks/base/core/java": Bp2BuildDefaultTrue,
+ "frameworks/base/core/res": Bp2BuildDefaultTrueRecursively,
"frameworks/base/libs/androidfw": Bp2BuildDefaultTrue,
"frameworks/base/libs/services": Bp2BuildDefaultTrue,
"frameworks/base/media/tests/MediaDump": Bp2BuildDefaultTrue,
+ "frameworks/base/mime": Bp2BuildDefaultTrueRecursively,
"frameworks/base/proto": Bp2BuildDefaultTrue,
"frameworks/base/services/tests/servicestests/aidl": Bp2BuildDefaultTrue,
"frameworks/base/startop/apps/test": Bp2BuildDefaultTrue,
@@ -242,6 +250,8 @@
"frameworks/base/tools/codegen": Bp2BuildDefaultTrueRecursively,
"frameworks/base/tools/locked_region_code_injection": Bp2BuildDefaultTrueRecursively,
"frameworks/base/tools/streaming_proto": Bp2BuildDefaultTrueRecursively,
+ "frameworks/hardware/interfaces": Bp2BuildDefaultTrue,
+ "frameworks/hardware/interfaces/displayservice": Bp2BuildDefaultTrueRecursively,
"frameworks/hardware/interfaces/stats/aidl": Bp2BuildDefaultTrue,
"frameworks/libs/modules-utils/build": Bp2BuildDefaultTrueRecursively,
"frameworks/libs/modules-utils/java": Bp2BuildDefaultTrue,
@@ -275,6 +285,7 @@
"hardware/interfaces/configstore/1.0": Bp2BuildDefaultTrue,
"hardware/interfaces/configstore/1.1": Bp2BuildDefaultTrue,
"hardware/interfaces/configstore/utils": Bp2BuildDefaultTrue,
+ "hardware/interfaces/contexthub/aidl": Bp2BuildDefaultTrue,
"hardware/interfaces/graphics/allocator/2.0": Bp2BuildDefaultTrue,
"hardware/interfaces/graphics/allocator/3.0": Bp2BuildDefaultTrue,
"hardware/interfaces/graphics/allocator/4.0": Bp2BuildDefaultTrue,
@@ -307,35 +318,41 @@
"hardware/interfaces/neuralnetworks/1.2/vts": Bp2BuildDefaultFalseRecursively,
"hardware/interfaces/neuralnetworks/1.3/vts": Bp2BuildDefaultFalseRecursively,
"hardware/interfaces/neuralnetworks/1.4/vts": Bp2BuildDefaultFalseRecursively,
+ "hardware/interfaces/tests": Bp2BuildDefaultTrueRecursively,
+ "hardware/interfaces/tests/extension": Bp2BuildDefaultFalseRecursively, // missing deps
+ "hardware/interfaces/tests/msgq": Bp2BuildDefaultFalseRecursively, // missing deps
"libnativehelper": Bp2BuildDefaultTrueRecursively,
- "packages/apps/DevCamera": Bp2BuildDefaultTrue,
- "packages/apps/HTMLViewer": Bp2BuildDefaultTrue,
- "packages/apps/Protips": Bp2BuildDefaultTrue,
- "packages/apps/SafetyRegulatoryInfo": Bp2BuildDefaultTrue,
- "packages/apps/WallpaperPicker": Bp2BuildDefaultTrue,
- "packages/modules/NeuralNetworks/driver/cache": Bp2BuildDefaultTrueRecursively,
- "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively,
- "packages/modules/adb": Bp2BuildDefaultTrue,
- "packages/modules/adb/apex": Bp2BuildDefaultTrue,
- "packages/modules/adb/fastdeploy": 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/modules/Connectivity/staticlibs/native": Bp2BuildDefaultTrueRecursively,
- "packages/modules/Gki/libkver": Bp2BuildDefaultTrue,
- "packages/modules/NetworkStack/common/captiveportal": Bp2BuildDefaultTrue,
- "packages/modules/NeuralNetworks/apex": Bp2BuildDefaultTrue,
- "packages/modules/NeuralNetworks/apex/testing": Bp2BuildDefaultTrue,
- "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultFalse, // TODO(b/242834374)
- "packages/screensavers/Basic": Bp2BuildDefaultTrue,
- "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321)
+ "packages/apps/DevCamera": Bp2BuildDefaultTrue,
+ "packages/apps/HTMLViewer": Bp2BuildDefaultTrue,
+ "packages/apps/Protips": Bp2BuildDefaultTrue,
+ "packages/apps/SafetyRegulatoryInfo": Bp2BuildDefaultTrue,
+ "packages/apps/WallpaperPicker": Bp2BuildDefaultTrue,
+ "packages/modules/NeuralNetworks/driver/cache": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/StatsD/lib/libstatssocket": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/adb": Bp2BuildDefaultTrue,
+ "packages/modules/adb/apex": Bp2BuildDefaultTrue,
+ "packages/modules/adb/fastdeploy": 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/modules/Connectivity/staticlibs/native": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Connectivity/staticlibs/netd/libnetdutils": Bp2BuildDefaultTrueRecursively,
+ "packages/modules/Gki/libkver": Bp2BuildDefaultTrue,
+ "packages/modules/NetworkStack/common/captiveportal": Bp2BuildDefaultTrue,
+ "packages/modules/NeuralNetworks/apex": Bp2BuildDefaultTrue,
+ "packages/modules/NeuralNetworks/apex/testing": Bp2BuildDefaultTrue,
+ "packages/providers/MediaProvider/tools/dialogs": Bp2BuildDefaultFalse, // TODO(b/242834374)
+ "packages/screensavers/Basic": Bp2BuildDefaultTrue,
+ "packages/services/Car/tests/SampleRearViewCamera": Bp2BuildDefaultFalse, // TODO(b/242834321)
- "platform_testing/tests/example": Bp2BuildDefaultTrueRecursively,
+ "platform_testing/libraries/annotations": Bp2BuildDefaultTrueRecursively,
+ "platform_testing/libraries/flag-helpers/libflagtest": Bp2BuildDefaultTrueRecursively,
+ "platform_testing/tests/example": Bp2BuildDefaultTrueRecursively,
"prebuilts/clang/host/linux-x86": Bp2BuildDefaultTrueRecursively,
"prebuilts/gradle-plugin": Bp2BuildDefaultTrueRecursively,
@@ -373,6 +390,7 @@
"system/core/libprocessgroup/cgrouprc": Bp2BuildDefaultTrue,
"system/core/libprocessgroup/cgrouprc_format": Bp2BuildDefaultTrue,
"system/core/libsparse": Bp2BuildDefaultTrueRecursively,
+ "system/core/libstats/expresslog": Bp2BuildDefaultTrueRecursively,
"system/core/libsuspend": Bp2BuildDefaultTrue,
"system/core/libsystem": Bp2BuildDefaultTrueRecursively,
"system/core/libsysutils": Bp2BuildDefaultTrueRecursively,
@@ -398,8 +416,7 @@
"system/libhidl/transport/manager/1.0": Bp2BuildDefaultTrue,
"system/libhidl/transport/manager/1.1": Bp2BuildDefaultTrue,
"system/libhidl/transport/manager/1.2": Bp2BuildDefaultTrue,
- "system/libhidl/transport/memory/1.0": Bp2BuildDefaultTrue,
- "system/libhidl/transport/memory/token/1.0": Bp2BuildDefaultTrue,
+ "system/libhidl/transport/memory": Bp2BuildDefaultTrueRecursively,
"system/libhidl/transport/safe_union/1.0": Bp2BuildDefaultTrue,
"system/libhidl/transport/token/1.0": Bp2BuildDefaultTrue,
"system/libhidl/transport/token/1.0/utils": Bp2BuildDefaultTrue,
@@ -409,14 +426,14 @@
"system/libziparchive": Bp2BuildDefaultTrueRecursively,
"system/logging": Bp2BuildDefaultTrueRecursively,
"system/media": Bp2BuildDefaultTrue,
- "system/media/audio": Bp2BuildDefaultTrueRecursively,
"system/media/alsa_utils": Bp2BuildDefaultTrueRecursively,
+ "system/media/audio": Bp2BuildDefaultTrueRecursively,
"system/media/audio_utils": Bp2BuildDefaultTrueRecursively,
"system/media/camera": Bp2BuildDefaultTrueRecursively,
"system/memory/libion": Bp2BuildDefaultTrueRecursively,
"system/memory/libmemunreachable": Bp2BuildDefaultTrueRecursively,
- "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively,
"system/security/fsverity": Bp2BuildDefaultTrueRecursively,
+ "system/sepolicy/apex": Bp2BuildDefaultTrueRecursively,
"system/testing/gtest_extras": Bp2BuildDefaultTrueRecursively,
"system/timezone/apex": Bp2BuildDefaultTrueRecursively,
"system/timezone/output_data": Bp2BuildDefaultTrueRecursively,
@@ -424,13 +441,14 @@
"system/timezone/testing": Bp2BuildDefaultTrueRecursively,
"system/tools/aidl/build/tests_bp2build": Bp2BuildDefaultTrue,
"system/tools/aidl/metadata": Bp2BuildDefaultTrue,
- "system/tools/hidl/metadata": Bp2BuildDefaultTrue,
- "system/tools/hidl/utils": Bp2BuildDefaultTrue,
+ "system/tools/hidl": Bp2BuildDefaultTrueRecursively,
"system/tools/mkbootimg": Bp2BuildDefaultTrueRecursively,
"system/tools/sysprop": Bp2BuildDefaultTrue,
"system/tools/xsdc/utils": Bp2BuildDefaultTrueRecursively,
"system/unwinding/libunwindstack": Bp2BuildDefaultTrueRecursively,
+ "test/vts/vts_hal_hidl_target": Bp2BuildDefaultTrueRecursively,
+
"tools/apifinder": Bp2BuildDefaultTrue,
"tools/apksig": Bp2BuildDefaultTrue,
"tools/dexter/slicer": Bp2BuildDefaultTrueRecursively,
@@ -438,6 +456,7 @@
"tools/metalava": Bp2BuildDefaultTrueRecursively,
"tools/platform-compat/java/android/compat": Bp2BuildDefaultTrueRecursively,
"tools/platform-compat/java/androidprocessor": Bp2BuildDefaultTrueRecursively,
+ "tools/tradefederation/core/util_apps": Bp2BuildDefaultTrueRecursively,
"tools/tradefederation/prebuilts/filegroups": Bp2BuildDefaultTrueRecursively,
}
@@ -463,6 +482,7 @@
"external/bazelbuild-rules_go":/* recursive = */ true,
"external/bazelbuild-rules_python":/* recursive = */ true,
"external/bazelbuild-rules_rust":/* recursive = */ true,
+ "external/bazelbuild-rules_testing":/* recursive = */ true,
"external/bazelbuild-kotlin-rules":/* recursive = */ true,
"external/bazel-skylib":/* recursive = */ true,
"external/protobuf":/* recursive = */ false,
@@ -484,6 +504,7 @@
"prebuilts/clang-tools":/* recursive = */ true,
"prebuilts/gcc":/* recursive = */ true,
"prebuilts/build-tools":/* recursive = */ true,
+ "prebuilts/jdk/jdk8":/* recursive = */ true,
"prebuilts/jdk/jdk17":/* recursive = */ true,
"prebuilts/misc":/* recursive = */ false, // not recursive because we need bp2build converted build files in prebuilts/misc/common/asm
"prebuilts/sdk":/* recursive = */ false,
@@ -556,13 +577,8 @@
// ext
"tagsoup",
- // framework-res
- "remote-color-resources-compile-public",
- "remote-color-resources-compile-colors",
-
// framework-minus-apex
"ImmutabilityAnnotationProcessor",
- "android.mime.types.minimized",
"debian.mime.types.minimized",
"framework-javastream-protos",
"libview-inspector-annotation-processor",
@@ -571,7 +587,6 @@
"apache-commons-math",
"cbor-java",
"icu4j_calendar_astronomer",
- "remote-color-resources-compile-public",
"statslog-art-java-gen",
"AndroidCommonLint",
@@ -619,7 +634,6 @@
"libneuralnetworks",
"libneuralnetworks_static",
"libgraphicsenv",
- "libhardware",
"libhardware_headers",
"libnativeloader-headers",
"libnativewindow_headers",
@@ -895,7 +909,6 @@
"libRSDispatch",
// hal_unit_tests and deps
- "android.hardware.contexthub_interface", // created implicitly by android.hardware.contexthub
"chre_flatbuffers",
"event_logger",
"hal_unit_tests",
@@ -923,11 +936,10 @@
"androidx.test.annotation-nodeps",
// jni deps of an internal android_test (b/297405812)
- "libdexmakerjvmtiagent",
"libopenjdkjvmti_headers",
- "libstaticjvmtiagent",
// tradefed deps
+ "apache-commons-compress",
"tradefed-protos",
"grpc-java",
"grpc-java-api",
@@ -949,6 +961,39 @@
"GsonBuildConfig.java",
"gson_version_generator",
"lab-resource-grpc",
+ "blueprint-deptools",
+ "protoc-gen-grpc-java-plugin",
+ "perfetto_trace-full",
+ "tf-remote-client",
+ "truth",
+ "tradefed-lite",
+ "tradefed-isolation-protos",
+ "snakeyaml_patched_src_files",
+ "asuite_proto_java",
+ "tradefed-service-grpc-lib",
+ "tradefed-invocation-grpc",
+ "tradefed-external-dependencies",
+ "tradefed-dynamic-sharding-grpc",
+ "tradefed-device-manager-grpc",
+ "statsd_internal_protos",
+ "snakeyaml",
+ "loganalysis",
+ "junit-params",
+ "grpc-java-testing",
+ "grpc-java-netty-shaded",
+ "aoa-helper",
+ "test-services.apk",
+ "test-composers",
+ "py3-stdlib-prebuilt-srcs",
+ "platformprotos",
+ "perfetto_metrics-full",
+ "test-services-normalized.apk",
+ "tradefed-common-util",
+ "tradefed-clearcut-client",
+ "tradefed-result-interfaces",
+ "tradefed-device-build-interfaces",
+ "tradefed-invocation-interfaces",
+ "tradefed-lib-core",
}
Bp2buildModuleTypeAlwaysConvertList = []string{
@@ -965,6 +1010,7 @@
"cc_prebuilt_library_static",
"combined_apis",
"droiddoc_exported_dir",
+ "java_aconfig_library",
"java_import",
"java_import_host",
"java_sdk_library",
@@ -974,6 +1020,7 @@
"ndk_headers",
"ndk_library",
"sysprop_library",
+ "versioned_ndk_headers",
"xsd_config",
// go/keep-sorted end
}
@@ -1000,6 +1047,8 @@
"libfsverity_rs",
"libtombstoned_client_rust",
+ "libhardware", //Depends on unconverted libapexsupport
+
// TODO(b/263326760): Failed already.
"minijail_compiler_unittest",
"minijail_parser_unittest",
@@ -1062,20 +1111,22 @@
"libtombstoned_client_rust_bridge_code", "libtombstoned_client_wrapper", // rust conversions are not supported
// unconverted deps
- "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
- "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi
- "android_icu4j_srcgen", // depends on unconverted modules: currysrc
- "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc
- "apex_compression_test", // depends on unconverted modules: soong_zip, com.android.example.apex
- "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full
- "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex
- "art-script", // depends on unconverted modules: dalvikvm, dex2oat
- "bin2c_fastdeployagent", // depends on unconverted modules: deployagent
- "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig
- "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9
- "dex2oat-script", // depends on unconverted modules: dex2oat
- "generated_android_icu4j_resources", // depends on unconverted modules: android_icu4j_srcgen_binary
- "generated_android_icu4j_test_resources", // depends on unconverted modules: android_icu4j_srcgen_binary
+ "CarHTMLViewer", // depends on unconverted modules android.car-stubs, car-ui-lib
+ "adb", // depends on unconverted modules: AdbWinApi, libandroidfw, libopenscreen-discovery, libopenscreen-platform-impl, libusb, bin2c_fastdeployagent, AdbWinUsbApi
+ "android_icu4j_srcgen", // depends on unconverted modules: currysrc
+ "android_icu4j_srcgen_binary", // depends on unconverted modules: android_icu4j_srcgen, currysrc
+ "apex_compression_test", // depends on unconverted modules: soong_zip, com.android.example.apex
+ "apex_manifest_proto_java", // b/210751803, depends on libprotobuf-java-full
+ "apexer_with_DCLA_preprocessing_test", // depends on unconverted modules: apexer_test_host_tools, com.android.example.apex
+ "art-script", // depends on unconverted modules: dalvikvm, dex2oat
+ "bin2c_fastdeployagent", // depends on unconverted modules: deployagent
+ "com.android.runtime", // depends on unconverted modules: bionic-linker-config, linkerconfig
+ "currysrc", // depends on unconverted modules: currysrc_org.eclipse, guavalib, jopt-simple-4.9
+ "dex2oat-script", // depends on unconverted modules: dex2oat
+ "generated_android_icu4j_resources", // depends on unconverted modules: android_icu4j_srcgen_binary
+ "generated_android_icu4j_test_resources", // depends on unconverted modules: android_icu4j_srcgen_binary
+ "hidl_system_api_test",
+ "hidl_test_java",
"host-libprotobuf-java-nano", // b/220869005, depends on libprotobuf-java-nano
"jacoco-stubs", // b/245767077, depends on droidstubs
"libapexutil", // depends on unconverted modules: apex-info-list-tinyxml
@@ -1658,6 +1709,7 @@
// python_test_host with test data
"sbom_writers_test",
+ "hidl_test",
// TODO(B/283193845): tradefed and its java_test_host dependents
"tradefed",
@@ -1715,6 +1767,13 @@
"NanoAndroidTest",
"MtsLibnativehelperTestCases",
+ // Depends on androidx.test.rules
+ "DexmakerTests",
+ "dexmaker-tests-lib",
+ "dexmaker-mockmaker-tests",
+ "dexmaker-inline-mockmaker-tests",
+ "dexmaker-extended-mockmaker-tests",
+
// android_test_helper_app from allowlisted packages, but with unconverted deps
"SharedLibraryInfoTestApp",
}
@@ -1779,18 +1838,4 @@
"art_": DEFAULT_PRIORITIZED_WEIGHT,
"ndk_library": DEFAULT_PRIORITIZED_WEIGHT,
}
-
- BazelSandwichTargets = []struct {
- Label string
- Host bool
- }{
- {
- Label: "//build/bazel/examples/partitions:system_image",
- Host: false,
- },
- {
- Label: "//build/bazel/examples/partitions:run_test",
- Host: false,
- },
- }
)
diff --git a/android/apex.go b/android/apex.go
index d84499b..c6d9940 100644
--- a/android/apex.go
+++ b/android/apex.go
@@ -482,7 +482,9 @@
}
return InList(what, apex_available) ||
(what != AvailableToPlatform && InList(AvailableToAnyApex, apex_available)) ||
- (strings.HasPrefix(what, "com.android.gki.") && InList(AvailableToGkiApex, apex_available))
+ (strings.HasPrefix(what, "com.android.gki.") && InList(AvailableToGkiApex, apex_available)) ||
+ (what == "com.google.mainline.primary.libs") || // TODO b/248601389
+ (what == "com.google.mainline.go.primary.libs") // TODO b/248601389
}
// Implements ApexModule
diff --git a/android/api_domain.go b/android/api_domain.go
index 0603c70..0a66c3d 100644
--- a/android/api_domain.go
+++ b/android/api_domain.go
@@ -14,20 +14,6 @@
package android
-import (
- "github.com/google/blueprint"
-
- "android/soong/bazel"
-)
-
-func init() {
- RegisterApiDomainBuildComponents(InitRegistrationContext)
-}
-
-func RegisterApiDomainBuildComponents(ctx RegistrationContext) {
- ctx.RegisterModuleType("api_domain", ApiDomainFactory)
-}
-
type ApiSurface int
// TODO(b/246656800): Reconcile with android.SdkKind
@@ -50,60 +36,3 @@
return "invalid"
}
}
-
-type apiDomain struct {
- ModuleBase
- BazelModuleBase
-
- properties apiDomainProperties
-}
-
-type apiDomainProperties struct {
- // cc library contributions (.h files/.map.txt) of this API domain
- // This dependency is a no-op in Soong, but the corresponding Bazel target in the api_bp2build workspace
- // will provide a `CcApiContributionInfo` provider
- Cc_api_contributions []string
-
- // java library contributions (as .txt) of this API domain
- // This dependency is a no-op in Soong, but the corresponding Bazel target in the api_bp2build workspace
- // will provide a `JavaApiContributionInfo` provider
- Java_api_contributions []string
-}
-
-func ApiDomainFactory() Module {
- m := &apiDomain{}
- m.AddProperties(&m.properties)
- InitAndroidArchModule(m, DeviceSupported, MultilibBoth)
- return m
-}
-
-// Do not create any dependency edges in Soong for now to skip visibility checks for some systemapi libraries.
-// Currently, all api_domain modules reside in build/orchestrator/apis/Android.bp
-// However, cc libraries like libsigchain (com.android.art) restrict their visibility to art/*
-// When the api_domain module types are collocated with their contributions, this dependency edge can be restored
-func (a *apiDomain) DepsMutator(ctx BottomUpMutatorContext) {
-}
-
-// API domain does not have any builld actions yet
-func (a *apiDomain) GenerateAndroidBuildActions(ctx ModuleContext) {
-}
-
-const (
- apiContributionSuffix = ".contribution"
-)
-
-// ApiContributionTargetName returns the name of the bp2build target (e.g. cc_api_contribution) of contribution modules (e.g. ndk_library)
-// A suffix is necessary to prevent a name collision with the base target in the same bp2build bazel package
-func ApiContributionTargetName(moduleName string) string {
- return moduleName + apiContributionSuffix
-}
-
-// For each contributing cc_library, format the name to its corresponding contribution bazel target in the bp2build workspace
-func contributionBazelAttributes(ctx TopDownMutatorContext, contributions []string) bazel.LabelListAttribute {
- addSuffix := func(ctx BazelConversionPathContext, module blueprint.Module) string {
- baseLabel := BazelModuleLabel(ctx, module)
- return ApiContributionTargetName(baseLabel)
- }
- bazelLabels := BazelLabelForModuleDepsWithFn(ctx, contributions, addSuffix)
- return bazel.MakeLabelListAttribute(bazelLabels)
-}
diff --git a/android/bazel.go b/android/bazel.go
index 4516396..b4e7ae5 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -218,6 +218,28 @@
module.bazelProps().Bazel_module.CanConvertToBazel = true
}
+// BazelHandcraftedHook is a load hook to possibly register the current module as
+// a "handcrafted" Bazel target of a given name. If the current module should be
+// registered in this way, the hook function should return the target name. If
+// it should not be registered in this way, this function should return the empty string.
+type BazelHandcraftedHook func(ctx LoadHookContext) string
+
+// AddBazelHandcraftedHook adds a load hook to (maybe) mark the given module so that
+// it is treated by bp2build as if it has a handcrafted Bazel target.
+func AddBazelHandcraftedHook(module BazelModule, hook BazelHandcraftedHook) {
+ AddLoadHook(module, func(ctx LoadHookContext) {
+ var targetName string = hook(ctx)
+ if len(targetName) > 0 {
+ moduleDir := ctx.ModuleDir()
+ if moduleDir == Bp2BuildTopLevel {
+ moduleDir = ""
+ }
+ label := fmt.Sprintf("//%s:%s", moduleDir, targetName)
+ module.bazelProps().Bazel_module.Label = &label
+ }
+ })
+}
+
// bazelProps returns the Bazel properties for the given BazelModuleBase.
func (b *BazelModuleBase) bazelProps() *properties {
return &b.bazelProperties
@@ -603,7 +625,18 @@
ctx.BottomUp("bp2build_conversion", bp2buildConversionMutator).Parallel()
}
+func registerBp2buildDepsMutator(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("bp2build_deps", bp2buildDepsMutator).Parallel()
+}
+
func bp2buildConversionMutator(ctx BottomUpMutatorContext) {
+ // If an existing BUILD file in the module directory has a target defined
+ // with this same name as this module, assume that this is an existing
+ // definition for this target.
+ if ctx.Config().HasBazelBuildTargetInSource(ctx.ModuleDir(), ctx.ModuleName()) {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE, ctx.ModuleName())
+ return
+ }
bModule, ok := ctx.Module().(Bazelable)
if !ok {
ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
@@ -637,6 +670,10 @@
panic(fmt.Errorf("illegal bp2build invariant: module '%s' was neither converted nor marked unconvertible", ctx.ModuleName()))
}
+ // If an existing BUILD file in the module directory has a target defined
+ // with the same name as any target generated by this module, assume that this
+ // is an existing definition for this target. (These generated target names
+ // may be different than the module name, as checked at the beginning of this function!)
for _, targetInfo := range ctx.Module().base().Bp2buildTargets() {
if ctx.Config().HasBazelBuildTargetInSource(targetInfo.TargetPackage(), targetInfo.TargetName()) {
// Defer to the BUILD target. Generating an additional target would
@@ -647,6 +684,39 @@
}
}
+// TODO: b/285631638 - Add this as a new mutator to the bp2build conversion mutators.
+// Currently, this only exists to prepare test coverage for the launch of this feature.
+func bp2buildDepsMutator(ctx BottomUpMutatorContext) {
+ if ctx.Module().base().GetUnconvertedReason() != nil {
+ return
+ }
+
+ if len(ctx.Module().GetMissingBp2buildDeps()) > 0 {
+ exampleDep := ctx.Module().GetMissingBp2buildDeps()[0]
+ ctx.MarkBp2buildUnconvertible(
+ bp2build_metrics_proto.UnconvertedReasonType_UNCONVERTED_DEP, exampleDep)
+ }
+
+ // Transitively mark modules unconvertible with the following set of conditions.
+ ctx.VisitDirectDeps(func(dep Module) {
+ if dep.base().GetUnconvertedReason() == nil {
+ return
+ }
+
+ if dep.base().GetUnconvertedReason().ReasonType ==
+ int(bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE) {
+ return
+ }
+
+ if ctx.OtherModuleDependencyTag(dep) != Bp2buildDepTag {
+ return
+ }
+
+ ctx.MarkBp2buildUnconvertible(
+ bp2build_metrics_proto.UnconvertedReasonType_UNCONVERTED_DEP, dep.Name())
+ })
+}
+
// GetMainClassInManifest scans the manifest file specified in filepath and returns
// the value of attribute Main-Class in the manifest file if it exists, or returns error.
// WARNING: this is for bp2build converters of java_* modules only.
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 56ec17d..51ce3c9 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -33,10 +33,10 @@
"android/soong/shared"
"android/soong/starlark_import"
+ "android/soong/bazel"
+
"github.com/google/blueprint"
"github.com/google/blueprint/metrics"
-
- "android/soong/bazel"
)
var (
@@ -1048,39 +1048,46 @@
allBazelCommands = []bazelCommand{aqueryCmd, cqueryCmd, buildCmd}
)
+// This can't be part of bp2build_product_config.go because it would create a circular go package dependency
+func getLabelsForBazelSandwichPartitions(variables *ProductVariables) []string {
+ targetProduct := "unknown"
+ if variables.DeviceProduct != nil {
+ targetProduct = *variables.DeviceProduct
+ }
+ currentProductFolder := fmt.Sprintf("build/bazel/products/%s", targetProduct)
+ if len(variables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory) > 0 {
+ currentProductFolder = fmt.Sprintf("%s%s", variables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory, targetProduct)
+ }
+ var ret []string
+ if variables.PartitionVarsForBazelMigrationOnlyDoNotUse.PartitionQualifiedVariables["system"].BuildingImage {
+ ret = append(ret, "@//"+currentProductFolder+":system_image")
+ ret = append(ret, "@//"+currentProductFolder+":run_system_image_test")
+ }
+ return ret
+}
+
func GetBazelSandwichCqueryRequests(config Config) ([]cqueryKey, error) {
- result := make([]cqueryKey, 0, len(allowlists.BazelSandwichTargets))
+ partitionLabels := getLabelsForBazelSandwichPartitions(&config.productVariables)
+ result := make([]cqueryKey, 0, len(partitionLabels))
labelRegex := regexp.MustCompile("^@?//([a-zA-Z0-9/_-]+):[a-zA-Z0-9_-]+$")
// Note that bazel "targets" are different from soong "targets", the bazel targets are
// synonymous with soong modules, and soong targets are a configuration a module is built in.
- for _, target := range allowlists.BazelSandwichTargets {
- match := labelRegex.FindStringSubmatch(target.Label)
+ for _, target := range partitionLabels {
+ match := labelRegex.FindStringSubmatch(target)
if match == nil {
- return nil, fmt.Errorf("invalid label, must match `^@?//([a-zA-Z0-9/_-]+):[a-zA-Z0-9_-]+$`: %s", target.Label)
- }
- if _, err := os.Stat(absolutePath(match[1])); err != nil {
- if os.IsNotExist(err) {
- // Ignore bazel sandwich targets that don't exist.
- continue
- } else {
- return nil, err
- }
+ return nil, fmt.Errorf("invalid label, must match `^@?//([a-zA-Z0-9/_-]+):[a-zA-Z0-9_-]+$`: %s", target)
}
- var soongTarget Target
- if target.Host {
- soongTarget = config.BuildOSTarget
- } else {
- soongTarget = config.AndroidCommonTarget
- if soongTarget.Os.Class != Device {
- // kernel-build-tools seems to set the AndroidCommonTarget to a linux host
- // target for some reason, disable device builds in that case.
- continue
- }
+ // change this to config.BuildOSTarget if we add host targets
+ soongTarget := config.AndroidCommonTarget
+ if soongTarget.Os.Class != Device {
+ // kernel-build-tools seems to set the AndroidCommonTarget to a linux host
+ // target for some reason, disable device builds in that case.
+ continue
}
result = append(result, cqueryKey{
- label: target.Label,
+ label: target,
requestType: cquery.GetOutputFiles,
configKey: configKey{
arch: soongTarget.Arch.String(),
diff --git a/android/bazel_paths.go b/android/bazel_paths.go
index 4ac5840..d272ec2 100644
--- a/android/bazel_paths.go
+++ b/android/bazel_paths.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "os"
"path/filepath"
"strings"
@@ -101,8 +102,8 @@
// BazelLabelForModuleDeps expects a list of reference to other modules, ("<module>"
// or ":<module>") and returns a Bazel-compatible label which corresponds to dependencies on the
// module within the given ctx.
-func BazelLabelForModuleDeps(ctx BazelConversionPathContext, modules []string) bazel.LabelList {
- return BazelLabelForModuleDepsWithFn(ctx, modules, BazelModuleLabel)
+func BazelLabelForModuleDeps(ctx Bp2buildMutatorContext, modules []string) bazel.LabelList {
+ return BazelLabelForModuleDepsWithFn(ctx, modules, BazelModuleLabel, /*markAsDeps=*/true)
}
// BazelLabelForModuleWholeDepsExcludes expects two lists: modules (containing modules to include in
@@ -111,15 +112,16 @@
// list which corresponds to dependencies on the module within the given ctx, and the excluded
// dependencies. Prebuilt dependencies will be appended with _alwayslink so they can be handled as
// whole static libraries.
-func BazelLabelForModuleDepsExcludes(ctx BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func BazelLabelForModuleDepsExcludes(ctx Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
return BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, BazelModuleLabel)
}
// BazelLabelForModuleDepsWithFn expects a list of reference to other modules, ("<module>"
// or ":<module>") and applies moduleToLabelFn to determine and return a Bazel-compatible label
// which corresponds to dependencies on the module within the given ctx.
-func BazelLabelForModuleDepsWithFn(ctx BazelConversionPathContext, modules []string,
- moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string) bazel.LabelList {
+func BazelLabelForModuleDepsWithFn(ctx Bp2buildMutatorContext, modules []string,
+ moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string,
+ markAsDeps bool) bazel.LabelList {
var labels bazel.LabelList
// In some cases, a nil string list is different than an explicitly empty list.
if len(modules) == 0 && modules != nil {
@@ -133,7 +135,7 @@
module = ":" + module
}
if m, t := SrcIsModuleWithTag(module); m != "" {
- l := getOtherModuleLabel(ctx, m, t, moduleToLabelFn)
+ l := getOtherModuleLabel(ctx, m, t, moduleToLabelFn, markAsDeps)
if l != nil {
l.OriginalModuleName = bpText
labels.Includes = append(labels.Includes, *l)
@@ -150,27 +152,27 @@
// to other modules, ("<module>" or ":<module>"). It applies moduleToLabelFn to determine and return a
// Bazel-compatible label list which corresponds to dependencies on the module within the given ctx, and
// the excluded dependencies.
-func BazelLabelForModuleDepsExcludesWithFn(ctx BazelConversionPathContext, modules, excludes []string,
+func BazelLabelForModuleDepsExcludesWithFn(ctx Bp2buildMutatorContext, modules, excludes []string,
moduleToLabelFn func(BazelConversionPathContext, blueprint.Module) string) bazel.LabelList {
- moduleLabels := BazelLabelForModuleDepsWithFn(ctx, RemoveListFromList(modules, excludes), moduleToLabelFn)
+ moduleLabels := BazelLabelForModuleDepsWithFn(ctx, RemoveListFromList(modules, excludes), moduleToLabelFn, /*markAsDeps=*/true)
if len(excludes) == 0 {
return moduleLabels
}
- excludeLabels := BazelLabelForModuleDepsWithFn(ctx, excludes, moduleToLabelFn)
+ excludeLabels := BazelLabelForModuleDepsWithFn(ctx, excludes, moduleToLabelFn, /*markAsDeps=*/false)
return bazel.LabelList{
Includes: moduleLabels.Includes,
Excludes: excludeLabels.Includes,
}
}
-func BazelLabelForModuleSrcSingle(ctx BazelConversionPathContext, path string) bazel.Label {
+func BazelLabelForModuleSrcSingle(ctx Bp2buildMutatorContext, path string) bazel.Label {
if srcs := BazelLabelForModuleSrcExcludes(ctx, []string{path}, []string(nil)).Includes; len(srcs) > 0 {
return srcs[0]
}
return bazel.Label{}
}
-func BazelLabelForModuleDepSingle(ctx BazelConversionPathContext, path string) bazel.Label {
+func BazelLabelForModuleDepSingle(ctx Bp2buildMutatorContext, path string) bazel.Label {
if srcs := BazelLabelForModuleDepsExcludes(ctx, []string{path}, []string(nil)).Includes; len(srcs) > 0 {
return srcs[0]
}
@@ -183,7 +185,7 @@
// relative if within the same package).
// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
// will have already been handled by the pathdeps mutator.
-func BazelLabelForModuleSrc(ctx BazelConversionPathContext, paths []string) bazel.LabelList {
+func BazelLabelForModuleSrc(ctx Bp2buildMutatorContext, paths []string) bazel.LabelList {
return BazelLabelForModuleSrcExcludes(ctx, paths, []string(nil))
}
@@ -193,13 +195,13 @@
// (absolute if in a different package or relative if within the same package).
// Properties must have been annotated with struct tag `android:"path"` so that dependencies modules
// will have already been handled by the pathdeps mutator.
-func BazelLabelForModuleSrcExcludes(ctx BazelConversionPathContext, paths, excludes []string) bazel.LabelList {
- excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil))
+func BazelLabelForModuleSrcExcludes(ctx Bp2buildMutatorContext, paths, excludes []string) bazel.LabelList {
+ excludeLabels := expandSrcsForBazel(ctx, excludes, []string(nil), false)
excluded := make([]string, 0, len(excludeLabels.Includes))
for _, e := range excludeLabels.Includes {
excluded = append(excluded, e.Label)
}
- labels := expandSrcsForBazel(ctx, paths, excluded)
+ labels := expandSrcsForBazel(ctx, paths, excluded, true)
labels.Excludes = excludeLabels.Includes
labels = TransformSubpackagePaths(ctx.Config(), ctx.ModuleDir(), labels)
return labels
@@ -228,10 +230,18 @@
// 2. An Android.bp doesn't exist, but a checked-in BUILD/BUILD.bazel file exists, and that file
// is allowlisted by the bp2build configuration to be merged into the symlink forest workspace.
func isPackageBoundary(config Config, prefix string, components []string, componentIndex int) bool {
+ isSymlink := func(c Config, path string) bool {
+ f, err := c.fs.Lstat(path)
+ if err != nil {
+ // The file does not exist
+ return false
+ }
+ return f.Mode()&os.ModeSymlink == os.ModeSymlink
+ }
prefix = filepath.Join(prefix, filepath.Join(components[:componentIndex+1]...))
if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "Android.bp")); exists {
return true
- } else if config.Bp2buildPackageConfig.ShouldKeepExistingBuildFileForDir(prefix) {
+ } else if config.Bp2buildPackageConfig.ShouldKeepExistingBuildFileForDir(prefix) || isSymlink(config, prefix) {
if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "BUILD")); exists {
return true
} else if exists, _, _ := config.fs.Exists(filepath.Join(prefix, "BUILD.bazel")); exists {
@@ -352,6 +362,12 @@
return newPaths
}
+var Bp2buildDepTag bp2buildDepTag
+
+type bp2buildDepTag struct {
+ blueprint.BaseDependencyTag
+}
+
// expandSrcsForBazel returns bazel.LabelList with paths rooted from the module's local source
// directory and Bazel target labels, excluding those included in the excludes argument (which
// should already be expanded to resolve references to Soong-modules). Valid elements of paths
@@ -374,7 +390,7 @@
// Properties passed as the paths or excludes argument must have been annotated with struct tag
// `android:"path"` so that dependencies on other modules will have already been handled by the
// pathdeps mutator.
-func expandSrcsForBazel(ctx BazelConversionPathContext, paths, expandedExcludes []string) bazel.LabelList {
+func expandSrcsForBazel(ctx Bp2buildMutatorContext, paths, expandedExcludes []string, markAsDeps bool) bazel.LabelList {
if paths == nil {
return bazel.LabelList{}
}
@@ -391,7 +407,7 @@
for _, p := range paths {
if m, tag := SrcIsModuleWithTag(p); m != "" {
- l := getOtherModuleLabel(ctx, m, tag, BazelModuleLabel)
+ l := getOtherModuleLabel(ctx, m, tag, BazelModuleLabel, markAsDeps)
if l != nil && !InList(l.Label, expandedExcludes) {
if strings.HasPrefix(m, "//") {
// this is a module in a soong namespace
@@ -423,8 +439,9 @@
// getOtherModuleLabel returns a bazel.Label for the given dependency/tag combination for the
// module. The label will be relative to the current directory if appropriate. The dependency must
// already be resolved by either deps mutator or path deps mutator.
-func getOtherModuleLabel(ctx BazelConversionPathContext, dep, tag string,
- labelFromModule func(BazelConversionPathContext, blueprint.Module) string) *bazel.Label {
+func getOtherModuleLabel(ctx Bp2buildMutatorContext, dep, tag string,
+ labelFromModule func(BazelConversionPathContext, blueprint.Module) string,
+ markAsDep bool) *bazel.Label {
m, _ := ctx.ModuleFromName(dep)
// The module was not found in an Android.bp file, this is often due to:
// * a limited manifest
@@ -435,6 +452,35 @@
Label: ":" + dep + "__BP2BUILD__MISSING__DEP",
}
}
+ // Returns true if a dependency from the current module to the target module
+ // should be skipped; doing so is a hack to circumvent certain problematic
+ // scenarios that will be addressed in the future.
+ shouldSkipDep := func(dep string) bool {
+ // Don't count dependencies of "libc". This is a hack to circumvent the
+ // fact that, in a variantless build graph, "libc" has a dependency on itself.
+ if ctx.ModuleName() == "libc" {
+ return true
+ }
+
+ // TODO: b/303307672: Dependencies on this module happen to "work" because
+ // there is a source file with the same name as this module in the
+ // same directory. We should remove this hack and enforce the underlying
+ // module of this name is the actual one used.
+ if dep == "mke2fs.conf" {
+ return true
+ }
+
+ // TODO: b/303310285: Remove this special-casing once all dependencies of
+ // crtbegin_dynamic are convertible
+ if ctx.ModuleName() == "crtbegin_dynamic" {
+ return true
+ }
+
+ return false
+ }
+ if markAsDep && !shouldSkipDep(dep) {
+ ctx.AddDependency(ctx.Module(), Bp2buildDepTag, dep)
+ }
if !convertedToBazel(ctx, m) {
ctx.AddUnconvertedBp2buildDep(dep)
}
@@ -442,6 +488,10 @@
otherLabel := labelFromModule(ctx, m)
// TODO(b/165114590): Convert tag (":name{.tag}") to corresponding Bazel implicit output targets.
+ if (tag != "" && m.Name() == "framework-res") ||
+ (tag == ".generated_srcjars" && ctx.OtherModuleType(m) == "java_aconfig_library") {
+ otherLabel += tag
+ }
if samePackage(label, otherLabel) {
otherLabel = bazelShortLabel(otherLabel)
diff --git a/android/config.go b/android/config.go
index f9d616d..524ff2f 100644
--- a/android/config.go
+++ b/android/config.go
@@ -297,6 +297,9 @@
// in tests when a path doesn't exist.
TestAllowNonExistentPaths bool
+ // If true, register the "bp2build_deps" mutator in the mutator pipeline.
+ Bp2buildDepsMutator bool
+
// The list of files that when changed, must invalidate soong_build to
// regenerate build.ninja.
ninjaFileDepsSet sync.Map
@@ -675,6 +678,7 @@
"framework-media": {},
"framework-mediaprovider": {},
"framework-ondevicepersonalization": {},
+ "framework-pdf": {},
"framework-permission": {},
"framework-permission-s": {},
"framework-scheduling": {},
@@ -1434,10 +1438,6 @@
return String(c.config.productVariables.Platform_vndk_version)
}
-func (c *deviceConfig) ProductVndkVersion() string {
- return String(c.config.productVariables.ProductVndkVersion)
-}
-
func (c *deviceConfig) ExtraVndkVersions() []string {
return c.config.productVariables.ExtraVndkVersions
}
@@ -2080,3 +2080,15 @@
func (c *deviceConfig) CheckVendorSeappViolations() bool {
return Bool(c.config.productVariables.CheckVendorSeappViolations)
}
+
+func (c *deviceConfig) NextReleaseHideFlaggedApi() bool {
+ return Bool(c.config.productVariables.NextReleaseHideFlaggedApi)
+}
+
+func (c *deviceConfig) ReleaseExposeFlaggedApi() bool {
+ return Bool(c.config.productVariables.Release_expose_flagged_api)
+}
+
+func (c *deviceConfig) HideFlaggedApis() bool {
+ return c.NextReleaseHideFlaggedApi() && !c.ReleaseExposeFlaggedApi()
+}
diff --git a/android/filegroup.go b/android/filegroup.go
index 5a8c4b9..856c50e 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -22,7 +22,6 @@
"android/soong/bazel"
"android/soong/bazel/cquery"
"android/soong/ui/metrics/bp2build_metrics_proto"
-
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -51,7 +50,7 @@
// ignoring case, checks for proto or protos as an independent word in the name, whether at the
// beginning, end, or middle. e.g. "proto.foo", "bar-protos", "baz_proto_srcs" would all match
filegroupLikelyProtoPattern = regexp.MustCompile("(?i)(^|[^a-z])proto(s)?([^a-z]|$)")
- filegroupLikelyAidlPattern = regexp.MustCompile("(?i)(^|[^a-z])aidl([^a-z]|$)")
+ filegroupLikelyAidlPattern = regexp.MustCompile("(?i)(^|[^a-z])aidl(s)?([^a-z]|$)")
ProtoSrcLabelPartition = bazel.LabelPartition{
Extensions: []string{".proto"},
@@ -106,8 +105,10 @@
if f.Label == fg.Name() {
if len(srcs.Value.Includes) > 1 {
ctx.ModuleErrorf("filegroup '%s' cannot contain a file with the same name", fg.Name())
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_SRC_NAME_COLLISION, "")
+ } else {
+ panic("This situation should have been handled by FileGroupFactory's call to InitBazelModuleAsHandcrafted")
}
- ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_SRC_NAME_COLLISION, "")
return
}
}
@@ -253,6 +254,16 @@
module.AddProperties(&module.properties)
InitAndroidModule(module)
InitBazelModule(module)
+ AddBazelHandcraftedHook(module, func(ctx LoadHookContext) string {
+ // If there is a single src with the same name as the filegroup module name,
+ // then don't generate this filegroup. It will be OK for other targets
+ // to depend on this source file by name directly.
+ fg := ctx.Module().(*fileGroup)
+ if len(fg.properties.Srcs) == 1 && fg.Name() == fg.properties.Srcs[0] {
+ return fg.Name()
+ }
+ return ""
+ })
InitDefaultableModule(module)
return module
}
diff --git a/android/mutator.go b/android/mutator.go
index 57ff1e0..3d59655 100644
--- a/android/mutator.go
+++ b/android/mutator.go
@@ -35,6 +35,9 @@
// RegisterMutatorsForBazelConversion is a alternate registration pipeline for bp2build. Exported for testing.
func RegisterMutatorsForBazelConversion(ctx *Context, preArchMutators []RegisterMutatorFunc) {
bp2buildMutators := append(preArchMutators, registerBp2buildConversionMutator)
+ if ctx.config.Bp2buildDepsMutator {
+ bp2buildMutators = append(bp2buildMutators, registerBp2buildDepsMutator)
+ }
registerMutatorsForBazelConversion(ctx, bp2buildMutators)
}
@@ -226,6 +229,15 @@
BazelConversionPathContext
BaseMutatorContext
+ // AddDependency adds a dependency to the given module. It returns a slice of modules for each
+ // dependency (some entries may be nil).
+ //
+ // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
+ // new dependencies have had the current mutator called on them. If the mutator is not
+ // parallel this method does not affect the ordering of the current mutator pass, but will
+ // be ordered correctly for all future mutator passes.
+ AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
+
// CreateBazelTargetModule creates a BazelTargetModule by calling the
// factory method, just like in CreateModule, but also requires
// BazelTargetModuleProperties containing additional metadata for the
@@ -294,15 +306,6 @@
BaseMutatorContext
Bp2buildMutatorContext
- // AddDependency adds a dependency to the given module. It returns a slice of modules for each
- // dependency (some entries may be nil).
- //
- // If the mutator is parallel (see MutatorHandle.Parallel), this method will pause until the
- // new dependencies have had the current mutator called on them. If the mutator is not
- // parallel this method does not affect the ordering of the current mutator pass, but will
- // be ordered correctly for all future mutator passes.
- AddDependency(module blueprint.Module, tag blueprint.DependencyTag, name ...string) []blueprint.Module
-
// AddReverseDependency adds a dependency from the destination to the given module.
// Does not affect the ordering of the current mutator pass, but will be ordered
// correctly for all future mutator passes. All reverse dependencies for a destination module are
diff --git a/android/prebuilt_build_tool.go b/android/prebuilt_build_tool.go
index aeae20f..17b3230 100644
--- a/android/prebuilt_build_tool.go
+++ b/android/prebuilt_build_tool.go
@@ -17,7 +17,7 @@
import "path/filepath"
func init() {
- RegisterModuleType("prebuilt_build_tool", prebuiltBuildToolFactory)
+ RegisterModuleType("prebuilt_build_tool", NewPrebuiltBuildTool)
}
type prebuiltBuildToolProperties struct {
@@ -101,10 +101,6 @@
// prebuilt_build_tool is to declare prebuilts to be used during the build, particularly for use
// in genrules with the "tools" property.
-func prebuiltBuildToolFactory() Module {
- return NewPrebuiltBuildTool()
-}
-
func NewPrebuiltBuildTool() Module {
module := &prebuiltBuildTool{}
module.AddProperties(&module.properties)
diff --git a/android/register.go b/android/register.go
index f1c2986..6182159 100644
--- a/android/register.go
+++ b/android/register.go
@@ -181,8 +181,7 @@
return ctx
}
-// Helper function to register the module types used in bp2build and
-// api_bp2build.
+// Helper function to register the module types used in bp2build.
func registerModuleTypes(ctx *Context) {
for _, t := range moduleTypes {
t.register(ctx)
diff --git a/android/rule_builder.go b/android/rule_builder.go
index 777c1cf..245b759 100644
--- a/android/rule_builder.go
+++ b/android/rule_builder.go
@@ -474,13 +474,23 @@
Inputs(depFiles.Paths())
}
+// BuildWithNinjaVars adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for
+// Outputs. This function will not escape Ninja variables, so it may be used to write sandbox manifests using Ninja variables.
+func (r *RuleBuilder) BuildWithUnescapedNinjaVars(name string, desc string) {
+ r.build(name, desc, false)
+}
+
// Build adds the built command line to the build graph, with dependencies on Inputs and Tools, and output files for
// Outputs.
func (r *RuleBuilder) Build(name string, desc string) {
+ r.build(name, desc, true)
+}
+
+func (r *RuleBuilder) build(name string, desc string, ninjaEscapeCommandString bool) {
name = ninjaNameEscape(name)
if len(r.missingDeps) > 0 {
- r.ctx.Build(pctx, BuildParams{
+ r.ctx.Build(r.pctx, BuildParams{
Rule: ErrorRule,
Outputs: r.Outputs(),
Description: desc,
@@ -619,12 +629,35 @@
name, r.sboxManifestPath.String(), r.outDir.String())
}
- // Create a rule to write the manifest as a the textproto.
+ // Create a rule to write the manifest as textproto.
pbText, err := prototext.Marshal(&manifest)
if err != nil {
ReportPathErrorf(r.ctx, "sbox manifest failed to marshal: %q", err)
}
- WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText))
+ if ninjaEscapeCommandString {
+ WriteFileRule(r.ctx, r.sboxManifestPath, string(pbText))
+ } else {
+ // We need to have a rule to write files that is
+ // defined on the RuleBuilder's pctx in order to
+ // write Ninja variables in the string.
+ // The WriteFileRule function above rule can only write
+ // raw strings because it is defined on the android
+ // package's pctx, and it can't access variables defined
+ // in another context.
+ r.ctx.Build(r.pctx, BuildParams{
+ Rule: r.ctx.Rule(r.pctx, "unescapedWriteFile", blueprint.RuleParams{
+ Command: `rm -rf ${out} && cat ${out}.rsp > ${out}`,
+ Rspfile: "${out}.rsp",
+ RspfileContent: "${content}",
+ Description: "write file",
+ }, "content"),
+ Output: r.sboxManifestPath,
+ Description: "write sbox manifest " + r.sboxManifestPath.Base(),
+ Args: map[string]string{
+ "content": string(pbText),
+ },
+ })
+ }
// Generate a new string to use as the command line of the sbox rule. This uses
// a RuleBuilderCommand as a convenience method of building the command line, then
@@ -723,9 +756,13 @@
pool = localPool
}
+ if ninjaEscapeCommandString {
+ commandString = proptools.NinjaEscape(commandString)
+ }
+
r.ctx.Build(r.pctx, BuildParams{
- Rule: r.ctx.Rule(pctx, name, blueprint.RuleParams{
- Command: proptools.NinjaEscape(commandString),
+ Rule: r.ctx.Rule(r.pctx, name, blueprint.RuleParams{
+ Command: commandString,
CommandDeps: proptools.NinjaEscapeList(tools.Strings()),
Restat: r.restat,
Rspfile: proptools.NinjaEscape(rspFile),
diff --git a/android/rule_builder_test.go b/android/rule_builder_test.go
index 86647eb..a6b3a27 100644
--- a/android/rule_builder_test.go
+++ b/android/rule_builder_test.go
@@ -28,6 +28,17 @@
"android/soong/shared"
)
+var (
+ pctx_ruleBuilderTest = NewPackageContext("android/soong/rule_builder")
+ pctx_ruleBuilderTestSubContext = NewPackageContext("android/soong/rule_builder/config")
+)
+
+func init() {
+ pctx_ruleBuilderTest.Import("android/soong/rule_builder/config")
+ pctx_ruleBuilderTest.StaticVariable("cmdFlags", "${config.ConfigFlags}")
+ pctx_ruleBuilderTestSubContext.StaticVariable("ConfigFlags", "--some-clang-flag")
+}
+
func builderContext() BuilderContext {
return BuilderContextForTesting(TestConfig("out", nil, "", map[string][]byte{
"ld": nil,
@@ -496,11 +507,13 @@
type testRuleBuilderModule struct {
ModuleBase
properties struct {
- Srcs []string
+ Srcs []string
+ Flags []string
- Restat bool
- Sbox bool
- Sbox_inputs bool
+ Restat bool
+ Sbox bool
+ Sbox_inputs bool
+ Unescape_ninja_vars bool
}
}
@@ -518,8 +531,9 @@
rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"})
manifestPath := PathForModuleOut(ctx, "sbox.textproto")
- testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir,
- manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs,
+ testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, t.properties.Flags,
+ out, outDep, outDir,
+ manifestPath, t.properties.Restat, t.properties.Sbox, t.properties.Sbox_inputs, t.properties.Unescape_ninja_vars,
rspFile, rspFileContents, rspFile2, rspFileContents2)
}
@@ -543,17 +557,18 @@
rspFileContents2 := PathsForSource(ctx, []string{"rsp_in2"})
manifestPath := PathForOutput(ctx, "singleton/sbox.textproto")
- testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, out, outDep, outDir,
- manifestPath, true, false, false,
+ testRuleBuilder_Build(ctx, in, implicit, orderOnly, validation, nil, out, outDep, outDir,
+ manifestPath, true, false, false, false,
rspFile, rspFileContents, rspFile2, rspFileContents2)
}
func testRuleBuilder_Build(ctx BuilderContext, in Paths, implicit, orderOnly, validation Path,
+ flags []string,
out, outDep, outDir, manifestPath WritablePath,
- restat, sbox, sboxInputs bool,
+ restat, sbox, sboxInputs, unescapeNinjaVars bool,
rspFile WritablePath, rspFileContents Paths, rspFile2 WritablePath, rspFileContents2 Paths) {
- rule := NewRuleBuilder(pctx, ctx)
+ rule := NewRuleBuilder(pctx_ruleBuilderTest, ctx)
if sbox {
rule.Sbox(outDir, manifestPath)
@@ -564,6 +579,7 @@
rule.Command().
Tool(PathForSource(ctx, "cp")).
+ Flags(flags).
Inputs(in).
Implicit(implicit).
OrderOnly(orderOnly).
@@ -577,7 +593,11 @@
rule.Restat()
}
- rule.Build("rule", "desc")
+ if unescapeNinjaVars {
+ rule.BuildWithUnescapedNinjaVars("rule", "desc")
+ } else {
+ rule.Build("rule", "desc")
+ }
}
var prepareForRuleBuilderTest = FixtureRegisterWithContext(func(ctx RegistrationContext) {
@@ -792,3 +812,47 @@
})
}
}
+
+func TestRuleBuilderWithNinjaVarEscaping(t *testing.T) {
+ bp := `
+ rule_builder_test {
+ name: "foo_sbox_escaped_ninja",
+ flags: ["${cmdFlags}"],
+ sbox: true,
+ sbox_inputs: true,
+ }
+ rule_builder_test {
+ name: "foo_sbox",
+ flags: ["${cmdFlags}"],
+ sbox: true,
+ sbox_inputs: true,
+ unescape_ninja_vars: true,
+ }
+ `
+ result := GroupFixturePreparers(
+ prepareForRuleBuilderTest,
+ FixtureWithRootAndroidBp(bp),
+ ).RunTest(t)
+
+ escapedNinjaMod := result.ModuleForTests("foo_sbox_escaped_ninja", "").Rule("writeFile")
+ AssertStringDoesContain(
+ t,
+ "",
+ escapedNinjaMod.BuildParams.Args["content"],
+ "$${cmdFlags}",
+ )
+
+ unescapedNinjaMod := result.ModuleForTests("foo_sbox", "").Rule("unescapedWriteFile")
+ AssertStringDoesContain(
+ t,
+ "",
+ unescapedNinjaMod.BuildParams.Args["content"],
+ "${cmdFlags}",
+ )
+ AssertStringDoesNotContain(
+ t,
+ "",
+ unescapedNinjaMod.BuildParams.Args["content"],
+ "$${cmdFlags}",
+ )
+}
diff --git a/android/test_asserts.go b/android/test_asserts.go
index 3a2cb1a..c33ade5 100644
--- a/android/test_asserts.go
+++ b/android/test_asserts.go
@@ -148,7 +148,7 @@
return
}
if !ok {
- t.Errorf("%s does not match regular expression %s", s, expectedRex)
+ t.Errorf("%s: %s does not match regular expression %s", message, s, expectedRex)
}
}
diff --git a/android/updatable_modules.go b/android/updatable_modules.go
index 71c76c5..6d0eeb7 100644
--- a/android/updatable_modules.go
+++ b/android/updatable_modules.go
@@ -14,9 +14,9 @@
package android
-// This file contains branch specific constants for building updatable modules.
-// They are stored in a separate file to minimise the potential of merge
-// conflicts between branches when the code from the package is changed.
+// This file contains branch specific constants. They are stored in a separate
+// file to minimise the potential of merge conflicts between branches when
+// the code from the package is changed.
// The default manifest version for all the modules on this branch.
// This version code will be used only if there is no version field in the
@@ -33,4 +33,4 @@
// * AOSP - xx9990000
// * x-mainline-prod - xx9990000
// * master - 990090000
-const DefaultUpdatableModuleVersion = "339990000"
+const DefaultUpdatableModuleVersion = "340090000"
diff --git a/android/variable.go b/android/variable.go
index d33294c..8882e80 100644
--- a/android/variable.go
+++ b/android/variable.go
@@ -418,8 +418,6 @@
ProductPublicSepolicyDirs []string `json:",omitempty"`
ProductPrivateSepolicyDirs []string `json:",omitempty"`
- ProductVndkVersion *string `json:",omitempty"`
-
TargetFSConfigGen []string `json:",omitempty"`
EnforceProductPartitionInterface *bool `json:",omitempty"`
@@ -485,11 +483,67 @@
CheckVendorSeappViolations *bool `json:",omitempty"`
- // PartitionsVars are extra variables that are used to define the partition images. They should
- // not be read from soong modules.
- PartitionVars struct {
- ProductDirectory string `json:",omitempty"`
- } `json:",omitempty"`
+ // PartitionVarsForBazelMigrationOnlyDoNotUse are extra variables that are used to define the
+ // partition images. They should not be read from soong modules.
+ PartitionVarsForBazelMigrationOnlyDoNotUse PartitionVariables `json:",omitempty"`
+
+ NextReleaseHideFlaggedApi *bool `json:",omitempty"`
+
+ Release_expose_flagged_api *bool `json:",omitempty"`
+}
+
+type PartitionVariables struct {
+ ProductDirectory string `json:",omitempty"`
+ PartitionQualifiedVariables map[string]struct {
+ BuildingImage bool `json:",omitempty"`
+ BoardErofsCompressor string `json:",omitempty"`
+ BoardErofsCompressHints string `json:",omitempty"`
+ BoardErofsPclusterSize string `json:",omitempty"`
+ BoardExtfsInodeCount string `json:",omitempty"`
+ BoardExtfsRsvPct string `json:",omitempty"`
+ BoardF2fsSloadCompressFlags string `json:",omitempty"`
+ BoardFileSystemCompress string `json:",omitempty"`
+ BoardFileSystemType string `json:",omitempty"`
+ BoardJournalSize string `json:",omitempty"`
+ BoardPartitionReservedSize string `json:",omitempty"`
+ BoardPartitionSize string `json:",omitempty"`
+ BoardSquashfsBlockSize string `json:",omitempty"`
+ BoardSquashfsCompressor string `json:",omitempty"`
+ BoardSquashfsCompressorOpt string `json:",omitempty"`
+ BoardSquashfsDisable4kAlign string `json:",omitempty"`
+ ProductBaseFsPath string `json:",omitempty"`
+ ProductHeadroom string `json:",omitempty"`
+ ProductVerityPartition string `json:",omitempty"`
+
+ BoardAvbAddHashtreeFooterArgs string `json:",omitempty"`
+ BoardAvbKeyPath string `json:",omitempty"`
+ BoardAvbAlgorithm string `json:",omitempty"`
+ BoardAvbRollbackIndex string `json:",omitempty"`
+ BoardAvbRollbackIndexLocation string `json:",omitempty"`
+ }
+ TargetUserimagesUseExt2 bool `json:",omitempty"`
+ TargetUserimagesUseExt3 bool `json:",omitempty"`
+ TargetUserimagesUseExt4 bool `json:",omitempty"`
+
+ TargetUserimagesSparseExtDisabled bool `json:",omitempty"`
+ TargetUserimagesSparseErofsDisabled bool `json:",omitempty"`
+ TargetUserimagesSparseSquashfsDisabled bool `json:",omitempty"`
+ TargetUserimagesSparseF2fsDisabled bool `json:",omitempty"`
+
+ BoardErofsCompressor string `json:",omitempty"`
+ BoardErofsCompressorHints string `json:",omitempty"`
+ BoardErofsPclusterSize string `json:",omitempty"`
+ BoardErofsShareDupBlocks string `json:",omitempty"`
+ BoardErofsUseLegacyCompression string `json:",omitempty"`
+ BoardExt4ShareDupBlocks string `json:",omitempty"`
+ BoardFlashLogicalBlockSize string `json:",omitempty"`
+ BoardFlashEraseBlockSize string `json:",omitempty"`
+ BoardUsesRecoveryAsBoot bool `json:",omitempty"`
+ BoardBuildGkiBootImageWithoutRamdisk bool `json:",omitempty"`
+ ProductUseDynamicPartitionSize bool `json:",omitempty"`
+ CopyImagesForTargetFilesZip bool `json:",omitempty"`
+
+ BoardAvbEnable bool `json:",omitempty"`
}
func boolPtr(v bool) *bool {
diff --git a/apex/apex.go b/apex/apex.go
index 090d9c4..f903373 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -736,7 +736,7 @@
vndkVersion = deviceConfig.VndkVersion()
} else if a.ProductSpecific() {
prefix = cc.ProductVariationPrefix
- vndkVersion = deviceConfig.ProductVndkVersion()
+ vndkVersion = deviceConfig.PlatformVndkVersion()
}
}
if vndkVersion == "current" {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index 9475f5d..e70d3af 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -948,7 +948,7 @@
// Ensure that stub dependency from a rust module is not included
ensureNotContains(t, copyCmds, "image.apex/lib64/libfoo.shared_from_rust.so")
// The rust module is linked to the stub cc library
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"]
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
@@ -1024,7 +1024,7 @@
mylibLdFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_shared_apex10000").Rule("ld").Args["libFlags"]
ensureNotContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared_current/mylib2.so")
ensureContains(t, mylibLdFlags, "mylib2/android_arm64_armv8-a_shared/mylib2.so")
- rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustLink").Args["linkFlags"]
+ rustDeps := ctx.ModuleForTests("foo.rust", "android_arm64_armv8-a_apex10000").Rule("rustc").Args["linkFlags"]
ensureNotContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so")
ensureContains(t, rustDeps, "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so")
}
@@ -3088,10 +3088,7 @@
apex_available: ["myapex"],
srcs: ["foo.cpp"],
}
- `, android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- variables.ProductVndkVersion = proptools.StringPtr("current")
- }),
- )
+ `)
cflags := strings.Fields(
ctx.ModuleForTests("foo", "android_product.29_arm64_armv8-a_myapex").Rule("cc").Args["cFlags"])
@@ -10521,6 +10518,7 @@
min_sdk_version: "29",
recovery_available: true,
vendor_available: true,
+ product_available: true,
}
api_imports {
name: "api_imports",
diff --git a/apex/vndk_test.go b/apex/vndk_test.go
index 2b86e53..e2aee96 100644
--- a/apex/vndk_test.go
+++ b/apex/vndk_test.go
@@ -115,12 +115,7 @@
})
t.Run("VNDK APEX gathers only vendor variants even if product variants are available", func(t *testing.T) {
- ctx := testApex(t, bp,
- android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
- // Now product variant is available
- variables.ProductVndkVersion = proptools.StringPtr("current")
- }),
- )
+ ctx := testApex(t, bp)
files := getFiles(t, ctx, "com.android.vndk.current", "android_common")
ensureFileSrc(t, files, "lib/libfoo.so", "libfoo/android_vendor.29_arm_armv7-a-neon_shared/libfoo.so")
diff --git a/bazel/aquery.go b/bazel/aquery.go
index c355712..641f16b 100644
--- a/bazel/aquery.go
+++ b/bazel/aquery.go
@@ -18,14 +18,16 @@
"crypto/sha256"
"encoding/base64"
"encoding/json"
+ "errors"
"fmt"
"path/filepath"
- analysis_v2_proto "prebuilts/bazel/common/proto/analysis_v2"
"reflect"
"sort"
"strings"
"sync"
+ analysis_v2_proto "prebuilts/bazel/common/proto/analysis_v2"
+
"github.com/google/blueprint/metrics"
"github.com/google/blueprint/proptools"
"google.golang.org/protobuf/proto"
@@ -370,13 +372,20 @@
defer eventHandler.End("build_statements")
wg := sync.WaitGroup{}
var errOnce sync.Once
-
+ id2targets := make(map[uint32]string, len(aqueryProto.Targets))
+ for _, t := range aqueryProto.Targets {
+ id2targets[t.GetId()] = t.GetLabel()
+ }
for i, actionEntry := range aqueryProto.Actions {
wg.Add(1)
go func(i int, actionEntry *analysis_v2_proto.Action) {
- buildStatement, aErr := aqueryHandler.actionToBuildStatement(actionEntry)
- if aErr != nil {
+ if strings.HasPrefix(id2targets[actionEntry.TargetId], "@bazel_tools//") {
+ // bazel_tools are removed depsets in `populateDepsetMaps()` so skipping
+ // conversion to build statements as well
+ buildStatements[i] = nil
+ } else if buildStatement, aErr := aqueryHandler.actionToBuildStatement(actionEntry); aErr != nil {
errOnce.Do(func() {
+ aErr = fmt.Errorf("%s: [%s] [%s]", aErr.Error(), actionEntry.GetMnemonic(), id2targets[actionEntry.TargetId])
err = aErr
})
} else {
@@ -782,7 +791,7 @@
}
if len(actionEntry.Arguments) < 1 {
- return nil, fmt.Errorf("received action with no command: [%s]", actionEntry.Mnemonic)
+ return nil, errors.New("received action with no command")
}
return a.normalActionBuildStatement(actionEntry)
diff --git a/bazel/aquery_test.go b/bazel/aquery_test.go
index 32c87a0..cbd2791 100644
--- a/bazel/aquery_test.go
+++ b/bazel/aquery_test.go
@@ -178,8 +178,8 @@
{ "id": 2, "path_fragment_id": 2 }],
"actions": [{
"target_id": 1,
- "action_key": "x",
- "mnemonic": "x",
+ "action_key": "action_x",
+ "mnemonic": "X",
"arguments": ["touch", "foo"],
"input_dep_set_ids": [1],
"output_ids": [3],
@@ -198,7 +198,7 @@
return
}
_, _, err = AqueryBuildStatements(data, &metrics.EventHandler{})
- assertError(t, err, "undefined outputId 3")
+ assertError(t, err, "undefined outputId 3: [X] []")
}
func TestInvalidInputDepsetIdFromAction(t *testing.T) {
@@ -209,13 +209,17 @@
{ "id": 2, "path_fragment_id": 2 }],
"actions": [{
"target_id": 1,
- "action_key": "x",
- "mnemonic": "x",
+ "action_key": "action_x",
+ "mnemonic": "X",
"arguments": ["touch", "foo"],
"input_dep_set_ids": [2],
"output_ids": [1],
"primary_output_id": 1
}],
+ "targets": [{
+ "id": 1,
+ "label": "target_x"
+ }],
"dep_set_of_files": [
{ "id": 1, "direct_artifact_ids": [1, 2] }],
"path_fragments": [
@@ -229,7 +233,7 @@
return
}
_, _, err = AqueryBuildStatements(data, &metrics.EventHandler{})
- assertError(t, err, "undefined (not even empty) input depsetId 2")
+ assertError(t, err, "undefined (not even empty) input depsetId 2: [X] [target_x]")
}
func TestInvalidInputDepsetIdFromDepset(t *testing.T) {
@@ -383,8 +387,8 @@
{ "id": 4, "path_fragment_id": 4 }],
"actions": [{
"target_id": 1,
- "action_key": "x",
- "mnemonic": "x",
+ "action_key": "action_x",
+ "mnemonic": "X",
"arguments": ["touch", "foo"],
"input_dep_set_ids": [1],
"output_ids": [2,3,4],
@@ -407,7 +411,7 @@
return
}
_, _, err = AqueryBuildStatements(data, &metrics.EventHandler{})
- assertError(t, err, `found multiple potential depfiles "two.d", "other.d"`)
+ assertError(t, err, `found multiple potential depfiles "two.d", "other.d": [X] []`)
}
func TestTransitiveInputDepsets(t *testing.T) {
@@ -559,7 +563,7 @@
}, actual)
}
-func TestBazelOutRemovalFromInputDepsets(t *testing.T) {
+func TestBazelToolsRemovalFromInputDepsets(t *testing.T) {
const inputString = `{
"artifacts": [
{ "id": 1, "path_fragment_id": 10 },
@@ -637,7 +641,55 @@
}
}
-func TestBazelOutRemovalFromTransitiveInputDepsets(t *testing.T) {
+func TestBazelToolsRemovalFromTargets(t *testing.T) {
+ const inputString = `{
+ "artifacts": [{ "id": 1, "path_fragment_id": 10 }],
+ "targets": [
+ { "id": 100, "label": "targetX" },
+ { "id": 200, "label": "@bazel_tools//tool_y" }
+],
+ "actions": [{
+ "target_id": 100,
+ "action_key": "actionX",
+ "arguments": ["bogus", "command"],
+ "mnemonic" : "x",
+ "output_ids": [1]
+ }, {
+ "target_id": 200,
+ "action_key": "y"
+ }],
+ "path_fragments": [{ "id": 10, "label": "outputX"}]
+}`
+ data, err := JsonToActionGraphContainer(inputString)
+ if err != nil {
+ t.Error(err)
+ return
+ }
+ actualBuildStatements, actualDepsets, _ := AqueryBuildStatements(data, &metrics.EventHandler{})
+ if len(actualDepsets) != 0 {
+ t.Errorf("expected 0 depset but found %#v", actualDepsets)
+ return
+ }
+ expectedBuildStatement := &BuildStatement{
+ Command: "bogus command",
+ OutputPaths: []string{"outputX"},
+ Mnemonic: "x",
+ SymlinkPaths: []string{},
+ }
+ buildStatementFound := false
+ for _, actualBuildStatement := range actualBuildStatements {
+ if buildStatementEquals(actualBuildStatement, expectedBuildStatement) == "" {
+ buildStatementFound = true
+ break
+ }
+ }
+ if !buildStatementFound {
+ t.Errorf("expected but missing %#v in %#v build statements", expectedBuildStatement, len(actualBuildStatements))
+ return
+ }
+}
+
+func TestBazelToolsRemovalFromTransitiveInputDepsets(t *testing.T) {
const inputString = `{
"artifacts": [
{ "id": 1, "path_fragment_id": 10 },
@@ -939,7 +991,7 @@
{ "id": 3, "path_fragment_id": 3 }],
"actions": [{
"target_id": 1,
- "action_key": "x",
+ "action_key": "action_x",
"mnemonic": "Symlink",
"input_dep_set_ids": [1],
"output_ids": [3],
@@ -958,7 +1010,7 @@
return
}
_, _, err = AqueryBuildStatements(data, &metrics.EventHandler{})
- assertError(t, err, `Expect 1 input and 1 output to symlink action, got: input ["file" "other_file"], output ["symlink"]`)
+ assertError(t, err, `Expect 1 input and 1 output to symlink action, got: input ["file" "other_file"], output ["symlink"]: [Symlink] []`)
}
func TestSymlinkMultipleOutputs(t *testing.T) {
@@ -989,7 +1041,7 @@
return
}
_, _, err = AqueryBuildStatements(data, &metrics.EventHandler{})
- assertError(t, err, "undefined outputId 2")
+ assertError(t, err, "undefined outputId 2: [Symlink] []")
}
func TestTemplateExpandActionSubstitutions(t *testing.T) {
@@ -1066,7 +1118,7 @@
return
}
_, _, err = AqueryBuildStatements(data, &metrics.EventHandler{})
- assertError(t, err, `Expect 1 output to template expand action, got: output []`)
+ assertError(t, err, `Expect 1 output to template expand action, got: output []: [TemplateExpand] []`)
}
func TestFileWrite(t *testing.T) {
diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go
index 40356a1..475c2d6 100644
--- a/bp2build/aar_conversion_test.go
+++ b/bp2build/aar_conversion_test.go
@@ -21,6 +21,17 @@
"android/soong/java"
)
+func runAndroidLibraryImportTestWithRegistrationCtxFunc(t *testing.T, registrationCtxFunc func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
+ t.Helper()
+ (&tc).ModuleTypeUnderTest = "android_library_import"
+ (&tc).ModuleTypeUnderTestFactory = java.AARImportFactory
+ RunBp2BuildTestCase(t, registrationCtxFunc, tc)
+}
+
+func runAndroidLibraryImportTest(t *testing.T, tc Bp2buildTestCase) {
+ runAndroidLibraryImportTestWithRegistrationCtxFunc(t, func(ctx android.RegistrationContext) {}, tc)
+}
+
func TestConvertAndroidLibrary(t *testing.T) {
t.Helper()
RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
@@ -75,7 +86,7 @@
func TestConvertAndroidLibraryWithNoSources(t *testing.T) {
t.Helper()
RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{
- Description: "Android Library - modules with deps must have sources",
+ Description: "Android Library - modules will deps when there are no sources",
ModuleTypeUnderTest: "android_library",
ModuleTypeUnderTestFactory: java.AndroidLibraryFactory,
Filesystem: map[string]string{
@@ -91,25 +102,29 @@
sdk_version: "current",
}
`,
- ExpectedBazelTargets: []string{},
+ StubbedBuildDefinitions: []string{"lib_dep"},
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget(
+ "android_library",
+ "TestLib",
+ AttrNameToString{
+ "manifest": `"AndroidManifest.xml"`,
+ "resource_files": `["res/res.png"]`,
+ "sdk_version": `"current"`, // use as default
+ },
+ ),
+ MakeNeverlinkDuplicateTarget("android_library", "TestLib"),
+ },
})
}
func TestConvertAndroidLibraryImport(t *testing.T) {
- t.Helper()
- RunBp2BuildTestCase(
- t,
+ runAndroidLibraryImportTestWithRegistrationCtxFunc(t,
func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("android_library", java.AndroidLibraryFactory)
},
Bp2buildTestCase{
- Description: "Android Library Import",
- ModuleTypeUnderTest: "android_library_import",
- ModuleTypeUnderTestFactory: java.AARImportFactory,
- Filesystem: map[string]string{
- "import.aar": "",
- "dep.aar": "",
- },
+ Description: "Android Library Import",
StubbedBuildDefinitions: []string{"static_lib_dep", "static_import_dep", "static_import_dep-neverlink"},
// Bazel's aar_import can only export *_import targets, so we expect
// only "static_import_dep" in exports, but both "static_lib_dep" and
@@ -122,7 +137,6 @@
sdk_version: "current",
}
-// TODO: b/301007952 - This dep is needed because android_library_import must have aars set.
android_library_import {
name: "static_import_dep",
aars: ["import.aar"],
@@ -220,3 +234,16 @@
MakeNeverlinkDuplicateTarget("android_library", "TestLib"),
}})
}
+
+func TestAarImportFailsToConvertNoAars(t *testing.T) {
+ runAndroidLibraryImportTest(t,
+ Bp2buildTestCase{
+ Description: "Android Library Import with no aars does not convert.",
+ Blueprint: `
+android_library_import {
+ name: "no_aar_import",
+}
+`,
+ ExpectedBazelTargets: []string{},
+ })
+}
diff --git a/bp2build/aconfig_conversion_test.go b/bp2build/aconfig_conversion_test.go
index cbf42ac..9d73ec0 100644
--- a/bp2build/aconfig_conversion_test.go
+++ b/bp2build/aconfig_conversion_test.go
@@ -20,11 +20,13 @@
"android/soong/aconfig"
"android/soong/android"
"android/soong/cc"
+ "android/soong/java"
)
func registerAconfigModuleTypes(ctx android.RegistrationContext) {
aconfig.RegisterBuildComponents(ctx)
ctx.RegisterModuleType("cc_library", cc.LibraryFactory)
+ ctx.RegisterModuleType("java_library", java.LibraryFactory)
}
func TestAconfigDeclarations(t *testing.T) {
@@ -105,7 +107,6 @@
cc_library {
name: "server_configurable_flags",
srcs: ["bar.cc"],
- bazel_module: { bp2build_available: false },
}
cc_aconfig_library {
name: "foo",
@@ -131,6 +132,105 @@
},
)}
RunBp2BuildTestCase(t, registerAconfigModuleTypes, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ StubbedBuildDefinitions: []string{"server_configurable_flags"},
+ })
+}
+
+func TestJavaAconfigLibrary(t *testing.T) {
+ bp := `
+ aconfig_declarations {
+ name: "foo_aconfig_declarations",
+ srcs: [
+ "foo1.aconfig",
+ ],
+ package: "com.android.foo",
+ }
+ java_aconfig_library {
+ name: "foo",
+ aconfig_declarations: "foo_aconfig_declarations",
+ test: true,
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTargetNoRestrictions(
+ "aconfig_declarations",
+ "foo_aconfig_declarations",
+ AttrNameToString{
+ "srcs": `["foo1.aconfig"]`,
+ "package": `"com.android.foo"`,
+ },
+ ),
+ MakeBazelTargetNoRestrictions(
+ "java_aconfig_library",
+ "foo",
+ AttrNameToString{
+ "aconfig_declarations": `":foo_aconfig_declarations"`,
+ "test": `True`,
+ "sdk_version": `"system_current"`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ },
+ )}
+ RunBp2BuildTestCase(t, registerAconfigModuleTypes, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ })
+}
+
+func TestJavaAconfigLibraryAsTaggedOutput(t *testing.T) {
+ bp := `
+ aconfig_declarations {
+ name: "foo_aconfig_declarations",
+ srcs: [
+ "foo.aconfig",
+ ],
+ package: "com.android.foo",
+ }
+ java_library {
+ name: "foo_library",
+ srcs: [":foo_aconfig_library{.generated_srcjars}"],
+ sdk_version: "current",
+ bazel_module: { bp2build_available: true },
+ }
+ java_aconfig_library {
+ name: "foo_aconfig_library",
+ aconfig_declarations: "foo_aconfig_declarations",
+ test: true,
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTargetNoRestrictions(
+ "aconfig_declarations",
+ "foo_aconfig_declarations",
+ AttrNameToString{
+ "srcs": `["foo.aconfig"]`,
+ "package": `"com.android.foo"`,
+ },
+ ),
+ MakeBazelTargetNoRestrictions(
+ "java_aconfig_library",
+ "foo_aconfig_library",
+ AttrNameToString{
+ "aconfig_declarations": `":foo_aconfig_declarations"`,
+ "test": `True`,
+ "sdk_version": `"system_current"`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ },
+ ),
+ MakeBazelTargetNoRestrictions(
+ "java_library",
+ "foo_library",
+ AttrNameToString{
+ "srcs": `[":foo_aconfig_library.generated_srcjars"]`,
+ "sdk_version": `"current"`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ },
+ ),
+ MakeNeverlinkDuplicateTarget("java_library", "foo_library"),
+ }
+
+ RunBp2BuildTestCase(t, registerAconfigModuleTypes, Bp2buildTestCase{
Blueprint: bp,
ExpectedBazelTargets: expectedBazelTargets,
})
diff --git a/bp2build/android_app_conversion_test.go b/bp2build/android_app_conversion_test.go
index 8ec4b35..afe6dcd 100644
--- a/bp2build/android_app_conversion_test.go
+++ b/bp2build/android_app_conversion_test.go
@@ -478,3 +478,41 @@
}),
}})
}
+
+func TestFrameworkResConversion(t *testing.T) {
+ runAndroidAppTestCase(t, Bp2buildTestCase{
+ Description: "Framework Res custom conversion",
+ ModuleTypeUnderTest: "android_app",
+ ModuleTypeUnderTestFactory: java.AndroidAppFactory,
+ Filesystem: map[string]string{
+ "res/values/attrs.xml": "",
+ "resource_zip.zip": "",
+ },
+ Blueprint: `
+android_app {
+ name: "framework-res",
+ resource_zips: [
+ "resource_zip.zip",
+ ],
+ certificate: "platform",
+}
+
+filegroup {
+ name: "framework-res-package-jar",
+ srcs: [":framework-res{.export-package.apk}"],
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("framework_resources", "framework-res", AttrNameToString{
+ "certificate_name": `"platform"`,
+ "manifest": `"AndroidManifest.xml"`,
+ "resource_files": `["res/values/attrs.xml"]`,
+ "resource_zips": `["resource_zip.zip"]`,
+ "target_compatible_with": `["//build/bazel/platforms/os:android"]`,
+ }),
+ MakeBazelTargetNoRestrictions("filegroup", "framework-res-package-jar", AttrNameToString{
+ "srcs": `[":framework-res.export-package.apk"]`,
+ }),
+ }})
+
+}
diff --git a/bp2build/android_test_conversion_test.go b/bp2build/android_test_conversion_test.go
index 52413fa..486f154 100644
--- a/bp2build/android_test_conversion_test.go
+++ b/bp2build/android_test_conversion_test.go
@@ -47,7 +47,40 @@
name: "TestApp",
srcs: ["app.java"],
sdk_version: "current",
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("android_test", "TestApp", AttrNameToString{
+ "srcs": `["app.java"]`,
+ "manifest": `"AndroidManifest.xml"`,
+ "resource_files": `["res/res.png"]`,
+ "sdk_version": `"current"`,
+ "assets": `["assets/asset.png"]`,
+ "assets_dir": `"assets"`,
+ // no need for optimize = False because it's false for
+ // android_test by default
+ }),
+ }})
+}
+
+func TestAndroidTest_OptimizationEnabled(t *testing.T) {
+ runAndroidAppTestCase(t, Bp2buildTestCase{
+ Description: "Android test - simple example",
+ ModuleTypeUnderTest: "android_test",
+ ModuleTypeUnderTestFactory: java.AndroidTestFactory,
+ Filesystem: map[string]string{
+ "app.java": "",
+ "res/res.png": "",
+ "AndroidManifest.xml": "",
+ "assets/asset.png": "",
+ },
+ Blueprint: `
+android_test {
+ name: "TestApp",
+ srcs: ["app.java"],
+ sdk_version: "current",
optimize: {
+ enabled: true,
shrink: true,
optimize: true,
obfuscate: true,
@@ -62,6 +95,9 @@
"sdk_version": `"current"`,
"assets": `["assets/asset.png"]`,
"assets_dir": `"assets"`,
+ // optimize = True because it's false for android_test by
+ // default
+ "optimize": `True`,
}),
}})
}
@@ -98,6 +134,45 @@
"assets": `["assets/asset.png"]`,
"assets_dir": `"assets"`,
"testonly": `True`,
+ // no need for optimize = True because it's true for
+ // android_test_helper_app by default
+ }),
+ }})
+}
+
+func TestAndroidTestHelperApp_OptimizationDisabled(t *testing.T) {
+ runAndroidAppTestCase(t, Bp2buildTestCase{
+ Description: "Android test helper app - simple example",
+ ModuleTypeUnderTest: "android_test_helper_app",
+ ModuleTypeUnderTestFactory: java.AndroidTestHelperAppFactory,
+ Filesystem: map[string]string{
+ "app.java": "",
+ "res/res.png": "",
+ "AndroidManifest.xml": "",
+ "assets/asset.png": "",
+ },
+ Blueprint: `
+android_test_helper_app {
+ name: "TestApp",
+ srcs: ["app.java"],
+ sdk_version: "current",
+ optimize: {
+ enabled: false,
+ },
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("android_binary", "TestApp", AttrNameToString{
+ "srcs": `["app.java"]`,
+ "manifest": `"AndroidManifest.xml"`,
+ "resource_files": `["res/res.png"]`,
+ "sdk_version": `"current"`,
+ "assets": `["assets/asset.png"]`,
+ "assets_dir": `"assets"`,
+ "testonly": `True`,
+ // optimize = False because it's true for
+ // android_test_helper_app by default
+ "optimize": `False`,
}),
}})
}
diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go
index 7c26262..3e00453 100644
--- a/bp2build/bp2build_product_config.go
+++ b/bp2build/bp2build_product_config.go
@@ -6,6 +6,7 @@
"os"
"path/filepath"
"reflect"
+ "sort"
"strings"
"android/soong/android"
@@ -22,6 +23,32 @@
bp2buildTargets map[string]BazelTargets
}
+type bazelLabel struct {
+ repo string
+ pkg string
+ target string
+}
+
+func (l *bazelLabel) Less(other *bazelLabel) bool {
+ if l.repo < other.repo {
+ return true
+ }
+ if l.repo > other.repo {
+ return false
+ }
+ if l.pkg < other.pkg {
+ return true
+ }
+ if l.pkg > other.pkg {
+ return false
+ }
+ return l.target < other.target
+}
+
+func (l *bazelLabel) String() string {
+ return fmt.Sprintf("@%s//%s:%s", l.repo, l.pkg, l.target)
+}
+
func createProductConfigFiles(
ctx *CodegenContext,
metrics CodegenMetrics) (createProductConfigFilesResult, error) {
@@ -54,8 +81,8 @@
}
currentProductFolder := fmt.Sprintf("build/bazel/products/%s", targetProduct)
- if len(productVariables.PartitionVars.ProductDirectory) > 0 {
- currentProductFolder = fmt.Sprintf("%s%s", productVariables.PartitionVars.ProductDirectory, targetProduct)
+ if len(productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory) > 0 {
+ currentProductFolder = fmt.Sprintf("%s%s", productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.ProductDirectory, targetProduct)
}
productReplacer := strings.NewReplacer(
@@ -72,14 +99,22 @@
productsForTesting[i] = fmt.Sprintf(" \"@//build/bazel/tests/products:%s\",", productsForTesting[i])
}
- productLabelsToVariables := make(map[string]*android.ProductVariables)
- productLabelsToVariables[productReplacer.Replace("@//{PRODUCT_FOLDER}:{PRODUCT}")] = &productVariables
+ productLabelsToVariables := make(map[bazelLabel]*android.ProductVariables)
+ productLabelsToVariables[bazelLabel{
+ repo: "",
+ pkg: currentProductFolder,
+ target: targetProduct,
+ }] = &productVariables
for product, productVariablesStarlark := range productsForTestingMap {
productVariables, err := starlarkMapToProductVariables(productVariablesStarlark)
if err != nil {
return res, err
}
- productLabelsToVariables["@//build/bazel/tests/products:"+product] = &productVariables
+ productLabelsToVariables[bazelLabel{
+ repo: "",
+ pkg: "build/bazel/tests/products",
+ target: product,
+ }] = &productVariables
}
res.bp2buildTargets = make(map[string]BazelTargets)
@@ -194,7 +229,7 @@
}
func platformMappingContent(
- productLabelToVariables map[string]*android.ProductVariables,
+ productLabelToVariables map[bazelLabel]*android.ProductVariables,
soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
convertedModulePathMap map[string]string) (string, error) {
var result strings.Builder
@@ -211,9 +246,16 @@
mergedConvertedModulePathMap[k] = v
}
+ productLabels := make([]bazelLabel, 0, len(productLabelToVariables))
+ for k := range productLabelToVariables {
+ productLabels = append(productLabels, k)
+ }
+ sort.Slice(productLabels, func(i, j int) bool {
+ return productLabels[i].Less(&productLabels[j])
+ })
result.WriteString("platforms:\n")
- for productLabel, productVariables := range productLabelToVariables {
- platformMappingSingleProduct(productLabel, productVariables, soongConfigDefinitions, mergedConvertedModulePathMap, &result)
+ for _, productLabel := range productLabels {
+ platformMappingSingleProduct(productLabel, productLabelToVariables[productLabel], soongConfigDefinitions, mergedConvertedModulePathMap, &result)
}
return result.String(), nil
}
@@ -233,7 +275,7 @@
}
func platformMappingSingleProduct(
- label string,
+ label bazelLabel,
productVariables *android.ProductVariables,
soongConfigDefinitions soongconfig.Bp2BuildSoongConfigDefinitions,
convertedModulePathMap map[string]string,
@@ -249,11 +291,22 @@
defaultAppCertificateFilegroup = "@//" + filepath.Dir(proptools.String(productVariables.DefaultAppCertificate)) + ":generated_android_certificate_directory"
}
+ // TODO: b/301598690 - commas can't be escaped in a string-list passed in a platform mapping,
+ // so commas are switched for ":" here, and must be back-substituted into commas
+ // wherever the AAPTCharacteristics product config variable is used.
+ AAPTConfig := []string{}
+ for _, conf := range productVariables.AAPTConfig {
+ AAPTConfig = append(AAPTConfig, strings.Replace(conf, ",", ":", -1))
+ }
+
for _, suffix := range bazelPlatformSuffixes {
result.WriteString(" ")
- result.WriteString(label)
+ result.WriteString(label.String())
result.WriteString(suffix)
result.WriteString("\n")
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_characteristics=%s\n", proptools.String(productVariables.AAPTCharacteristics)))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_config=%s\n", strings.Join(AAPTConfig, ",")))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:aapt_preferred_config=%s\n", proptools.String(productVariables.AAPTPreferredConfig)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:always_use_prebuilt_sdks=%t\n", proptools.Bool(productVariables.Always_use_prebuilt_sdks)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:arc=%t\n", proptools.Bool(productVariables.Arc)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:apex_global_min_sdk_version_override=%s\n", proptools.String(productVariables.ApexGlobalMinSdkVersionOverride)))
@@ -272,7 +325,7 @@
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_name=%s\n", proptools.String(productVariables.DeviceName)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_page_size_agnostic=%t\n", proptools.Bool(productVariables.DevicePageSizeAgnostic)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_product=%s\n", proptools.String(productVariables.DeviceProduct)))
- result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_platform=%s\n", label))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:device_platform=%s\n", label.String()))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:enable_cfi=%t\n", proptools.BoolDefault(productVariables.EnableCFI, true)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:enforce_vintf_manifest=%t\n", proptools.Bool(productVariables.Enforce_vintf_manifest)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:malloc_not_svelte=%t\n", proptools.Bool(productVariables.Malloc_not_svelte)))
@@ -284,6 +337,8 @@
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:manifest_package_name_overrides=%s\n", strings.Join(productVariables.ManifestPackageNameOverrides, ",")))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:native_coverage=%t\n", proptools.Bool(productVariables.Native_coverage)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_sdk_final=%t\n", proptools.Bool(productVariables.Platform_sdk_final)))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_security_patch=%s\n", proptools.String(productVariables.Platform_security_patch)))
+ result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_version_last_stable=%s\n", proptools.String(productVariables.Platform_version_last_stable)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:platform_version_name=%s\n", proptools.String(productVariables.Platform_version_name)))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_brand=%s\n", productVariables.ProductBrand))
result.WriteString(fmt.Sprintf(" --//build/bazel/product_config:product_manufacturer=%s\n", productVariables.ProductManufacturer))
@@ -310,8 +365,9 @@
}
}
- for namespace, namespaceContents := range productVariables.VendorVars {
- for variable, value := range namespaceContents {
+ for _, namespace := range android.SortedKeys(productVariables.VendorVars) {
+ for _, variable := range android.SortedKeys(productVariables.VendorVars[namespace]) {
+ value := productVariables.VendorVars[namespace][variable]
key := namespace + "__" + variable
_, hasBool := soongConfigDefinitions.BoolVars[key]
_, hasString := soongConfigDefinitions.StringVars[key]
@@ -422,11 +478,15 @@
return result, nil
}
-func createTargets(productLabelsToVariables map[string]*android.ProductVariables, res map[string]BazelTargets) {
+func createTargets(productLabelsToVariables map[bazelLabel]*android.ProductVariables, res map[string]BazelTargets) {
createGeneratedAndroidCertificateDirectories(productLabelsToVariables, res)
+ createAvbKeyFilegroups(productLabelsToVariables, res)
+ for label, variables := range productLabelsToVariables {
+ createSystemPartition(label, &variables.PartitionVarsForBazelMigrationOnlyDoNotUse, res)
+ }
}
-func createGeneratedAndroidCertificateDirectories(productLabelsToVariables map[string]*android.ProductVariables, targets map[string]BazelTargets) {
+func createGeneratedAndroidCertificateDirectories(productLabelsToVariables map[bazelLabel]*android.ProductVariables, targets map[string]BazelTargets) {
var allDefaultAppCertificateDirs []string
for _, productVariables := range productLabelsToVariables {
if proptools.String(productVariables.DefaultAppCertificate) != "" {
@@ -454,3 +514,311 @@
})
}
}
+
+func createAvbKeyFilegroups(productLabelsToVariables map[bazelLabel]*android.ProductVariables, targets map[string]BazelTargets) {
+ var allAvbKeys []string
+ for _, productVariables := range productLabelsToVariables {
+ for _, partitionVariables := range productVariables.PartitionVarsForBazelMigrationOnlyDoNotUse.PartitionQualifiedVariables {
+ if partitionVariables.BoardAvbKeyPath != "" {
+ if !android.InList(partitionVariables.BoardAvbKeyPath, allAvbKeys) {
+ allAvbKeys = append(allAvbKeys, partitionVariables.BoardAvbKeyPath)
+ }
+ }
+ }
+ }
+ for _, key := range allAvbKeys {
+ dir := filepath.Dir(key)
+ name := filepath.Base(key)
+ content := fmt.Sprintf(`filegroup(
+ name = "%s_filegroup",
+ srcs = ["%s"],
+ visibility = ["//visibility:public"],
+)`, name, name)
+ targets[dir] = append(targets[dir], BazelTarget{
+ name: name + "_filegroup",
+ packageName: dir,
+ content: content,
+ ruleClass: "filegroup",
+ })
+ }
+}
+
+func createSystemPartition(platformLabel bazelLabel, variables *android.PartitionVariables, targets map[string]BazelTargets) {
+ if !variables.PartitionQualifiedVariables["system"].BuildingImage {
+ return
+ }
+ qualifiedVariables := variables.PartitionQualifiedVariables["system"]
+
+ imageProps := generateImagePropDictionary(variables, "system")
+ imageProps["skip_fsck"] = "true"
+
+ var properties strings.Builder
+ for _, prop := range android.SortedKeys(imageProps) {
+ properties.WriteString(prop)
+ properties.WriteRune('=')
+ properties.WriteString(imageProps[prop])
+ properties.WriteRune('\n')
+ }
+
+ var extraProperties strings.Builder
+ if variables.BoardAvbEnable {
+ extraProperties.WriteString(" avb_enable = True,\n")
+ extraProperties.WriteString(fmt.Sprintf(" avb_add_hashtree_footer_args = %q,\n", qualifiedVariables.BoardAvbAddHashtreeFooterArgs))
+ keypath := qualifiedVariables.BoardAvbKeyPath
+ if keypath != "" {
+ extraProperties.WriteString(fmt.Sprintf(" avb_key = \"//%s:%s\",\n", filepath.Dir(keypath), filepath.Base(keypath)+"_filegroup"))
+ extraProperties.WriteString(fmt.Sprintf(" avb_algorithm = %q,\n", qualifiedVariables.BoardAvbAlgorithm))
+ extraProperties.WriteString(fmt.Sprintf(" avb_rollback_index = %s,\n", qualifiedVariables.BoardAvbRollbackIndex))
+ extraProperties.WriteString(fmt.Sprintf(" avb_rollback_index_location = %s,\n", qualifiedVariables.BoardAvbRollbackIndexLocation))
+ }
+ }
+
+ targets[platformLabel.pkg] = append(targets[platformLabel.pkg], BazelTarget{
+ name: "system_image",
+ packageName: platformLabel.pkg,
+ content: fmt.Sprintf(`partition(
+ name = "system_image",
+ base_staging_dir = "//build/bazel/bazel_sandwich:system_staging_dir",
+ base_staging_dir_file_list = "//build/bazel/bazel_sandwich:system_staging_dir_file_list",
+ root_dir = "//build/bazel/bazel_sandwich:root_staging_dir",
+ selinux_file_contexts = "//build/bazel/bazel_sandwich:selinux_file_contexts",
+ image_properties = """
+%s
+""",
+%s
+ type = "system",
+)`, properties.String(), extraProperties.String()),
+ ruleClass: "partition",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules/partitions:partition.bzl",
+ symbols: []BazelLoadSymbol{{
+ symbol: "partition",
+ }},
+ }},
+ }, BazelTarget{
+ name: "system_image_test",
+ packageName: platformLabel.pkg,
+ content: `partition_diff_test(
+ name = "system_image_test",
+ partition1 = "//build/bazel/bazel_sandwich:make_system_image",
+ partition2 = ":system_image",
+)`,
+ ruleClass: "partition_diff_test",
+ loads: []BazelLoad{{
+ file: "//build/bazel/rules/partitions/diff:partition_diff.bzl",
+ symbols: []BazelLoadSymbol{{
+ symbol: "partition_diff_test",
+ }},
+ }},
+ }, BazelTarget{
+ name: "run_system_image_test",
+ packageName: platformLabel.pkg,
+ content: `run_test_in_build(
+ name = "run_system_image_test",
+ test = ":system_image_test",
+)`,
+ ruleClass: "run_test_in_build",
+ loads: []BazelLoad{{
+ file: "//build/bazel/bazel_sandwich:run_test_in_build.bzl",
+ symbols: []BazelLoadSymbol{{
+ symbol: "run_test_in_build",
+ }},
+ }},
+ })
+}
+
+var allPartitionTypes = []string{
+ "system",
+ "vendor",
+ "cache",
+ "userdata",
+ "product",
+ "system_ext",
+ "oem",
+ "odm",
+ "vendor_dlkm",
+ "odm_dlkm",
+ "system_dlkm",
+}
+
+// An equivalent of make's generate-image-prop-dictionary function
+func generateImagePropDictionary(variables *android.PartitionVariables, partitionType string) map[string]string {
+ partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
+ if !ok {
+ panic("Unknown partitionType: " + partitionType)
+ }
+ ret := map[string]string{}
+ if partitionType == "system" {
+ if len(variables.PartitionQualifiedVariables["system_other"].BoardPartitionSize) > 0 {
+ ret["system_other_size"] = variables.PartitionQualifiedVariables["system_other"].BoardPartitionSize
+ }
+ if len(partitionQualifiedVariables.ProductHeadroom) > 0 {
+ ret["system_headroom"] = partitionQualifiedVariables.ProductHeadroom
+ }
+ addCommonRoFlagsToImageProps(variables, partitionType, ret)
+ }
+ // TODO: other partition-specific logic
+ if variables.TargetUserimagesUseExt2 {
+ ret["fs_type"] = "ext2"
+ } else if variables.TargetUserimagesUseExt3 {
+ ret["fs_type"] = "ext3"
+ } else if variables.TargetUserimagesUseExt4 {
+ ret["fs_type"] = "ext4"
+ }
+
+ if !variables.TargetUserimagesSparseExtDisabled {
+ ret["extfs_sparse_flag"] = "-s"
+ }
+ if !variables.TargetUserimagesSparseErofsDisabled {
+ ret["erofs_sparse_flag"] = "-s"
+ }
+ if !variables.TargetUserimagesSparseSquashfsDisabled {
+ ret["squashfs_sparse_flag"] = "-s"
+ }
+ if !variables.TargetUserimagesSparseF2fsDisabled {
+ ret["f2fs_sparse_flag"] = "-S"
+ }
+ erofsCompressor := variables.BoardErofsCompressor
+ if len(erofsCompressor) == 0 && hasErofsPartition(variables) {
+ if len(variables.BoardErofsUseLegacyCompression) > 0 {
+ erofsCompressor = "lz4"
+ } else {
+ erofsCompressor = "lz4hc,9"
+ }
+ }
+ if len(erofsCompressor) > 0 {
+ ret["erofs_default_compressor"] = erofsCompressor
+ }
+ if len(variables.BoardErofsCompressorHints) > 0 {
+ ret["erofs_default_compress_hints"] = variables.BoardErofsCompressorHints
+ }
+ if len(variables.BoardErofsCompressorHints) > 0 {
+ ret["erofs_default_compress_hints"] = variables.BoardErofsCompressorHints
+ }
+ if len(variables.BoardErofsPclusterSize) > 0 {
+ ret["erofs_pcluster_size"] = variables.BoardErofsPclusterSize
+ }
+ if len(variables.BoardErofsShareDupBlocks) > 0 {
+ ret["erofs_share_dup_blocks"] = variables.BoardErofsShareDupBlocks
+ }
+ if len(variables.BoardErofsUseLegacyCompression) > 0 {
+ ret["erofs_use_legacy_compression"] = variables.BoardErofsUseLegacyCompression
+ }
+ if len(variables.BoardExt4ShareDupBlocks) > 0 {
+ ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
+ }
+ if len(variables.BoardFlashLogicalBlockSize) > 0 {
+ ret["flash_logical_block_size"] = variables.BoardFlashLogicalBlockSize
+ }
+ if len(variables.BoardFlashEraseBlockSize) > 0 {
+ ret["flash_erase_block_size"] = variables.BoardFlashEraseBlockSize
+ }
+ if len(variables.BoardExt4ShareDupBlocks) > 0 {
+ ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
+ }
+ if len(variables.BoardExt4ShareDupBlocks) > 0 {
+ ret["ext4_share_dup_blocks"] = variables.BoardExt4ShareDupBlocks
+ }
+ for _, partitionType := range allPartitionTypes {
+ if qualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]; ok && len(qualifiedVariables.ProductVerityPartition) > 0 {
+ ret[partitionType+"_verity_block_device"] = qualifiedVariables.ProductVerityPartition
+ }
+ }
+ // TODO: Vboot
+ // TODO: AVB
+ if variables.BoardUsesRecoveryAsBoot {
+ ret["recovery_as_boot"] = "true"
+ }
+ if variables.BoardBuildGkiBootImageWithoutRamdisk {
+ ret["gki_boot_image_without_ramdisk"] = "true"
+ }
+ if variables.ProductUseDynamicPartitionSize {
+ ret["use_dynamic_partition_size"] = "true"
+ }
+ if variables.CopyImagesForTargetFilesZip {
+ ret["use_fixed_timestamp"] = "true"
+ }
+ return ret
+}
+
+// Soong equivalent of make's add-common-ro-flags-to-image-props
+func addCommonRoFlagsToImageProps(variables *android.PartitionVariables, partitionType string, ret map[string]string) {
+ partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
+ if !ok {
+ panic("Unknown partitionType: " + partitionType)
+ }
+ if len(partitionQualifiedVariables.BoardErofsCompressor) > 0 {
+ ret[partitionType+"_erofs_compressor"] = partitionQualifiedVariables.BoardErofsCompressor
+ }
+ if len(partitionQualifiedVariables.BoardErofsCompressHints) > 0 {
+ ret[partitionType+"_erofs_compress_hints"] = partitionQualifiedVariables.BoardErofsCompressHints
+ }
+ if len(partitionQualifiedVariables.BoardErofsPclusterSize) > 0 {
+ ret[partitionType+"_erofs_pcluster_size"] = partitionQualifiedVariables.BoardErofsPclusterSize
+ }
+ if len(partitionQualifiedVariables.BoardExtfsRsvPct) > 0 {
+ ret[partitionType+"_extfs_rsv_pct"] = partitionQualifiedVariables.BoardExtfsRsvPct
+ }
+ if len(partitionQualifiedVariables.BoardF2fsSloadCompressFlags) > 0 {
+ ret[partitionType+"_f2fs_sldc_flags"] = partitionQualifiedVariables.BoardF2fsSloadCompressFlags
+ }
+ if len(partitionQualifiedVariables.BoardFileSystemCompress) > 0 {
+ ret[partitionType+"_f2fs_compress"] = partitionQualifiedVariables.BoardFileSystemCompress
+ }
+ if len(partitionQualifiedVariables.BoardFileSystemType) > 0 {
+ ret[partitionType+"_fs_type"] = partitionQualifiedVariables.BoardFileSystemType
+ }
+ if len(partitionQualifiedVariables.BoardJournalSize) > 0 {
+ ret[partitionType+"_journal_size"] = partitionQualifiedVariables.BoardJournalSize
+ }
+ if len(partitionQualifiedVariables.BoardPartitionReservedSize) > 0 {
+ ret[partitionType+"_reserved_size"] = partitionQualifiedVariables.BoardPartitionReservedSize
+ }
+ if len(partitionQualifiedVariables.BoardPartitionSize) > 0 {
+ ret[partitionType+"_size"] = partitionQualifiedVariables.BoardPartitionSize
+ }
+ if len(partitionQualifiedVariables.BoardSquashfsBlockSize) > 0 {
+ ret[partitionType+"_squashfs_block_size"] = partitionQualifiedVariables.BoardSquashfsBlockSize
+ }
+ if len(partitionQualifiedVariables.BoardSquashfsCompressor) > 0 {
+ ret[partitionType+"_squashfs_compressor"] = partitionQualifiedVariables.BoardSquashfsCompressor
+ }
+ if len(partitionQualifiedVariables.BoardSquashfsCompressorOpt) > 0 {
+ ret[partitionType+"_squashfs_compressor_opt"] = partitionQualifiedVariables.BoardSquashfsCompressorOpt
+ }
+ if len(partitionQualifiedVariables.BoardSquashfsDisable4kAlign) > 0 {
+ ret[partitionType+"_squashfs_disable_4k_align"] = partitionQualifiedVariables.BoardSquashfsDisable4kAlign
+ }
+ if len(partitionQualifiedVariables.BoardPartitionSize) == 0 && len(partitionQualifiedVariables.BoardPartitionReservedSize) == 0 && len(partitionQualifiedVariables.ProductHeadroom) == 0 {
+ ret[partitionType+"_disable_sparse"] = "true"
+ }
+ addCommonFlagsToImageProps(variables, partitionType, ret)
+}
+
+func hasErofsPartition(variables *android.PartitionVariables) bool {
+ return variables.PartitionQualifiedVariables["product"].BoardFileSystemType == "erofs" ||
+ variables.PartitionQualifiedVariables["system_ext"].BoardFileSystemType == "erofs" ||
+ variables.PartitionQualifiedVariables["odm"].BoardFileSystemType == "erofs" ||
+ variables.PartitionQualifiedVariables["vendor"].BoardFileSystemType == "erofs" ||
+ variables.PartitionQualifiedVariables["system"].BoardFileSystemType == "erofs" ||
+ variables.PartitionQualifiedVariables["vendor_dlkm"].BoardFileSystemType == "erofs" ||
+ variables.PartitionQualifiedVariables["odm_dlkm"].BoardFileSystemType == "erofs" ||
+ variables.PartitionQualifiedVariables["system_dlkm"].BoardFileSystemType == "erofs"
+}
+
+// Soong equivalent of make's add-common-flags-to-image-props
+func addCommonFlagsToImageProps(variables *android.PartitionVariables, partitionType string, ret map[string]string) {
+ // The selinux_fc will be handled separately
+ partitionQualifiedVariables, ok := variables.PartitionQualifiedVariables[partitionType]
+ if !ok {
+ panic("Unknown partitionType: " + partitionType)
+ }
+ ret["building_"+partitionType+"_image"] = boolToMakeString(partitionQualifiedVariables.BuildingImage)
+}
+
+func boolToMakeString(b bool) string {
+ if b {
+ return "true"
+ }
+ return ""
+}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index e6941df..53c37b9 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -287,9 +287,9 @@
return r.buildFileToTargets
}
-// struct to store state of go bazel targets
+// struct to store state of b bazel targets (e.g. go targets which do not implement android.Module)
// this implements bp2buildModule interface and is passed to generateBazelTargets
-type goBazelTarget struct {
+type bTarget struct {
targetName string
targetPackage string
bazelRuleClass string
@@ -297,26 +297,26 @@
bazelAttributes []interface{}
}
-var _ bp2buildModule = (*goBazelTarget)(nil)
+var _ bp2buildModule = (*bTarget)(nil)
-func (g goBazelTarget) TargetName() string {
- return g.targetName
+func (b bTarget) TargetName() string {
+ return b.targetName
}
-func (g goBazelTarget) TargetPackage() string {
- return g.targetPackage
+func (b bTarget) TargetPackage() string {
+ return b.targetPackage
}
-func (g goBazelTarget) BazelRuleClass() string {
- return g.bazelRuleClass
+func (b bTarget) BazelRuleClass() string {
+ return b.bazelRuleClass
}
-func (g goBazelTarget) BazelRuleLoadLocation() string {
- return g.bazelRuleLoadLocation
+func (b bTarget) BazelRuleLoadLocation() string {
+ return b.bazelRuleLoadLocation
}
-func (g goBazelTarget) BazelAttributes() []interface{} {
- return g.bazelAttributes
+func (b bTarget) BazelAttributes() []interface{} {
+ return b.bazelAttributes
}
// Creates a target_compatible_with entry that is *not* compatible with android
@@ -421,7 +421,7 @@
Target_compatible_with: targetNotCompatibleWithAndroid(),
}
- libTest := goBazelTarget{
+ libTest := bTarget{
targetName: gp.name,
targetPackage: gp.dir,
bazelRuleClass: "go_test",
@@ -514,7 +514,7 @@
Target_compatible_with: targetNotCompatibleWithAndroid(),
}
- lib := goBazelTarget{
+ lib := bTarget{
targetName: g.Name(),
targetPackage: ctx.ModuleDir(g),
bazelRuleClass: "go_library",
@@ -555,23 +555,35 @@
Deps []string
}
+type buildConversionMetadata struct {
+ nameToGoLibraryModule nameToGoLibraryModule
+ ndkHeaders []blueprint.Module
+}
+
type nameToGoLibraryModule map[string]goLibraryModule
-// Visit each module in the graph
+// Visit each module in the graph, and collect metadata about the build graph
// If a module is of type `bootstrap_go_package`, return a map containing metadata like its dir and deps
-func createGoLibraryModuleMap(ctx *android.Context) nameToGoLibraryModule {
- ret := nameToGoLibraryModule{}
+// If a module is of type `ndk_headers`, add it to a list and return the list
+func createBuildConversionMetadata(ctx *android.Context) buildConversionMetadata {
+ goMap := nameToGoLibraryModule{}
+ ndkHeaders := []blueprint.Module{}
ctx.VisitAllModules(func(m blueprint.Module) {
moduleType := ctx.ModuleType(m)
// We do not need to store information about blueprint_go_binary since it does not have any rdeps
if moduleType == "bootstrap_go_package" {
- ret[m.Name()] = goLibraryModule{
+ goMap[m.Name()] = goLibraryModule{
Dir: ctx.ModuleDir(m),
Deps: m.(*bootstrap.GoPackage).Deps(),
}
+ } else if moduleType == "ndk_headers" || moduleType == "versioned_ndk_headers" {
+ ndkHeaders = append(ndkHeaders, m)
}
})
- return ret
+ return buildConversionMetadata{
+ nameToGoLibraryModule: goMap,
+ ndkHeaders: ndkHeaders,
+ }
}
// Returns the deps in the transitive closure of a go target
@@ -620,7 +632,7 @@
Deps: goDepLabels(transitiveDeps, goModulesMap),
Target_compatible_with: targetNotCompatibleWithAndroid(),
}
- libTestSource := goBazelTarget{
+ libTestSource := bTarget{
targetName: goSource,
targetPackage: ctx.ModuleDir(g),
bazelRuleClass: "go_source",
@@ -669,7 +681,7 @@
ga.Srcs = goSrcLabels(ctx.Config(), ctx.ModuleDir(g), g.Srcs(), g.LinuxSrcs(), g.DarwinSrcs())
}
- bin := goBazelTarget{
+ bin := bTarget{
targetName: g.Name(),
targetPackage: ctx.ModuleDir(g),
bazelRuleClass: "go_binary",
@@ -700,7 +712,9 @@
// Visit go libraries in a pre-run and store its state in a map
// The time complexity remains O(N), and this does not add significant wall time.
- nameToGoLibMap := createGoLibraryModuleMap(ctx.Context())
+ meta := createBuildConversionMetadata(ctx.Context())
+ nameToGoLibMap := meta.nameToGoLibraryModule
+ ndkHeaders := meta.ndkHeaders
bpCtx := ctx.Context()
bpCtx.VisitAllModules(func(m blueprint.Module) {
@@ -769,13 +783,13 @@
} else if glib, ok := m.(*bootstrap.GoPackage); ok {
targets, targetErrs = generateBazelTargetsGoPackage(bpCtx, glib, nameToGoLibMap)
errs = append(errs, targetErrs...)
- metrics.IncrementRuleClassCount("go_library")
- metrics.AddConvertedModule(glib, "go_library", dir)
+ metrics.IncrementRuleClassCount("bootstrap_go_package")
+ metrics.AddConvertedModule(glib, "bootstrap_go_package", dir)
} else if gbin, ok := m.(*bootstrap.GoBinary); ok {
targets, targetErrs = generateBazelTargetsGoBinary(bpCtx, gbin, nameToGoLibMap)
errs = append(errs, targetErrs...)
- metrics.IncrementRuleClassCount("go_binary")
- metrics.AddConvertedModule(gbin, "go_binary", dir)
+ metrics.IncrementRuleClassCount("blueprint_go_binary")
+ metrics.AddConvertedModule(gbin, "blueprint_go_binary", dir)
} else {
metrics.AddUnconvertedModule(m, moduleType, dir, android.UnconvertedReason{
ReasonType: int(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED),
@@ -805,6 +819,39 @@
}
})
+ // Create an ndk_sysroot target that has a dependency edge on every target corresponding to Soong's ndk_headers
+ // This root target will provide headers to sdk variants of jni libraries
+ if ctx.Mode() == Bp2Build {
+ var depLabels bazel.LabelList
+ for _, ndkHeader := range ndkHeaders {
+ depLabel := bazel.Label{
+ Label: "//" + bpCtx.ModuleDir(ndkHeader) + ":" + ndkHeader.Name(),
+ }
+ depLabels.Add(&depLabel)
+ }
+ a := struct {
+ Deps bazel.LabelListAttribute
+ System_dynamic_deps bazel.LabelListAttribute
+ }{
+ Deps: bazel.MakeLabelListAttribute(bazel.UniqueSortedBazelLabelList(depLabels)),
+ System_dynamic_deps: bazel.MakeLabelListAttribute(bazel.MakeLabelList([]bazel.Label{})),
+ }
+ ndkSysroot := bTarget{
+ targetName: "ndk_sysroot",
+ targetPackage: "build/bazel/rules/cc", // The location is subject to change, use build/bazel for now
+ bazelRuleClass: "cc_library_headers",
+ bazelRuleLoadLocation: "//build/bazel/rules/cc:cc_library_headers.bzl",
+ bazelAttributes: []interface{}{&a},
+ }
+
+ if t, err := generateBazelTarget(bpCtx, ndkSysroot); err == nil {
+ dir := ndkSysroot.targetPackage
+ buildFileToTargets[dir] = append(buildFileToTargets[dir], t)
+ } else {
+ errs = append(errs, err)
+ }
+ }
+
if len(errs) > 0 {
return conversionResults{}, errs
}
diff --git a/bp2build/build_conversion_test.go b/bp2build/build_conversion_test.go
index afbfffa..8e51d98 100644
--- a/bp2build/build_conversion_test.go
+++ b/bp2build/build_conversion_test.go
@@ -349,19 +349,6 @@
},
},
{
- Description: "non-existent dep",
- Blueprint: `custom {
- name: "has_dep",
- arch_paths: [":dep"],
- bazel_module: { bp2build_available: true },
-}`,
- ExpectedBazelTargets: []string{
- MakeBazelTarget("custom", "has_dep", AttrNameToString{
- "arch_paths": `[":dep__BP2BUILD__MISSING__DEP"]`,
- }),
- },
- },
- {
Description: "arch-variant srcs",
Blueprint: `custom {
name: "arch_paths",
@@ -2101,3 +2088,219 @@
})
}
+
+func TestBp2buildDepsMutator_missingTransitiveDep(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ }
+
+ custom {
+ name: "has_deps",
+ arch_paths: [":has_missing_dep", ":foo"],
+ }
+
+ custom {
+ name: "has_missing_dep",
+ arch_paths: [":missing"],
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Skipping conversion of a target with missing transitive dep",
+ DepsMutator: true,
+ })
+}
+
+func TestBp2buildDepsMutator_missingDirectDep(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ arch_paths: [":exists"],
+ }
+ custom {
+ name: "exists",
+ }
+
+ custom {
+ name: "has_missing_dep",
+ arch_paths: [":missing"],
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{"arch_paths": `[":exists"]`},
+ ),
+ MakeBazelTarget(
+ "custom",
+ "exists",
+ AttrNameToString{},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Skipping conversion of a target with missing direct dep",
+ DepsMutator: true,
+ })
+}
+
+func TestBp2buildDepsMutator_unconvertedDirectDep(t *testing.T) {
+ bp := `
+ custom {
+ name: "has_unconverted_dep",
+ arch_paths: [":unconvertible"],
+ }
+
+ custom {
+ name: "unconvertible",
+ does_not_convert_to_bazel: true
+ }
+ `
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: []string{},
+ Description: "Skipping conversion of a target with unconverted direct dep",
+ DepsMutator: true,
+ })
+}
+
+func TestBp2buildDepsMutator_unconvertedTransitiveDep(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ arch_paths: [":has_unconverted_dep", ":bar"],
+ }
+
+ custom {
+ name: "bar",
+ }
+
+ custom {
+ name: "has_unconverted_dep",
+ arch_paths: [":unconvertible"],
+ }
+
+ custom {
+ name: "unconvertible",
+ does_not_convert_to_bazel: true
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "bar",
+ AttrNameToString{},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Skipping conversion of a target with unconverted transitive dep",
+ DepsMutator: true,
+ })
+}
+
+func TestBp2buildDepsMutator_alreadyExistsBuildDeps(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ arch_paths: [":bar"],
+ }
+ custom {
+ name: "bar",
+ arch_paths: [":checked_in"],
+ }
+ custom {
+ name: "checked_in",
+ arch_paths: [":checked_in"],
+ does_not_convert_to_bazel: true
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{"arch_paths": `[":bar"]`},
+ ),
+ MakeBazelTarget(
+ "custom",
+ "bar",
+ AttrNameToString{"arch_paths": `[":checked_in"]`},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"checked_in"},
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Convert target with already-existing build dep",
+ DepsMutator: true,
+ })
+}
+
+// Tests that deps of libc are always considered valid for libc. This circumvents
+// an issue that, in a variantless graph (such as bp2build's), libc has the
+// unique predicament that it depends on itself.
+func TestBp2buildDepsMutator_depOnLibc(t *testing.T) {
+ bp := `
+ custom {
+ name: "foo",
+ arch_paths: [":libc"],
+ }
+ custom {
+ name: "libc",
+ arch_paths: [":libc_dep"],
+ }
+ custom {
+ name: "libc_dep",
+ does_not_convert_to_bazel: true
+ }
+ `
+ expectedBazelTargets := []string{
+ MakeBazelTarget(
+ "custom",
+ "foo",
+ AttrNameToString{"arch_paths": `[":libc"]`},
+ ),
+ MakeBazelTarget(
+ "custom",
+ "libc",
+ AttrNameToString{"arch_paths": `[":libc_dep"]`},
+ ),
+ }
+ registerCustomModule := func(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("custom", customModuleFactoryHostAndDevice)
+ }
+ RunBp2BuildTestCase(t, registerCustomModule, Bp2buildTestCase{
+ StubbedBuildDefinitions: []string{"checked_in"},
+ Blueprint: bp,
+ ExpectedBazelTargets: expectedBazelTargets,
+ Description: "Convert target with dep on libc",
+ DepsMutator: true,
+ })
+}
diff --git a/bp2build/bzl_conversion_test.go b/bp2build/bzl_conversion_test.go
index 402d4b0..645298f 100644
--- a/bp2build/bzl_conversion_test.go
+++ b/bp2build/bzl_conversion_test.go
@@ -95,6 +95,7 @@
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"dir": attr.string(),
+ "does_not_convert_to_bazel": attr.bool(),
"embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
@@ -128,6 +129,7 @@
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"dir": attr.string(),
+ "does_not_convert_to_bazel": attr.bool(),
"embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
@@ -161,6 +163,7 @@
"bool_prop": attr.bool(),
"bool_ptr_prop": attr.bool(),
"dir": attr.string(),
+ "does_not_convert_to_bazel": attr.bool(),
"embedded_prop": attr.string(),
"int64_ptr_prop": attr.int(),
# nested_props start
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 560123e..5ddae68 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -159,6 +159,10 @@
"min_sdk_version": `"29"`,
"use_version_lib": `True`,
"whole_archive_deps": `["//build/soong/cc/libbuildversion:libbuildversion"]`,
+ "deps": `select({
+ "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
+ "//conditions:default": [],
+ })`,
}),
})
}
@@ -555,8 +559,8 @@
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
Dir: "foo/bar",
- StubbedBuildDefinitions: []string{"//foo/bar:prebuilt_whole_static_lib_for_shared", "//foo/bar:prebuilt_whole_static_lib_for_static",
- "//foo/bar:prebuilt_whole_static_lib_for_both"},
+ StubbedBuildDefinitions: []string{"//foo/bar:whole_static_lib_for_shared", "//foo/bar:whole_static_lib_for_static",
+ "//foo/bar:whole_static_lib_for_both"},
Filesystem: map[string]string{
"foo/bar/Android.bp": `
cc_library {
@@ -3351,6 +3355,7 @@
Description: "cc_library with target.apex",
ModuleTypeUnderTest: "cc_library",
ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ StubbedBuildDefinitions: []string{"bar", "baz", "buh"},
Blueprint: `
cc_library {
name: "foo",
@@ -3362,27 +3367,29 @@
exclude_static_libs: ["buh"],
}
}
-}`,
+}` + simpleModule("cc_library_static", "baz") +
+ simpleModule("cc_library_static", "buh") +
+ simpleModule("cc_library_static", "bar"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{
- "implementation_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
+ "implementation_deps": `[":baz"] + select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":buh__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":buh"],
})`,
- "implementation_dynamic_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
+ "implementation_dynamic_deps": `[":baz"] + select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":bar"],
})`,
"local_includes": `["."]`,
}),
MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
- "implementation_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
+ "implementation_deps": `[":baz"] + select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":buh__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":buh"],
})`,
- "implementation_dynamic_deps": `[":baz__BP2BUILD__MISSING__DEP"] + select({
+ "implementation_dynamic_deps": `[":baz"] + select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":bar"],
})`,
"local_includes": `["."]`,
}),
@@ -3408,20 +3415,23 @@
exclude_static_libs: ["abc"],
}
}
-}`,
+}` + simpleModule("cc_library_static", "bar") +
+ simpleModule("cc_library_static", "baz") +
+ simpleModule("cc_library_static", "abc"),
+ StubbedBuildDefinitions: []string{"bar", "baz", "abc"},
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_static", "foo", AttrNameToString{
"implementation_dynamic_deps": `select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":bar__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":bar"],
})`,
"dynamic_deps": `select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":baz__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":baz"],
})`,
"deps": `select({
"//build/bazel/rules/apex:in_apex": [],
- "//conditions:default": [":abc__BP2BUILD__MISSING__DEP"],
+ "//conditions:default": [":abc"],
})`,
"local_includes": `["."]`,
}),
@@ -5157,7 +5167,6 @@
Blueprint: `
cc_library {
name: "libfoo",
- bazel_module: { bp2build_available: false },
}
ndk_library {
name: "libfoo",
@@ -5165,6 +5174,7 @@
symbol_file: "libfoo.map.txt",
}
`,
+ StubbedBuildDefinitions: []string{"libfoo"},
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_stub_suite", "libfoo.ndk_stub_libs", AttrNameToString{
"api_surface": `"publicapi"`,
@@ -5210,3 +5220,34 @@
}
runCcLibraryTestCase(t, tc)
}
+
+func TestVersionedNdkHeadersConversion(t *testing.T) {
+ tc := Bp2buildTestCase{
+ Description: "versioned_ndk_headers conversion",
+ ModuleTypeUnderTest: "versioned_ndk_headers",
+ ModuleTypeUnderTestFactory: cc.VersionedNdkHeadersFactory,
+ Blueprint: `
+versioned_ndk_headers {
+ name: "libfoo_headers",
+ from: "from",
+ to: "to",
+}
+`,
+ Filesystem: map[string]string{
+ "from/foo.h": "",
+ "from/foo_other.h": "",
+ },
+ ExpectedBazelTargets: []string{
+ MakeBazelTargetNoRestrictions("ndk_headers", "libfoo_headers", AttrNameToString{
+ "strip_import_prefix": `"from"`,
+ "import_prefix": `"to"`,
+ "hdrs": `[
+ "from/foo.h",
+ "from/foo_other.h",
+ ]`,
+ "run_versioner": "True",
+ }),
+ },
+ }
+ runCcLibraryTestCase(t, tc)
+}
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index fde4c97..5168fe9 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -70,10 +70,6 @@
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers test",
Filesystem: map[string]string{
- "lib-1/lib1a.h": "",
- "lib-1/lib1b.h": "",
- "lib-2/lib2a.h": "",
- "lib-2/lib2b.h": "",
"dir-1/dir1a.h": "",
"dir-1/dir1b.h": "",
"dir-2/dir2a.h": "",
@@ -86,7 +82,6 @@
cc_library_headers {
name: "foo_headers",
export_include_dirs: ["dir-1", "dir-2"],
- header_libs: ["lib-1", "lib-2"],
arch: {
arm64: {
@@ -118,6 +113,10 @@
]`,
"sdk_version": `"current"`,
"min_sdk_version": `"29"`,
+ "deps": `select({
+ "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
+ "//conditions:default": [],
+ })`,
}),
},
})
@@ -318,7 +317,7 @@
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_static_lib_headers is reexported",
Filesystem: map[string]string{},
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "foo_no_reexport"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -326,7 +325,8 @@
static_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModule("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export") +
+ simpleModule("cc_library_headers", "foo_no_reexport"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -339,7 +339,7 @@
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_shared_lib_headers is reexported",
Filesystem: map[string]string{},
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "foo_no_reexport"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -347,7 +347,8 @@
shared_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModule("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export") +
+ simpleModule("cc_library_headers", "foo_no_reexport"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -360,7 +361,7 @@
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers exported_header_lib_headers is reexported",
Filesystem: map[string]string{},
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "foo_no_reexport"},
Blueprint: soongCcLibraryHeadersPreamble + `
cc_library_headers {
name: "foo_headers",
@@ -368,7 +369,8 @@
header_libs: ["foo_export", "foo_no_reexport"],
bazel_module: { bp2build_available: true },
}
-` + simpleModule("cc_library_headers", "foo_export"),
+` + simpleModule("cc_library_headers", "foo_export") +
+ simpleModule("cc_library_headers", "foo_no_reexport"),
ExpectedBazelTargets: []string{
MakeBazelTarget("cc_library_headers", "foo_headers", AttrNameToString{
"deps": `[":foo_export"]`,
@@ -422,7 +424,7 @@
func TestPrebuiltCcLibraryHeadersPreferredRdepUpdated(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers prebuilt preferred is used as rdep",
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "//foo/bar:foo_headers"},
Filesystem: map[string]string{
"foo/bar/Android.bp": simpleModule("cc_library_headers", "foo_headers"),
},
@@ -454,7 +456,7 @@
func TestPrebuiltCcLibraryHeadersRdepUpdated(t *testing.T) {
runCcLibraryHeadersTestCase(t, Bp2buildTestCase{
Description: "cc_library_headers not preferred is not used for rdep",
- StubbedBuildDefinitions: []string{"foo_export"},
+ StubbedBuildDefinitions: []string{"foo_export", "//foo/bar:foo_headers"},
Filesystem: map[string]string{
"foo/bar/Android.bp": simpleModule("cc_library_headers", "foo_headers"),
},
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index 6fa14e3..2c5305f 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -175,6 +175,10 @@
]`,
"sdk_version": `"current"`,
"min_sdk_version": `"29"`,
+ "deps": `select({
+ "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
+ "//conditions:default": [],
+ })`,
}),
},
})
@@ -1642,6 +1646,10 @@
})`,
"local_includes": `["."]`,
"sdk_version": `"current"`,
+ "deps": `select({
+ "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
+ "//conditions:default": [],
+ })`,
}),
},
})
diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go
index 7b97b39..09e40ed 100644
--- a/bp2build/cc_library_static_conversion_test.go
+++ b/bp2build/cc_library_static_conversion_test.go
@@ -203,6 +203,10 @@
]`,
"sdk_version": `"current"`,
"min_sdk_version": `"29"`,
+ "deps": `select({
+ "//build/bazel/rules/apex:unbundled_app": ["//build/bazel/rules/cc:ndk_sysroot"],
+ "//conditions:default": [],
+ })`,
}),
},
})
diff --git a/bp2build/filegroup_conversion_test.go b/bp2build/filegroup_conversion_test.go
index cb2e207..9c49dac 100644
--- a/bp2build/filegroup_conversion_test.go
+++ b/bp2build/filegroup_conversion_test.go
@@ -40,7 +40,9 @@
srcs: ["foo"],
}
`,
- ExpectedBazelTargets: []string{}})
+ ExpectedBazelTargets: []string{},
+ ExpectedHandcraftedModules: []string{"foo"}},
+ )
}
func TestFilegroupSameNameAsFile_MultipleFiles(t *testing.T) {
diff --git a/bp2build/gensrcs_conversion_test.go b/bp2build/gensrcs_conversion_test.go
index e808340..e9fc61d 100644
--- a/bp2build/gensrcs_conversion_test.go
+++ b/bp2build/gensrcs_conversion_test.go
@@ -15,16 +15,22 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/genrule"
- "testing"
)
+func registerModulesForGensrcsTests(ctx android.RegistrationContext) {
+ ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
+}
+
func TestGensrcs(t *testing.T) {
testcases := []struct {
- name string
- bp string
- expectedBazelAttrs AttrNameToString
+ name string
+ bp string
+ expectedBazelAttrs AttrNameToString
+ stubbedBuildDefinitions []string
}{
{
name: "gensrcs with common usage of properties",
@@ -37,18 +43,22 @@
data: ["foo/file.txt", ":external_files"],
output_extension: "out",
bazel_module: { bp2build_available: true },
+ }
+ filegroup {
+ name: "external_files",
}`,
+ stubbedBuildDefinitions: []string{"external_files"},
expectedBazelAttrs: AttrNameToString{
"srcs": `[
"test/input.txt",
- ":external_files__BP2BUILD__MISSING__DEP",
+ ":external_files",
]`,
"tools": `["program.py"]`,
"output_extension": `"out"`,
- "cmd": `"$(location program.py) $(SRC) $(OUT) $(location foo/file.txt) $(location :external_files__BP2BUILD__MISSING__DEP)"`,
+ "cmd": `"$(location program.py) $(SRC) $(OUT) $(location foo/file.txt) $(location :external_files)"`,
"data": `[
"foo/file.txt",
- ":external_files__BP2BUILD__MISSING__DEP",
+ ":external_files",
]`,
},
},
@@ -73,12 +83,13 @@
MakeBazelTargetNoRestrictions("gensrcs", "foo", test.expectedBazelAttrs),
}
t.Run(test.name, func(t *testing.T) {
- RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {},
+ RunBp2BuildTestCase(t, registerModulesForGensrcsTests,
Bp2buildTestCase{
ModuleTypeUnderTest: "gensrcs",
ModuleTypeUnderTestFactory: genrule.GenSrcsFactory,
Blueprint: test.bp,
ExpectedBazelTargets: expectedBazelTargets,
+ StubbedBuildDefinitions: test.stubbedBuildDefinitions,
})
})
}
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index 7e4e44e..426dffa 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -567,12 +567,20 @@
"b.aidl",
],
}
+filegroup {
+ name: "aidls_files",
+ srcs: [
+ "a.aidl",
+ "b.aidl",
+ ],
+}
java_library {
name: "example_lib",
srcs: [
"a.java",
"b.java",
":aidl_files",
+ ":aidls_files",
":random_other_files",
],
sdk_version: "current",
@@ -586,8 +594,18 @@
]`,
"tags": `["apex_available=//apex_available:anyapex"]`,
}),
+ MakeBazelTargetNoRestrictions("aidl_library", "aidls_files", AttrNameToString{
+ "srcs": `[
+ "a.aidl",
+ "b.aidl",
+ ]`,
+ "tags": `["apex_available=//apex_available:anyapex"]`,
+ }),
MakeBazelTarget("java_aidl_library", "example_lib_java_aidl_library", AttrNameToString{
- "deps": `[":aidl_files"]`,
+ "deps": `[
+ ":aidl_files",
+ ":aidls_files",
+ ]`,
}),
MakeBazelTarget("java_library", "example_lib", AttrNameToString{
"deps": `[":example_lib_java_aidl_library"]`,
@@ -617,7 +635,7 @@
Description: "java_library with non adjacent aidl filegroup",
ModuleTypeUnderTest: "java_library",
ModuleTypeUnderTestFactory: java.LibraryFactory,
- StubbedBuildDefinitions: []string{"A_aidl"},
+ StubbedBuildDefinitions: []string{"//path/to/A:A_aidl"},
Filesystem: map[string]string{
"path/to/A/Android.bp": `
filegroup {
diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go
index 4e96efe..cd89978 100644
--- a/bp2build/java_proto_conversion_test.go
+++ b/bp2build/java_proto_conversion_test.go
@@ -193,3 +193,46 @@
},
})
}
+
+func TestJavaProtoPlugin(t *testing.T) {
+ runJavaProtoTestCase(t, Bp2buildTestCase{
+ Description: "java_library proto plugin",
+ StubbedBuildDefinitions: []string{"protoc-gen-test-plugin"},
+ Blueprint: `java_library_static {
+ name: "java-protos",
+ srcs: ["a.proto"],
+ proto: {
+ plugin: "test-plugin",
+ },
+ sdk_version: "current",
+}
+
+java_library_static {
+ name: "protoc-gen-test-plugin",
+}
+`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("proto_library", "java-protos_proto", AttrNameToString{
+ "srcs": `["a.proto"]`,
+ }),
+ MakeBazelTarget(
+ "java_lite_proto_library",
+ "java-protos_java_proto_lite",
+ AttrNameToString{
+ "deps": `[":java-protos_proto"]`,
+ "plugin": `":protoc-gen-test-plugin"`,
+ "sdk_version": `"current"`,
+ }),
+ MakeBazelTarget("java_library", "java-protos", AttrNameToString{
+ "exports": `[":java-protos_java_proto_lite"]`,
+ "sdk_version": `"current"`,
+ }),
+ MakeNeverlinkDuplicateTargetWithAttrs(
+ "java_library",
+ "java-protos",
+ AttrNameToString{
+ "sdk_version": `"current"`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/java_test_host_conversion_test.go b/bp2build/java_test_host_conversion_test.go
index 95c239d..87f35f6 100644
--- a/bp2build/java_test_host_conversion_test.go
+++ b/bp2build/java_test_host_conversion_test.go
@@ -97,14 +97,13 @@
java_library {
name: "lib_a",
- bazel_module: { bp2build_available: false },
}
java_library {
name: "static_libs_a",
- bazel_module: { bp2build_available: false },
}
`,
+ StubbedBuildDefinitions: []string{"lib_a", "static_libs_a"},
ExpectedBazelTargets: []string{
MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{
"runtime_deps": `[
diff --git a/bp2build/rust_protobuf_conversion_test.go b/bp2build/rust_protobuf_conversion_test.go
index cf256aa..bd4f54b 100644
--- a/bp2build/rust_protobuf_conversion_test.go
+++ b/bp2build/rust_protobuf_conversion_test.go
@@ -27,7 +27,7 @@
func registerRustProtobufModuleTypes(ctx android.RegistrationContext) {
ctx.RegisterModuleType("rust_protobuf_host", rust.RustProtobufHostFactory)
-
+ ctx.RegisterModuleType("rust_protobuf", rust.RustProtobufHostFactory)
}
func TestRustProtobufHostTestCase(t *testing.T) {
@@ -58,3 +58,32 @@
},
)
}
+
+func TestRustProtobufTestCase(t *testing.T) {
+ runRustProtobufTestCase(t, Bp2buildTestCase{
+ Dir: "external/rust/crates/foo",
+ Blueprint: "",
+ Filesystem: map[string]string{
+ "external/rust/crates/foo/src/lib.rs": "",
+ "external/rust/crates/foo/src/helper.rs": "",
+ "external/rust/crates/foo/Android.bp": `
+rust_protobuf {
+ name: "libfoo",
+ crate_name: "foo",
+ protos: ["src/foo.proto"],
+ bazel_module: { bp2build_available: true },
+}
+`,
+ },
+ ExpectedBazelTargets: []string{
+ makeBazelTargetHostOrDevice("proto_library", "libfoo_proto", AttrNameToString{
+ "srcs": `["src/foo.proto"]`,
+ }, android.HostSupported),
+ makeBazelTargetHostOrDevice("rust_proto_library", "libfoo", AttrNameToString{
+ "crate_name": `"foo"`,
+ "deps": `[":libfoo_proto"]`,
+ }, android.HostSupported),
+ },
+ },
+ )
+}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index dfd4d57..6907487 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -27,6 +27,7 @@
"strings"
"testing"
+ "android/soong/ui/metrics/bp2build_metrics_proto"
"github.com/google/blueprint/proptools"
"android/soong/android"
@@ -87,6 +88,15 @@
// ExpectedBazelTargets compares the BazelTargets generated in `Dir` (if not empty).
// Otherwise, it checks the BazelTargets generated by `Blueprint` in the root directory.
ExpectedBazelTargets []string
+ // ExpectedConvertedModules asserts that modules in this list are labeled as "converted
+ // by bp2build" in the metrics reported by bp2build.
+ ExpectedConvertedModules []string
+ // ExpectedHandcraftedModules asserts that modules in this list are labeled as "handcrafted
+ // in build files" in the metrics reported by bp2build. Such modules are either explicitly
+ // defined in a BUILD file (by name), or registered as "otherwise implicitly handled"
+ // by bp2build (for example, by macros owned by other modules).
+ ExpectedHandcraftedModules []string
+
// AlreadyExistingBuildContents, if non-empty, simulates an already-present source BUILD file
// in the directory under test. The BUILD file has the given contents. This BUILD file
// will also be treated as "BUILD file to keep" by the simulated bp2build environment.
@@ -114,15 +124,37 @@
// be merged with the generated BUILD file. This allows custom BUILD targets
// to be used in tests, or use BUILD files to draw package boundaries.
KeepBuildFileForDirs []string
+
+ // If true, the bp2build_deps mutator is used for this test. This is an
+ // experimental mutator that will disable modules which have transitive
+ // dependencies with no bazel definition.
+ // TODO: b/285631638 - Enable this feature by default.
+ DepsMutator bool
+}
+
+func RunBp2BuildTestCaseExtraContext(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), modifyContext func(ctx *android.TestContext), tc Bp2buildTestCase) {
+ t.Helper()
+ preparers := []android.FixturePreparer{
+ android.FixtureRegisterWithContext(registerModuleTypes),
+ }
+ if modifyContext != nil {
+ preparers = append(preparers, android.FixtureModifyContext(modifyContext))
+ }
+ if tc.DepsMutator {
+ preparers = append(preparers, android.FixtureModifyConfig(func(cfg android.Config) {
+ cfg.Bp2buildDepsMutator = true
+ }))
+ }
+ preparers = append(preparers, SetBp2BuildTestRunner)
+ bp2buildSetup := android.GroupFixturePreparers(
+ preparers...,
+ )
+ runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
}
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
t.Helper()
- bp2buildSetup := android.GroupFixturePreparers(
- android.FixtureRegisterWithContext(registerModuleTypes),
- SetBp2BuildTestRunner,
- )
- runBp2BuildTestCaseWithSetup(t, bp2buildSetup, tc)
+ RunBp2BuildTestCaseExtraContext(t, registerModuleTypes, nil, tc)
}
func runBp2BuildTestCaseWithSetup(t *testing.T, extraPreparer android.FixturePreparer, tc Bp2buildTestCase) {
@@ -223,7 +255,7 @@
checkDir: tc.ExpectedBazelTargets,
}
- result.CompareAllBazelTargets(t, tc.Description, expectedTargets, true)
+ result.CompareAllBazelTargets(t, tc, expectedTargets, true)
}
// SetBp2BuildTestRunner customizes the test fixture mechanism to run tests in Bp2Build mode.
@@ -274,7 +306,7 @@
// have a corresponding expected BazelTarget.
//
// If ignoreUnexpected=true then it will ignore directories for which there are no expected targets.
-func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, description string, expectedTargets map[string][]string, ignoreUnexpected bool) {
+func (b BazelTestResult) CompareAllBazelTargets(t *testing.T, tc Bp2buildTestCase, expectedTargets map[string][]string, ignoreUnexpected bool) {
t.Helper()
actualTargets := b.buildFileToTargets
@@ -301,7 +333,24 @@
t.Errorf("expected %d bazel modules in %q but did not find any", expectedCount, dir)
}
} else {
- b.CompareBazelTargets(t, description, expected, actual)
+ b.CompareBazelTargets(t, tc.Description, expected, actual)
+ }
+ }
+
+ for _, module := range tc.ExpectedConvertedModules {
+ if _, found := b.metrics.convertedModulePathMap[module]; !found {
+ t.Errorf("expected %s to be generated by bp2build, but was not. Map of converted modules: %s", module, b.metrics.convertedModulePathMap)
+ }
+ }
+
+ for _, module := range tc.ExpectedHandcraftedModules {
+ if reason, found := b.metrics.serialized.UnconvertedModules[module]; !found {
+ t.Errorf("expected %s to be marked 'unconverted' by bp2build, but was not found. Full list: %s",
+ module, b.metrics.serialized.UnconvertedModules)
+ } else {
+ if reason.Type != bp2build_metrics_proto.UnconvertedReasonType_DEFINED_IN_BUILD_FILE {
+ t.Errorf("expected %s to be marked 'handcrafted' by bp2build, but was disabled for another reason: %s", module, reason)
+ }
}
}
}
@@ -363,6 +412,10 @@
// Prop used to indicate this conversion should be 1 module -> multiple targets
One_to_many_prop *bool
+ // Prop used to simulate an unsupported property in bp2build conversion. If this
+ // is true, this module should be treated as "unconvertible" via bp2build.
+ Does_not_convert_to_bazel *bool
+
Api *string // File describing the APIs of this module
Test_config_setting *bool // Used to test generation of config_setting targets
@@ -498,6 +551,10 @@
}
func (m *customModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if p := m.props.Does_not_convert_to_bazel; p != nil && *p {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "")
+ return
+ }
if p := m.props.One_to_many_prop; p != nil && *p {
customBp2buildOneToMany(ctx, m)
return
diff --git a/cc/Android.bp b/cc/Android.bp
index c32d854..8fa0fbe 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -18,6 +18,7 @@
"soong-genrule",
"soong-multitree",
"soong-snapshot",
+ "soong-sysprop-bp2build",
"soong-tradefed",
],
srcs: [
@@ -49,7 +50,6 @@
"snapshot_utils.go",
"stl.go",
"strip.go",
- "sysprop.go",
"tidy.go",
"util.go",
"vendor_snapshot.go",
diff --git a/cc/bp2build.go b/cc/bp2build.go
index 5dc119e..ec5d522 100644
--- a/cc/bp2build.go
+++ b/cc/bp2build.go
@@ -99,7 +99,7 @@
Tidy_timeout_srcs bazel.LabelListAttribute
}
-func (m *Module) convertTidyAttributes(ctx android.BaseMutatorContext, moduleAttrs *tidyAttributes) {
+func (m *Module) convertTidyAttributes(ctx android.Bp2buildMutatorContext, moduleAttrs *tidyAttributes) {
for _, f := range m.features {
if tidy, ok := f.(*tidyFeature); ok {
var tidyAttr *string
@@ -246,9 +246,9 @@
implementation bazel.LabelList
}
-type bazelLabelForDepsFn func(android.BazelConversionPathContext, []string) bazel.LabelList
+type bazelLabelForDepsFn func(android.Bp2buildMutatorContext, []string) bazel.LabelList
-func maybePartitionExportedAndImplementationsDeps(ctx android.BazelConversionPathContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
+func maybePartitionExportedAndImplementationsDeps(ctx android.Bp2buildMutatorContext, exportsDeps bool, allDeps, exportedDeps []string, fn bazelLabelForDepsFn) depsPartition {
if !exportsDeps {
return depsPartition{
implementation: fn(ctx, allDeps),
@@ -263,9 +263,9 @@
}
}
-type bazelLabelForDepsExcludesFn func(android.BazelConversionPathContext, []string, []string) bazel.LabelList
+type bazelLabelForDepsExcludesFn func(android.Bp2buildMutatorContext, []string, []string) bazel.LabelList
-func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.BazelConversionPathContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
+func maybePartitionExportedAndImplementationsDepsExcludes(ctx android.Bp2buildMutatorContext, exportsDeps bool, allDeps, excludes, exportedDeps []string, fn bazelLabelForDepsExcludesFn) depsPartition {
if !exportsDeps {
return depsPartition{
implementation: fn(ctx, allDeps, excludes),
@@ -352,7 +352,7 @@
Enabled bazel.BoolAttribute
}
-func parseSrc(ctx android.BazelConversionPathContext, srcLabelAttribute *bazel.LabelAttribute, axis bazel.ConfigurationAxis, config string, srcs []string) {
+func parseSrc(ctx android.Bp2buildMutatorContext, srcLabelAttribute *bazel.LabelAttribute, axis bazel.ConfigurationAxis, config string, srcs []string) {
srcFileError := func() {
ctx.ModuleErrorf("parseSrc: Expected at most one source file for %s %s\n", axis, config)
}
@@ -370,7 +370,7 @@
}
// NOTE: Used outside of Soong repo project, in the clangprebuilts.go bootstrap_go_package
-func Bp2BuildParsePrebuiltLibraryProps(ctx android.BazelConversionPathContext, module *Module, isStatic bool) prebuiltAttributes {
+func Bp2BuildParsePrebuiltLibraryProps(ctx android.Bp2buildMutatorContext, module *Module, isStatic bool) prebuiltAttributes {
var srcLabelAttribute bazel.LabelAttribute
bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
@@ -407,7 +407,7 @@
}
}
-func bp2BuildParsePrebuiltBinaryProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
+func bp2BuildParsePrebuiltBinaryProps(ctx android.Bp2buildMutatorContext, module *Module) prebuiltAttributes {
var srcLabelAttribute bazel.LabelAttribute
bp2BuildPropParseHelper(ctx, module, &prebuiltLinkerProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
if props, ok := props.(*prebuiltLinkerProperties); ok {
@@ -420,7 +420,7 @@
}
}
-func bp2BuildParsePrebuiltObjectProps(ctx android.BazelConversionPathContext, module *Module) prebuiltAttributes {
+func bp2BuildParsePrebuiltObjectProps(ctx android.Bp2buildMutatorContext, module *Module) prebuiltAttributes {
var srcLabelAttribute bazel.LabelAttribute
bp2BuildPropParseHelper(ctx, module, &prebuiltObjectProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
if props, ok := props.(*prebuiltObjectProperties); ok {
@@ -555,7 +555,7 @@
return result
}
-func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.BazelConversionPathContext, axis bazel.ConfigurationAxis, config string, props *BaseCompilerProperties) {
+func (ca *compilerAttributes) bp2buildForAxisAndConfig(ctx android.Bp2buildMutatorContext, axis bazel.ConfigurationAxis, config string, props *BaseCompilerProperties) {
// If there's arch specific srcs or exclude_srcs, generate a select entry for it.
// TODO(b/186153868): do this for OS specific srcs and exclude_srcs too.
srcsList, ok := parseSrcs(ctx, props)
@@ -680,7 +680,7 @@
}
// Parse srcs from an arch or OS's props value.
-func parseSrcs(ctx android.BazelConversionPathContext, props *BaseCompilerProperties) (bazel.LabelList, bool) {
+func parseSrcs(ctx android.Bp2buildMutatorContext, props *BaseCompilerProperties) (bazel.LabelList, bool) {
anySrcs := false
// Add srcs-like dependencies such as generated files.
// First create a LabelList containing these dependencies, then merge the values with srcs.
@@ -1265,7 +1265,7 @@
// resolveTargetApex re-adds the shared and static libs in target.apex.exclude_shared|static_libs props to non-apex variant
// since all libs are already excluded by default
-func (la *linkerAttributes) resolveTargetApexProp(ctx android.BazelConversionPathContext, props *BaseLinkerProperties) {
+func (la *linkerAttributes) resolveTargetApexProp(ctx android.Bp2buildMutatorContext, props *BaseLinkerProperties) {
excludeSharedLibs := bazelLabelForSharedDeps(ctx, props.Target.Apex.Exclude_shared_libs)
sharedExcludes := bazel.LabelList{Excludes: excludeSharedLibs.Includes}
sharedExcludesLabelList := bazel.LabelListAttribute{}
@@ -1378,10 +1378,10 @@
// having stubs or not, so Bazel select() statement can be used to choose
// source/stub variants of them.
apexAvailable := module.ApexAvailable()
- SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, 0, false)
- SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, 1, false)
+ SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.export, &la.dynamicDeps, &la.deps, 0, false)
+ SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, sharedDeps.implementation, &la.implementationDynamicDeps, &la.deps, 1, false)
if len(systemSharedLibs) > 0 {
- SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, bazelLabelForSharedDeps(ctx, systemSharedLibs), &la.systemDynamicDeps, 2, true)
+ SetStubsForDynamicDeps(ctx, axis, config, apexAvailable, bazelLabelForSharedDeps(ctx, systemSharedLibs), &la.systemDynamicDeps, &la.deps, 2, true)
}
}
@@ -1588,7 +1588,7 @@
}
func SetStubsForDynamicDeps(ctx android.Bp2buildMutatorContext, axis bazel.ConfigurationAxis,
- config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, ind int, buildNonApexWithStubs bool) {
+ config string, apexAvailable []string, dynamicLibs bazel.LabelList, dynamicDeps *bazel.LabelListAttribute, deps *bazel.LabelListAttribute, ind int, buildNonApexWithStubs bool) {
// Create a config_setting for each apex_available.
// This will be used to select impl of a dep if dep is available to the same apex.
@@ -1669,9 +1669,21 @@
existingValue.Append(bazel.MakeLabelList([]bazel.Label{label}))
dynamicDeps.SetSelectValue(bazel.OsAndInApexAxis, "unbundled_app", bazel.FirstUniqueBazelLabelList(existingValue))
}
+
+ // Add ndk_sysroot to deps.
+ // ndk_sysroot has a dependency edge on all ndk_headers, and will provide the .h files of _every_ ndk library
+ existingValue := deps.SelectValue(bazel.OsAndInApexAxis, "unbundled_app")
+ existingValue.Append(bazel.MakeLabelList([]bazel.Label{ndkSysrootLabel}))
+ deps.SetSelectValue(bazel.OsAndInApexAxis, "unbundled_app", bazel.FirstUniqueBazelLabelList(existingValue))
}
}
+var (
+ ndkSysrootLabel = bazel.Label{
+ Label: "//build/bazel/rules/cc:ndk_sysroot",
+ }
+)
+
func (la *linkerAttributes) convertStripProps(ctx android.BazelConversionPathContext, module *Module) {
bp2BuildPropParseHelper(ctx, module, &StripProperties{}, func(axis bazel.ConfigurationAxis, config string, props interface{}) {
if stripProperties, ok := props.(*StripProperties); ok {
@@ -1684,7 +1696,7 @@
})
}
-func (la *linkerAttributes) convertProductVariables(ctx android.BazelConversionPathContext, productVariableProps android.ProductConfigProperties) {
+func (la *linkerAttributes) convertProductVariables(ctx android.Bp2buildMutatorContext, productVariableProps android.ProductConfigProperties) {
type productVarDep struct {
// the name of the corresponding excludes field, if one exists
@@ -1692,7 +1704,7 @@
// reference to the bazel attribute that should be set for the given product variable config
attribute *bazel.LabelListAttribute
- depResolutionFunc func(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList
+ depResolutionFunc func(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList
}
// an intermediate attribute that holds Header_libs info, and will be appended to
@@ -1750,7 +1762,7 @@
la.implementationDeps.Append(headerDeps)
}
-func (la *linkerAttributes) finalize(ctx android.BazelConversionPathContext) {
+func (la *linkerAttributes) finalize(ctx android.Bp2buildMutatorContext) {
// if system dynamic deps have the default value, any use of a system dynamic library used will
// result in duplicate library errors for bionic OSes. Here, we explicitly exclude those libraries
// from bionic OSes and the no config case as these libraries only build for bionic OSes.
@@ -1891,39 +1903,39 @@
return xsd.CppBp2buildTargetName()
}
-func bazelLabelForWholeDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
- return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps)
+func bazelLabelForWholeDeps(ctx android.Bp2buildMutatorContext, modules []string) bazel.LabelList {
+ return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticWholeModuleDeps, /*markAsDeps=*/true)
}
-func bazelLabelForWholeDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func bazelLabelForWholeDepsExcludes(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticWholeModuleDeps)
}
-func bazelLabelForStaticDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func bazelLabelForStaticDepsExcludes(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForStaticModule)
}
-func bazelLabelForStaticDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
- return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule)
+func bazelLabelForStaticDeps(ctx android.Bp2buildMutatorContext, modules []string) bazel.LabelList {
+ return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForStaticModule, /*markAsDeps=*/true)
}
-func bazelLabelForSharedDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
- return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule)
+func bazelLabelForSharedDeps(ctx android.Bp2buildMutatorContext, modules []string) bazel.LabelList {
+ return android.BazelLabelForModuleDepsWithFn(ctx, modules, bazelLabelForSharedModule, /*markAsDeps=*/true)
}
-func bazelLabelForHeaderDeps(ctx android.BazelConversionPathContext, modules []string) bazel.LabelList {
+func bazelLabelForHeaderDeps(ctx android.Bp2buildMutatorContext, modules []string) bazel.LabelList {
// This is not elegant, but bp2build's shared library targets only propagate
// their header information as part of the normal C++ provider.
return bazelLabelForSharedDeps(ctx, modules)
}
-func bazelLabelForHeaderDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func bazelLabelForHeaderDepsExcludes(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
// This is only used when product_variable header_libs is processed, to follow
// the pattern of depResolutionFunc
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
}
-func bazelLabelForSharedDepsExcludes(ctx android.BazelConversionPathContext, modules, excludes []string) bazel.LabelList {
+func bazelLabelForSharedDepsExcludes(ctx android.Bp2buildMutatorContext, modules, excludes []string) bazel.LabelList {
return android.BazelLabelForModuleDepsExcludesWithFn(ctx, modules, excludes, bazelLabelForSharedModule)
}
diff --git a/cc/cc.go b/cc/cc.go
index 1896766..8c248f9 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1895,8 +1895,7 @@
// do not add a name suffix because it is a base module.
return ""
}
- vndkVersion = ctx.DeviceConfig().ProductVndkVersion()
- nameSuffix = ProductSuffix
+ return ProductSuffix
} else {
vndkVersion = ctx.DeviceConfig().VndkVersion()
nameSuffix = VendorSuffix
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 7ce0f37..f7eb8d2 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -41,7 +41,6 @@
PrepareForTestWithCcIncludeVndk,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
- variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("29")
}),
)
@@ -104,33 +103,6 @@
return result.TestContext
}
-// testCcNoVndk runs tests using the prepareForCcTest
-//
-// See testCc for an explanation as to how to stop using this deprecated method.
-//
-// deprecated
-func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
- t.Helper()
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
-
- return testCcWithConfig(t, config)
-}
-
-// testCcNoProductVndk runs tests using the prepareForCcTest
-//
-// See testCc for an explanation as to how to stop using this deprecated method.
-//
-// deprecated
-func testCcNoProductVndk(t *testing.T, bp string) *android.TestContext {
- t.Helper()
- config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
- config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.Platform_vndk_version = StringPtr("29")
-
- return testCcWithConfig(t, config)
-}
-
// testCcErrorWithConfig runs tests using the prepareForCcTest
//
// See testCc for an explanation as to how to stop using this deprecated method.
@@ -167,7 +139,6 @@
t.Helper()
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
testCcErrorWithConfig(t, pattern, config)
return
@@ -523,7 +494,6 @@
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
ctx := testCcWithConfig(t, config)
@@ -889,63 +859,6 @@
}
}
-func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
- t.Parallel()
- ctx := testCcNoVndk(t, `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
- cc_library {
- name: "libvndk-private",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- private: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libllndk",
- llndk: {
- symbol_file: "libllndk.map.txt",
- export_llndk_headers: ["libllndk_headers"],
- }
- }
-
- cc_library_headers {
- name: "libllndk_headers",
- llndk: {
- symbol_file: "libllndk.map.txt",
- },
- export_include_dirs: ["include"],
- }
- `)
-
- checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
- "LLNDK: libc.so",
- "LLNDK: libdl.so",
- "LLNDK: libft2.so",
- "LLNDK: libllndk.so",
- "LLNDK: libm.so",
- "VNDK-SP: libc++.so",
- "VNDK-core: libvndk-private.so",
- "VNDK-core: libvndk.so",
- "VNDK-private: libft2.so",
- "VNDK-private: libvndk-private.so",
- "VNDK-product: libc++.so",
- "VNDK-product: libvndk-private.so",
- "VNDK-product: libvndk.so",
- })
-}
-
func TestVndkModuleError(t *testing.T) {
t.Parallel()
// Check the error message for vendor_available and product_available properties.
@@ -1111,6 +1024,7 @@
cc_library {
name: "libnonvndk",
vendor_available: true,
+ product_available: true,
nocrt: true,
}
`)
@@ -1132,6 +1046,7 @@
cc_library {
name: "libnonvndk",
vendor_available: true,
+ product_available: true,
nocrt: true,
}
`)
@@ -1153,6 +1068,7 @@
cc_library {
name: "libnonvndk",
vendor_available: true,
+ product_available: true,
nocrt: true,
}
`)
@@ -1175,6 +1091,7 @@
cc_library {
name: "libnonvndk",
vendor_available: true,
+ product_available: true,
nocrt: true,
}
`)
@@ -1390,6 +1307,7 @@
cc_library {
name: "libanothervndksp",
vendor_available: true,
+ product_available: true,
}
`)
}
@@ -1467,7 +1385,6 @@
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
ctx := testCcWithConfig(t, config)
@@ -1482,70 +1399,6 @@
assertString(t, mod_product.outputFile.Path().Base(), "libvndk2-suffix.so")
}
-func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
- t.Parallel()
- // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
- ctx := testCcNoVndk(t, `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext",
- vendor: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
- `)
-
- // Ensures that the core variant of "libvndk_ext" can be found.
- mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
- if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
- t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
- }
-}
-
-func TestVndkExtWithoutProductVndkVersion(t *testing.T) {
- t.Parallel()
- // This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set.
- ctx := testCcNoProductVndk(t, `
- cc_library {
- name: "libvndk",
- vendor_available: true,
- product_available: true,
- vndk: {
- enabled: true,
- },
- nocrt: true,
- }
-
- cc_library {
- name: "libvndk_ext_product",
- product_specific: true,
- vndk: {
- enabled: true,
- extends: "libvndk",
- },
- nocrt: true,
- }
- `)
-
- // Ensures that the core variant of "libvndk_ext_product" can be found.
- mod := ctx.ModuleForTests("libvndk_ext_product", coreVariant).Module().(*Module)
- if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
- t.Errorf("\"libvndk_ext_product\" must extend from \"libvndk\" but get %q", extends)
- }
-}
-
func TestVndkExtError(t *testing.T) {
t.Parallel()
// This test ensures an error is emitted in ill-formed vndk-ext definition.
@@ -1920,7 +1773,6 @@
`
config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
- config.TestProductVariables.ProductVndkVersion = StringPtr("current")
config.TestProductVariables.Platform_vndk_version = StringPtr("29")
testCcWithConfig(t, config)
@@ -3034,24 +2886,6 @@
checkRuntimeLibs(t, nil, module)
}
-func TestRuntimeLibsNoVndk(t *testing.T) {
- t.Parallel()
- ctx := testCcNoVndk(t, runtimeLibAndroidBp)
-
- // If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
-
- variant := "android_arm64_armv8-a_shared"
-
- module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available"}, module)
-
- module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available", "libvendor1", "libproduct_vendor"}, module)
-
- module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
- checkRuntimeLibs(t, []string{"liball_available", "libproduct1", "libproduct_vendor"}, module)
-}
-
func checkStaticLibs(t *testing.T, expected []string, module *Module) {
t.Helper()
actual := module.Properties.AndroidMkStaticLibs
diff --git a/cc/config/global.go b/cc/config/global.go
index a586a3f..62b008b 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -29,83 +29,112 @@
// Flags used by lots of devices. Putting them in package static variables
// will save bytes in build.ninja so they aren't repeated for every file
commonGlobalCflags = []string{
- "-DANDROID",
- "-fmessage-length=0",
- "-W",
+ // Enable some optimization by default.
+ "-O2",
+
+ // Warnings enabled by default. Reference:
+ // https://clang.llvm.org/docs/DiagnosticsReference.html
"-Wall",
- "-Wno-unused",
+ "-Wextra",
"-Winit-self",
"-Wpointer-arith",
- "-Wunreachable-code-loop-increment",
+ "-Wunguarded-availability",
- // Make paths in deps files relative
- "-no-canonical-prefixes",
+ // Warnings treated as errors by default.
+ // See also noOverrideGlobalCflags for errors that cannot be disabled
+ // from Android.bp files.
- "-DNDEBUG",
- "-UDEBUG",
-
- "-fno-exceptions",
-
- "-O2",
- "-fdebug-default-version=5",
-
- "-fno-strict-aliasing",
-
+ // Using __DATE__/__TIME__ causes build nondeterminism.
"-Werror=date-time",
+ // Detects forgotten */& that usually cause a crash
+ "-Werror=int-conversion",
+ // Detects unterminated alignment modification pragmas, which often lead
+ // to ABI mismatch between modules and hard-to-debug crashes.
"-Werror=pragma-pack",
+ // Same as above, but detects alignment pragmas around a header
+ // inclusion.
"-Werror=pragma-pack-suspicious-include",
+ // Detects dividing an array size by itself, which is a common typo that
+ // leads to bugs.
+ "-Werror=sizeof-array-div",
+ // Detects a typo that cuts off a prefix from a string literal.
"-Werror=string-plus-int",
+ // Detects for loops that will never execute more than once (for example
+ // due to unconditional break), but have a non-empty loop increment
+ // clause. Often a mistake/bug.
"-Werror=unreachable-code-loop-increment",
- // Force deprecation warnings to be warnings for code that compiles with -Werror.
- // Making deprecated usages an error causes extreme pain when trying to deprecate anything.
- "-Wno-error=deprecated-declarations",
+ // Warnings that should not be errors even for modules with -Werror.
+ // Making deprecated usages an error causes extreme pain when trying to
+ // deprecate anything.
+ "-Wno-error=deprecated-declarations",
+ // This rarely indicates a bug. http://b/145210666
+ "-Wno-error=reorder-init-list",
+
+ // Warnings disabled by default.
+
+ // Designated initializer syntax is recommended by the Google C++ style
+ // and is OK to use even if not formally supported by the chosen C++
+ // version.
+ "-Wno-c99-designator",
+ // Detects uses of a GNU C extension equivalent to a limited form of
+ // constexpr. Enabling this would require replacing many constants with
+ // macros, which is not a good trade-off.
+ "-Wno-gnu-folding-constant",
+ // AIDL generated code redeclares pure virtual methods in each
+ // subsequent version of an interface, so this warning is currently
+ // infeasible to enable.
+ "-Wno-inconsistent-missing-override",
+ // Incompatible with the Google C++ style guidance to use 'int' for loop
+ // indices; poor signal to noise ratio.
+ "-Wno-sign-compare",
+ // Poor signal to noise ratio.
+ "-Wno-unused",
+
+ // Global preprocessor constants.
+
+ "-DANDROID",
+ "-DNDEBUG",
+ "-UDEBUG",
"-D__compiler_offsetof=__builtin_offsetof",
+ // Allows the bionic versioning.h to indirectly determine whether the
+ // option -Wunguarded-availability is on or not.
+ "-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__",
+
+ // -f and -g options.
// Emit address-significance table which allows linker to perform safe ICF. Clang does
// not emit the table by default on Android since NDK still uses GNU binutils.
"-faddrsig",
- // Help catch common 32/64-bit errors.
- "-Werror=int-conversion",
+ // Emit debugging data in a modern format (DWARF v5).
+ "-fdebug-default-version=5",
// Force clang to always output color diagnostics. Ninja will strip the ANSI
// color codes if it is not running in a terminal.
"-fcolor-diagnostics",
- // -Wno-sign-compare is incompatible with the Google C++ style guidance
- // to use 'int' for loop indices, and the signal to noise ratio is poor
- // anyway.
- "-Wno-sign-compare",
-
- // AIDL generated code redeclares pure virtual methods in each
- // subsequent version of an interface, so this is currently infeasible
- // to enable.
- "-Wno-inconsistent-missing-override",
-
- // Designated initializer syntax is recommended by the Google C++ style
- // guide and should not be a warning, at least by default.
- "-Wno-c99-designator",
-
- // Warnings from clang-12
- "-Wno-gnu-folding-constant",
-
- // http://b/145210666
- "-Wno-error=reorder-init-list",
-
- // Calls to the APIs that are newer than the min sdk version of the caller should be
- // guarded with __builtin_available.
- "-Wunguarded-availability",
- // This macro allows the bionic versioning.h to indirectly determine whether the
- // option -Wunguarded-availability is on or not.
- "-D__ANDROID_UNAVAILABLE_SYMBOLS_ARE_WEAK__",
-
// Turn off FMA which got enabled by default in clang-r445002 (http://b/218805949)
"-ffp-contract=off",
+ // Google C++ style does not allow exceptions, turn them off by default.
+ "-fno-exceptions",
+
+ // Disable optimizations based on strict aliasing by default.
+ // The performance benefit of enabling them currently does not outweigh
+ // the risk of hard-to-reproduce bugs.
+ "-fno-strict-aliasing",
+
+ // Disable line wrapping for error messages - it interferes with
+ // displaying logs in web browsers.
+ "-fmessage-length=0",
+
// Using simple template names reduces the size of debug builds.
"-gsimple-template-names",
+
+ // Make paths in deps files relative.
+ "-no-canonical-prefixes",
}
commonGlobalConlyflags = []string{}
@@ -117,6 +146,7 @@
"-fdebug-default-version=4",
}
+ // Compilation flags for device code; not applied to host code.
deviceGlobalCflags = []string{
"-ffunction-sections",
"-fdata-sections",
@@ -152,6 +182,7 @@
"-fvisibility-inlines-hidden",
}
+ // Linking flags for device code; not applied to host binaries.
deviceGlobalLdflags = []string{
"-Wl,-z,noexecstack",
"-Wl,-z,relro",
@@ -180,8 +211,6 @@
hostGlobalLldflags = commonGlobalLldflags
commonGlobalCppflags = []string{
- "-Wsign-promo",
-
// -Wimplicit-fallthrough is not enabled by -Wall.
"-Wimplicit-fallthrough",
@@ -194,6 +223,14 @@
// These flags are appended after the module's cflags, so they cannot be
// overridden from Android.bp files.
+ //
+ // NOTE: if you need to disable a warning to unblock a compiler upgrade
+ // and it is only triggered by third party code, add it to
+ // extraExternalCflags (if possible) or noOverrideExternalGlobalCflags
+ // (if the former doesn't work). If the new warning also occurs in first
+ // party code, try adding it to commonGlobalCflags first. Adding it here
+ // should be the last resort, because it prevents all code in Android from
+ // opting into the warning.
noOverrideGlobalCflags = []string{
"-Werror=bool-operation",
"-Werror=format-insufficient-args",
@@ -245,35 +282,9 @@
noOverride64GlobalCflags = []string{}
- // Similar to noOverrideGlobalCflags, but applies only to third-party code
- // (anything for which IsThirdPartyPath() in build/soong/android/paths.go
- // returns true - includes external/, most of vendor/ and most of hardware/)
- noOverrideExternalGlobalCflags = []string{
- // http://b/151457797
- "-fcommon",
- // http://b/191699019
- "-Wno-format-insufficient-args",
- // http://b/296321145
- // Indicates potential memory or stack corruption, so should be changed
- // to a hard error. Currently triggered by some vendor code.
- "-Wno-incompatible-function-pointer-types",
- // http://b/296321508
- // Introduced in response to a critical security vulnerability and
- // should be a hard error - it requires only whitespace changes to fix.
- "-Wno-misleading-indentation",
- // Triggered by old LLVM code in external/llvm. Likely not worth
- // enabling since it's a cosmetic issue.
- "-Wno-bitwise-instead-of-logical",
-
- "-Wno-unused-but-set-variable",
- "-Wno-unused-but-set-parameter",
- "-Wno-unqualified-std-cast-call",
- "-Wno-array-parameter",
- "-Wno-gnu-offsetof-extensions",
- }
-
- // Extra cflags for external third-party projects to disable warnings that
- // are infeasible to fix in all the external projects and their upstream repos.
+ // Extra cflags applied to third-party code (anything for which
+ // IsThirdPartyPath() in build/soong/android/paths.go returns true;
+ // includes external/, most of vendor/ and most of hardware/)
extraExternalCflags = []string{
"-Wno-enum-compare",
"-Wno-enum-compare-switch",
@@ -303,11 +314,41 @@
"-Wno-deprecated-non-prototype",
}
+ // Similar to noOverrideGlobalCflags, but applies only to third-party code
+ // (see extraExternalCflags).
+ // This section can unblock compiler upgrades when a third party module that
+ // enables -Werror and some group of warnings explicitly triggers newly
+ // added warnings.
+ noOverrideExternalGlobalCflags = []string{
+ // http://b/151457797
+ "-fcommon",
+ // http://b/191699019
+ "-Wno-format-insufficient-args",
+ // http://b/296321145
+ // Indicates potential memory or stack corruption, so should be changed
+ // to a hard error. Currently triggered by some vendor code.
+ "-Wno-incompatible-function-pointer-types",
+ // http://b/296321508
+ // Introduced in response to a critical security vulnerability and
+ // should be a hard error - it requires only whitespace changes to fix.
+ "-Wno-misleading-indentation",
+ // Triggered by old LLVM code in external/llvm. Likely not worth
+ // enabling since it's a cosmetic issue.
+ "-Wno-bitwise-instead-of-logical",
+
+ "-Wno-unused-but-set-variable",
+ "-Wno-unused-but-set-parameter",
+ "-Wno-unqualified-std-cast-call",
+ "-Wno-array-parameter",
+ "-Wno-gnu-offsetof-extensions",
+ }
+
llvmNextExtraCommonGlobalCflags = []string{
// Do not report warnings when testing with the top of trunk LLVM.
"-Wno-error",
}
+ // Flags that must not appear in any command line.
IllegalFlags = []string{
"-w",
}
diff --git a/cc/config/riscv64_device.go b/cc/config/riscv64_device.go
index e048622..d5bc760 100644
--- a/cc/config/riscv64_device.go
+++ b/cc/config/riscv64_device.go
@@ -27,6 +27,9 @@
"-Werror=implicit-function-declaration",
"-fno-emulated-tls",
"-march=rv64gcv_zba_zbb_zbs",
+ // Equivalent to "-munaligned-access", but our clang doesn't have that yet.
+ "-Xclang -target-feature -Xclang +unaligned-scalar-mem",
+ "-Xclang -target-feature -Xclang +unaligned-vector-mem",
}
riscv64ArchVariantCflags = map[string][]string{}
@@ -34,6 +37,9 @@
riscv64Ldflags = []string{
"-Wl,--hash-style=gnu",
"-march=rv64gcv_zba_zbb_zbs",
+ // Equivalent to "-munaligned-access", but our clang doesn't have that yet.
+ "-Xclang -target-feature -Xclang +unaligned-scalar-mem",
+ "-Xclang -target-feature -Xclang +unaligned-vector-mem",
}
riscv64Lldflags = append(riscv64Ldflags,
diff --git a/cc/fdo_profile.go b/cc/fdo_profile.go
index 05a8f46..cd3eb1e 100644
--- a/cc/fdo_profile.go
+++ b/cc/fdo_profile.go
@@ -72,7 +72,8 @@
ctx.CreateBazelTargetModuleWithRestrictions(
bazel.BazelTargetModuleProperties{
- Rule_class: "fdo_profile",
+ Bzl_load_location: "//build/bazel/rules/fdo:fdo_profile.bzl",
+ Rule_class: "fdo_profile",
},
android.CommonAttributes{
Name: fp.Name(),
diff --git a/cc/gen.go b/cc/gen.go
index b15f164..151f23d 100644
--- a/cc/gen.go
+++ b/cc/gen.go
@@ -20,6 +20,7 @@
"android/soong/aidl_library"
"android/soong/bazel"
+ "android/soong/sysprop/bp2build"
"github.com/google/blueprint"
@@ -240,12 +241,13 @@
}
func bp2buildCcSysprop(ctx android.Bp2buildMutatorContext, moduleName string, minSdkVersion *string, srcs bazel.LabelListAttribute) *bazel.LabelAttribute {
- labels := SyspropLibraryLabels{
- SyspropLibraryLabel: moduleName + "_sysprop_library",
- StaticLibraryLabel: moduleName + "_cc_sysprop_library_static",
+ labels := bp2build.SyspropLibraryLabels{
+ SyspropLibraryLabel: moduleName + "_sysprop_library",
+ CcStaticLibraryLabel: moduleName + "_cc_sysprop_library_static",
}
- Bp2buildSysprop(ctx, labels, srcs, minSdkVersion)
- return createLabelAttributeCorrespondingToSrcs(":"+labels.StaticLibraryLabel, srcs)
+ bp2build.Bp2buildBaseSyspropLibrary(ctx, labels.SyspropLibraryLabel, srcs)
+ bp2build.Bp2buildSyspropCc(ctx, labels, minSdkVersion)
+ return createLabelAttributeCorrespondingToSrcs(":"+labels.CcStaticLibraryLabel, srcs)
}
// Creates a LabelAttribute for a given label where the value is only set for
diff --git a/cc/genrule.go b/cc/genrule.go
index d1c4c2a..63c728c 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -84,7 +84,7 @@
return true
}
- if ctx.DeviceConfig().ProductVndkVersion() != "" && ctx.ProductSpecific() {
+ if ctx.ProductSpecific() {
return false
}
@@ -134,15 +134,8 @@
}
}
- if ctx.DeviceConfig().ProductVndkVersion() == "" {
- return variants
- }
-
if Bool(g.Product_available) || ctx.ProductSpecific() {
variants = append(variants, ProductVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion())
- if vndkVersion := ctx.DeviceConfig().ProductVndkVersion(); vndkVersion != "current" {
- variants = append(variants, ProductVariationPrefix+vndkVersion)
- }
}
return variants
diff --git a/cc/image.go b/cc/image.go
index f91762a..239f1db 100644
--- a/cc/image.go
+++ b/cc/image.go
@@ -427,7 +427,6 @@
platformVndkVersion := mctx.DeviceConfig().PlatformVndkVersion()
boardVndkVersion := mctx.DeviceConfig().VndkVersion()
- productVndkVersion := mctx.DeviceConfig().ProductVndkVersion()
recoverySnapshotVersion := mctx.DeviceConfig().RecoverySnapshotVersion()
usingRecoverySnapshot := recoverySnapshotVersion != "current" &&
recoverySnapshotVersion != ""
@@ -444,9 +443,6 @@
if boardVndkVersion == "current" {
boardVndkVersion = platformVndkVersion
}
- if productVndkVersion == "current" {
- productVndkVersion = platformVndkVersion
- }
if m.NeedsLlndkVariants() {
// This is an LLNDK library. The implementation of the library will be on /system,
@@ -462,9 +458,6 @@
if needVndkVersionVendorVariantForLlndk {
vendorVariants = append(vendorVariants, boardVndkVersion)
}
- if productVndkVersion != "" {
- productVariants = append(productVariants, productVndkVersion)
- }
} else if m.NeedsVendorPublicLibraryVariants() {
// A vendor public library has the implementation on /vendor, with stub variants
// for system and product.
@@ -473,9 +466,6 @@
if platformVndkVersion != "" {
productVariants = append(productVariants, platformVndkVersion)
}
- if productVndkVersion != "" {
- productVariants = append(productVariants, productVndkVersion)
- }
} else if boardVndkVersion == "" {
// If the device isn't compiling against the VNDK, we always
// use the core mode.
@@ -507,10 +497,6 @@
// product_available modules are available to /product.
if m.HasProductVariant() {
productVariants = append(productVariants, platformVndkVersion)
- // VNDK is always PLATFORM_VNDK_VERSION
- if !m.IsVndk() {
- productVariants = append(productVariants, productVndkVersion)
- }
}
} else if vendorSpecific && m.SdkVersion() == "" {
// This will be available in /vendor (or /odm) only
@@ -538,17 +524,10 @@
coreVariantNeeded = true
}
- if boardVndkVersion != "" && productVndkVersion != "" {
- if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
- // The module has "product_specific: true" that does not create core variant.
- coreVariantNeeded = false
- productVariants = append(productVariants, productVndkVersion)
- }
- } else {
- // Unless PRODUCT_PRODUCT_VNDK_VERSION is set, product partition has no
- // restriction to use system libs.
- // No product variants defined in this case.
- productVariants = []string{}
+ if coreVariantNeeded && productSpecific && m.SdkVersion() == "" {
+ // The module has "product_specific: true" that does not create core variant.
+ coreVariantNeeded = false
+ productVariants = append(productVariants, platformVndkVersion)
}
if m.RamdiskAvailable() {
diff --git a/cc/library.go b/cc/library.go
index e66ce08..90d91ca 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -547,54 +547,6 @@
includes.attrs.Deps.Append(lla)
}
-// includes provided to the module-lib API surface. This API surface is used by apexes.
-func getModuleLibApiIncludes(ctx android.TopDownMutatorContext, c *Module) apiIncludes {
- flagProps := c.library.(*libraryDecorator).flagExporter.Properties
- linkProps := c.library.(*libraryDecorator).baseLinker.Properties
- includes := android.FirstUniqueStrings(flagProps.Export_include_dirs)
- systemIncludes := android.FirstUniqueStrings(flagProps.Export_system_include_dirs)
- headerLibs := android.FirstUniqueStrings(linkProps.Export_header_lib_headers)
- attrs := bazelCcLibraryHeadersAttributes{
- Export_includes: bazel.MakeStringListAttribute(includes),
- Export_system_includes: bazel.MakeStringListAttribute(systemIncludes),
- Deps: bazel.MakeLabelListAttribute(apiHeaderLabels(ctx, headerLibs)),
- }
-
- return apiIncludes{
- name: c.Name() + ".module-libapi.headers",
- attrs: bazelCcApiLibraryHeadersAttributes{
- bazelCcLibraryHeadersAttributes: attrs,
- },
- }
-}
-
-func getVendorApiIncludes(ctx android.TopDownMutatorContext, c *Module) apiIncludes {
- baseProps := c.library.(*libraryDecorator).flagExporter.Properties
- llndkProps := c.library.(*libraryDecorator).Properties.Llndk
- includes := baseProps.Export_include_dirs
- systemIncludes := baseProps.Export_system_include_dirs
- // LLNDK can override the base includes
- if llndkIncludes := llndkProps.Override_export_include_dirs; llndkIncludes != nil {
- includes = llndkIncludes
- }
- if proptools.Bool(llndkProps.Export_headers_as_system) {
- systemIncludes = append(systemIncludes, includes...)
- includes = nil
- }
-
- attrs := bazelCcLibraryHeadersAttributes{
- Export_includes: bazel.MakeStringListAttribute(includes),
- Export_system_includes: bazel.MakeStringListAttribute(systemIncludes),
- Deps: bazel.MakeLabelListAttribute(apiHeaderLabels(ctx, llndkProps.Export_llndk_headers)),
- }
- return apiIncludes{
- name: c.Name() + ".vendorapi.headers",
- attrs: bazelCcApiLibraryHeadersAttributes{
- bazelCcLibraryHeadersAttributes: attrs,
- },
- }
-}
-
// cc_library creates both static and/or shared libraries for a device and/or
// host. By default, a cc_library has a single variant that targets the device.
// Specifying `host_supported: true` also creates a library that targets the
diff --git a/cc/library_headers.go b/cc/library_headers.go
index fccdf99..4da2b48 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -161,18 +161,3 @@
Tags: tags,
}, attrs)
}
-
-// Append .contribution suffix to input labels
-func apiBazelTargets(ll bazel.LabelList) bazel.LabelList {
- labels := make([]bazel.Label, 0)
- for _, l := range ll.Includes {
- labels = append(labels, bazel.Label{
- Label: android.ApiContributionTargetName(l.Label),
- })
- }
- return bazel.MakeLabelList(labels)
-}
-
-var (
- allArches = []string{"arm", "arm64", "x86", "x86_64"}
-)
diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go
index da5db1c..461aa96 100644
--- a/cc/ndk_headers.go
+++ b/cc/ndk_headers.go
@@ -19,6 +19,7 @@
"path/filepath"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/bazel"
@@ -151,6 +152,7 @@
Strip_import_prefix *string
Import_prefix *string
Hdrs bazel.LabelListAttribute
+ Run_versioner *bool
}
func (h *headerModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
@@ -217,6 +219,7 @@
// Note that this is really only built to handle bionic/libc/include.
type versionedHeaderModule struct {
android.ModuleBase
+ android.BazelModuleBase
properties versionedHeaderProperties
@@ -255,6 +258,25 @@
processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, m.srcPaths, installPaths)
}
+func (h *versionedHeaderModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ props := bazel.BazelTargetModuleProperties{
+ Rule_class: "ndk_headers",
+ Bzl_load_location: "//build/bazel/rules/cc:ndk_headers.bzl",
+ }
+ globPattern := headerGlobPattern(proptools.String(h.properties.From))
+ attrs := &bazelNdkHeadersAttributes{
+ Strip_import_prefix: h.properties.From,
+ Import_prefix: h.properties.To,
+ Run_versioner: proptools.BoolPtr(true),
+ Hdrs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, []string{globPattern})),
+ }
+ ctx.CreateBazelTargetModule(
+ props,
+ android.CommonAttributes{Name: h.Name()},
+ attrs,
+ )
+}
+
func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path,
srcPaths android.Paths, installPaths []android.WritablePath) android.Path {
// The versioner depends on a dependencies directory to simplify determining include paths
@@ -298,12 +320,13 @@
// Unlike the ndk_headers soong module, versioned_ndk_headers operates on a
// directory level specified in `from` property. This is only used to process
// the bionic/libc/include directory.
-func versionedNdkHeadersFactory() android.Module {
+func VersionedNdkHeadersFactory() android.Module {
module := &versionedHeaderModule{}
module.AddProperties(&module.properties)
android.InitAndroidModule(module)
+ android.InitBazelModule(module)
return module
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index b3bb2da..2064b1b 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -61,7 +61,7 @@
// because we don't want to spam the build output with "nothing
// changed" messages, so redirect output message to $out, and if
// changes were detected print the output and fail.
- Command: "$stgdiff $args --stg $in -o $out || (cat $out && false)",
+ Command: "$stgdiff $args --stg $in -o $out || (cat $out && false; echo 'Run $$ANDROID_BUILD_TOP/development/tools/ndk/update_ndk_abi.sh to update the ABI dumps.')",
CommandDeps: []string{"$stgdiff"},
}, "args")
@@ -386,9 +386,11 @@
// level.
abiDiffPath := android.PathForModuleOut(ctx, "stgdiff.timestamp")
prebuiltAbiDump := this.findPrebuiltAbiDump(ctx, this.apiLevel)
+ missingPrebuiltErrorTemplate :=
+ "Did not find prebuilt ABI dump for %q (%q). Generate with " +
+ "//development/tools/ndk/update_ndk_abi.sh."
missingPrebuiltError := fmt.Sprintf(
- "Did not find prebuilt ABI dump for %q (%q). Generate with "+
- "//development/tools/ndk/update_ndk_abi.sh.", this.libraryName(ctx),
+ missingPrebuiltErrorTemplate, this.libraryName(ctx),
prebuiltAbiDump.InvalidReason())
if !prebuiltAbiDump.Valid() {
ctx.Build(pctx, android.BuildParams{
@@ -424,12 +426,15 @@
nextAbiDiffPath := android.PathForModuleOut(ctx,
"abidiff_next.timestamp")
nextAbiDump := this.findPrebuiltAbiDump(ctx, *nextApiLevel)
+ missingNextPrebuiltError := fmt.Sprintf(
+ missingPrebuiltErrorTemplate, this.libraryName(ctx),
+ nextAbiDump.InvalidReason())
if !nextAbiDump.Valid() {
ctx.Build(pctx, android.BuildParams{
Rule: android.ErrorRule,
Output: nextAbiDiffPath,
Args: map[string]string{
- "error": missingPrebuiltError,
+ "error": missingNextPrebuiltError,
},
})
} else {
@@ -575,15 +580,6 @@
Library_name string
}
-// Names of the cc_api_header targets in the bp2build workspace
-func apiHeaderLabels(ctx android.TopDownMutatorContext, hdrLibs []string) bazel.LabelList {
- addSuffix := func(ctx android.BazelConversionPathContext, module blueprint.Module) string {
- label := android.BazelModuleLabel(ctx, module)
- return android.ApiContributionTargetName(label)
- }
- return android.BazelLabelForModuleDepsWithFn(ctx, hdrLibs, addSuffix)
-}
-
func ndkLibraryBp2build(ctx android.Bp2buildMutatorContext, c *Module) {
ndk, _ := c.linker.(*stubDecorator)
props := bazel.BazelTargetModuleProperties{
diff --git a/cc/ndk_sysroot.go b/cc/ndk_sysroot.go
index 54a2ee2..483d23b 100644
--- a/cc/ndk_sysroot.go
+++ b/cc/ndk_sysroot.go
@@ -64,7 +64,7 @@
func RegisterNdkModuleTypes(ctx android.RegistrationContext) {
ctx.RegisterModuleType("ndk_headers", NdkHeadersFactory)
ctx.RegisterModuleType("ndk_library", NdkLibraryFactory)
- ctx.RegisterModuleType("versioned_ndk_headers", versionedNdkHeadersFactory)
+ ctx.RegisterModuleType("versioned_ndk_headers", VersionedNdkHeadersFactory)
ctx.RegisterModuleType("preprocessed_ndk_headers", preprocessedNdkHeadersFactory)
ctx.RegisterParallelSingletonType("ndk", NdkSingleton)
}
diff --git a/cc/sanitize.go b/cc/sanitize.go
index 9ceb1c8..6329e97 100644
--- a/cc/sanitize.go
+++ b/cc/sanitize.go
@@ -1113,12 +1113,15 @@
// indirectly (via a mutator) sets the bool ptr to true, and you can't
// distinguish between the cases. It isn't needed though - both cases can be
// treated identically.
-func (sanitize *sanitize) isSanitizerEnabled(t SanitizerType) bool {
- if sanitize == nil {
+func (s *sanitize) isSanitizerEnabled(t SanitizerType) bool {
+ if s == nil {
+ return false
+ }
+ if proptools.Bool(s.Properties.SanitizeMutated.Never) {
return false
}
- sanitizerVal := sanitize.getSanitizerBoolPtr(t)
+ sanitizerVal := s.getSanitizerBoolPtr(t)
return sanitizerVal != nil && *sanitizerVal == true
}
diff --git a/cc/sanitize_test.go b/cc/sanitize_test.go
index 49117a0..31e668e 100644
--- a/cc/sanitize_test.go
+++ b/cc/sanitize_test.go
@@ -16,6 +16,7 @@
import (
"fmt"
+ "reflect"
"runtime"
"strings"
"testing"
@@ -1273,3 +1274,122 @@
t.Errorf("non-CFI variant of baz not expected to contain CFI flags ")
}
}
+
+func TestHwasan(t *testing.T) {
+ t.Parallel()
+
+ bp := `
+ cc_library_shared {
+ name: "shared_with_hwaddress",
+ static_libs: [
+ "static_dep_with_hwaddress",
+ "static_dep_no_hwaddress",
+ ],
+ sanitize: {
+ hwaddress: true,
+ },
+ sdk_version: "current",
+ stl: "c++_shared",
+ }
+
+ cc_library_static {
+ name: "static_dep_with_hwaddress",
+ sanitize: {
+ hwaddress: true,
+ },
+ sdk_version: "current",
+ stl: "c++_shared",
+ }
+
+ cc_library_static {
+ name: "static_dep_no_hwaddress",
+ sdk_version: "current",
+ stl: "c++_shared",
+ }
+`
+
+ androidArm := "android_arm_armv7-a-neon"
+ androidArm64 := "android_arm64_armv8-a"
+ androidX86 := "android_x86_silvermont"
+ sharedSuffix := "_shared"
+ hwasanSuffix := "_hwasan"
+ staticSuffix := "_static"
+ sdkSuffix := "_sdk"
+
+ sharedWithHwasanVariant := sharedSuffix + hwasanSuffix
+ sharedWithSdkVariant := sdkSuffix + sharedSuffix
+ staticWithHwasanVariant := staticSuffix + hwasanSuffix
+ staticWithSdkVariant := sdkSuffix + staticSuffix
+
+ testCases := []struct {
+ buildOs string
+ extraPreparer android.FixturePreparer
+ expectedVariants map[string][]string
+ }{
+ {
+ buildOs: androidArm64,
+ expectedVariants: map[string][]string{
+ "shared_with_hwaddress": []string{
+ androidArm64 + sharedWithHwasanVariant,
+ androidArm64 + sharedWithSdkVariant,
+ androidArm + sharedSuffix,
+ androidArm + sharedWithSdkVariant,
+ },
+ "static_dep_with_hwaddress": []string{
+ androidArm64 + staticSuffix,
+ androidArm64 + staticWithHwasanVariant,
+ androidArm64 + staticWithSdkVariant,
+ androidArm + staticSuffix,
+ androidArm + staticWithSdkVariant,
+ },
+ "static_dep_no_hwaddress": []string{
+ androidArm64 + staticSuffix,
+ androidArm64 + staticWithHwasanVariant,
+ androidArm64 + staticWithSdkVariant,
+ androidArm + staticSuffix,
+ androidArm + staticWithSdkVariant,
+ },
+ },
+ },
+ {
+ buildOs: androidX86,
+ extraPreparer: android.FixtureModifyConfig(func(config android.Config) {
+ config.Targets[android.Android] = []android.Target{
+ {
+ android.Android,
+ android.Arch{
+ ArchType: android.X86, ArchVariant: "silvermont", Abi: []string{"armeabi-v7a"}}, android.NativeBridgeDisabled, "", "", false},
+ }
+ }),
+ expectedVariants: map[string][]string{
+ "shared_with_hwaddress": []string{
+ androidX86 + sharedSuffix,
+ androidX86 + sharedWithSdkVariant,
+ },
+ "static_dep_with_hwaddress": []string{
+ androidX86 + staticSuffix,
+ androidX86 + staticWithSdkVariant,
+ },
+ "static_dep_no_hwaddress": []string{
+ androidX86 + staticSuffix,
+ androidX86 + staticWithSdkVariant,
+ },
+ },
+ },
+ }
+
+ for _, tc := range testCases {
+ preparer := android.GroupFixturePreparers(
+ prepareForCcTest,
+ android.OptionalFixturePreparer(tc.extraPreparer),
+ )
+ result := preparer.RunTestWithBp(t, bp)
+
+ for m, v := range tc.expectedVariants {
+ variants := result.ModuleVariantsForTests(m)
+ if !reflect.DeepEqual(variants, v) {
+ t.Errorf("Expected variants of %q to be %q, but got %q", m, v, variants)
+ }
+ }
+ }
+}
diff --git a/cc/sysprop.go b/cc/sysprop.go
deleted file mode 100644
index be03004..0000000
--- a/cc/sysprop.go
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (C) 2019 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package cc
-
-import (
- "android/soong/android"
- "android/soong/bazel"
-)
-
-// TODO(b/240463568): Additional properties will be added for API validation
-type bazelSyspropLibraryAttributes struct {
- Srcs bazel.LabelListAttribute
- Tags bazel.StringListAttribute
-}
-
-type bazelCcSyspropLibraryAttributes struct {
- Dep bazel.LabelAttribute
- Min_sdk_version *string
- Tags bazel.StringListAttribute
-}
-
-type SyspropLibraryLabels struct {
- SyspropLibraryLabel string
- SharedLibraryLabel string
- StaticLibraryLabel string
-}
-
-func Bp2buildSysprop(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLabels, srcs bazel.LabelListAttribute, minSdkVersion *string) {
- apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx, ctx.Module())
- ctx.CreateBazelTargetModule(
- bazel.BazelTargetModuleProperties{
- Rule_class: "sysprop_library",
- Bzl_load_location: "//build/bazel/rules/sysprop:sysprop_library.bzl",
- },
- android.CommonAttributes{Name: labels.SyspropLibraryLabel},
- &bazelSyspropLibraryAttributes{
- Srcs: srcs,
- Tags: apexAvailableTags,
- },
- )
-
- attrs := &bazelCcSyspropLibraryAttributes{
- Dep: *bazel.MakeLabelAttribute(":" + labels.SyspropLibraryLabel),
- Min_sdk_version: minSdkVersion,
- Tags: apexAvailableTags,
- }
-
- if labels.SharedLibraryLabel != "" {
- ctx.CreateBazelTargetModule(
- bazel.BazelTargetModuleProperties{
- Rule_class: "cc_sysprop_library_shared",
- Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
- },
- android.CommonAttributes{Name: labels.SharedLibraryLabel},
- attrs)
- }
-
- ctx.CreateBazelTargetModule(
- bazel.BazelTargetModuleProperties{
- Rule_class: "cc_sysprop_library_static",
- Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
- },
- android.CommonAttributes{Name: labels.StaticLibraryLabel},
- attrs)
-}
diff --git a/cc/test.go b/cc/test.go
index 8c63dc6..f128187 100644
--- a/cc/test.go
+++ b/cc/test.go
@@ -799,7 +799,7 @@
// cc_test that builds using gtest needs some additional deps
// addImplicitGtestDeps makes these deps explicit in the generated BUILD files
-func addImplicitGtestDeps(ctx android.BazelConversionPathContext, attrs *testBinaryAttributes, gtest, gtestIsolated bool) {
+func addImplicitGtestDeps(ctx android.Bp2buildMutatorContext, attrs *testBinaryAttributes, gtest, gtestIsolated bool) {
addDepsAndDedupe := func(lla *bazel.LabelListAttribute, modules []string) {
moduleLabels := android.BazelLabelForModuleDeps(ctx, modules)
lla.Value.Append(moduleLabels)
diff --git a/cc/testing.go b/cc/testing.go
index 7531f6d..71d986b 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -35,6 +35,7 @@
multitree.RegisterApiImportsModule(ctx)
+ ctx.RegisterModuleType("prebuilt_build_tool", android.NewPrebuiltBuildTool)
ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory)
ctx.RegisterModuleType("cc_object", ObjectFactory)
ctx.RegisterModuleType("cc_genrule", GenRuleFactory)
diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go
index 9ea337b..e8e930e 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -98,6 +98,11 @@
if !sanitizable.Shared() && sanitizable.IsSanitizerEnabled(scs) {
return false
}
+ // cfi and hwasan cannot be enabled at the same time.
+ // Skip variants that have both cfi and hwasan enabled.
+ if sanitizable.IsSanitizerEnabled(cfi) && sanitizable.IsSanitizerEnabled(Hwasan) {
+ return false
+ }
// cfi and hwasan also export both variants. But for static, we capture both.
// This is because cfi static libraries can't be linked from non-cfi modules,
// and vice versa.
diff --git a/cmd/sbox/sbox.go b/cmd/sbox/sbox.go
index fc56dd5..3364f50 100644
--- a/cmd/sbox/sbox.go
+++ b/cmd/sbox/sbox.go
@@ -119,6 +119,9 @@
}
manifest, err := readManifest(manifestFile)
+ if err != nil {
+ return err
+ }
if len(manifest.Commands) == 0 {
return fmt.Errorf("at least one commands entry is required in %q", manifestFile)
diff --git a/docs/clion.md b/docs/clion.md
index d6ae19a..110891b 100644
--- a/docs/clion.md
+++ b/docs/clion.md
@@ -3,6 +3,10 @@
Soong can generate CLion projects. This is intended for source code editing
only. Build should still be done via make/m/mm(a)/mmm(a).
+Note: alternatively, you can use
+[aidegen to generate a Clion or VSCode project](https://android.googlesource.com/platform/tools/asuite/+/refs/heads/master/aidegen/README.md)
+with a single command, using the `-i c` flag.
+
CMakeLists.txt project file generation is enabled via environment variable:
```bash
diff --git a/genrule/allowlists.go b/genrule/allowlists.go
index afa52cc..3e92706 100644
--- a/genrule/allowlists.go
+++ b/genrule/allowlists.go
@@ -135,10 +135,125 @@
"ltp_config_arm_64_lowmem_hwasan",
"ltp_config_x86",
"libbssl_sys_src_nostd",
+ "libcore-non-cts-tests-txt",
+ "ControlEnvProxyServerProto_cc",
+ "ControlEnvProxyServerProto_h",
+ "camera-its",
+ "android-cts-verifier",
+ "CtsApkVerityTestDebugFiles",
+ "vm-tests-tf-lib",
+ "egl_extensions_functions_hdr",
+ "egl_functions_hdr",
+ "gles1_core_functions_hdr",
+ "gles1_extensions_functions_hdr",
+ "gles2_core_functions_hdr",
+ "gles2_extensions_functions_hdr",
+ "gles31_only_functions_hdr",
+ "gles3_only_functions_hdr",
+ "angle_commit_id",
+ "deqp_spvtools_update_build_version",
+ "emp_ematch.yacc.c",
+ "emp_ematch.yacc.h",
+ "libchrome-crypto-include",
+ "libchrome-include",
+ "libmojo_jni_headers",
+ "libxml2_schema_fuzz_corpus",
+ "libxml2_xml_fuzz_corpus",
+ "libc_musl_sysroot_bits",
+ "awkgram.tab.h",
+ "openwrt_rootfs_combined_aarch64",
+ "openwrt_rootfs_combined_x86_64",
+ "openwrt_rootfs_customization_aarch64",
+ "openwrt_rootfs_customization_x86_64",
+ "pandora-python-gen-src",
+ "pdl_cxx_canonical_be_src_gen",
+ "pdl_cxx_canonical_be_test_gen",
+ "pdl_cxx_canonical_le_src_gen",
+ "pdl_cxx_canonical_le_test_gen",
+ "pdl_python_generator_be_test_gen",
+ "pdl_python_generator_le_test_gen",
+ "pdl_rust_noalloc_le_test_backend_srcs",
+ "pdl_rust_noalloc_le_test_gen_harness",
+ "swiftshader_spvtools_update_build_version",
+ "uwb_core_artifacts",
+ "futility_cmds",
+ "MultiDexLegacyTestApp_genrule",
+ "com.android.overlaytest.overlaid.pem",
+ "com.android.overlaytest.overlaid.pubkey",
+ "com.android.overlaytest.overlay.pem",
+ "com.android.overlaytest.overlay.pubkey",
+ "wm_shell_protolog_src",
+ "services.core.protologsrc",
+ "PackageManagerServiceServerTests_apks_as_resources",
+ "wmtests.protologsrc",
+ "com.android.apex.apkrollback.test.pem",
+ "com.android.apex.apkrollback.test.pubkey",
+ "UpdatableSystemFontTest_NotoColorEmojiV0.sig",
+ "UpdatableSystemFontTest_NotoColorEmojiV0.ttf",
+ "UpdatableSystemFontTest_NotoColorEmojiVPlus1.sig",
+ "UpdatableSystemFontTest_NotoColorEmojiVPlus1.ttf",
+ "UpdatableSystemFontTest_NotoColorEmojiVPlus2.sig",
+ "UpdatableSystemFontTest_NotoColorEmojiVPlus2.ttf",
+ "temp_layoutlib",
+ "android-support-multidex-instrumentation-version",
+ "android-support-multidex-version",
+ "core-tests-smali-dex",
+ "gd_hci_packets_python3_gen",
+ "gd_smp_packets_python3_gen",
+ "bluetooth_core_rust_packets",
+ "HeadlessBuildTimestamp",
+ "hci_packets_python3_gen",
+ "link_layer_packets_python3_gen",
+ "llcp_packets_python3_gen",
+ "rootcanal_bredr_bb_packets_cxx_gen",
+ "rootcanal_hci_packets_cxx_gen",
+ "rootcanal_link_layer_packets_cxx_gen",
+ "authfs_test_apk_assets",
+ "measure_io_as_jar",
+ "statsd-config-protos",
+ "statsd-config-protos",
+ "sample-profile-text-protos",
+ "sample-profile-text-protos",
+ "lib-test-profile-text-protos",
+ "lib-test-profile-text-protos",
+ "common-profile-text-protos",
+ "common-profile-text-protos",
+ "vndk_abi_dump_zip",
+ "r8retrace-dexdump-sample-app",
+ "gen_key_mismatch_capex",
+ "gen_corrupt_rebootless_apex",
+ "gen_corrupt_superblock_apex",
+ "gen_manifest_mismatch_apex_no_hashtree",
+ "apexer_test_host_tools",
+ "com.android.apex.cts.shim.debug.pem",
+ "com.android.apex.cts.shim.debug.pubkey",
+ "com.android.apex.cts.shim.pem",
+ "com.android.apex.cts.shim.pubkey",
+ "com.android.apex.cts.shim.v2_no_pb",
+ "com.android.apex.cts.shim.v2_signed_bob",
+ "com.android.apex.cts.shim.v2_signed_bob_rot",
+ "com.android.apex.cts.shim.v2_signed_bob_rot_rollback",
+ "com.android.apex.cts.shim.v2_unsigned_apk_container",
+ "com.android.apex.cts.shim.v3_signed_bob",
+ "com.android.apex.cts.shim.v3_signed_bob_rot",
+ "com.android.apex.cts.shim_not_pre_installed.pem",
+ "com.android.apex.cts.shim_not_pre_installed.pubkey",
+ "com.android.apex.rotation.key.bob.pem",
+ "com.android.apex.rotation.key.bob.pk8",
+ "com.android.apex.rotation.key.bob.rot.rollback",
+ "com.android.apex.rotation.key.bob.rot",
+ "com.android.apex.rotation.key.bob.x509.pem",
+ "generate_hash_v1",
+ "ue_unittest_erofs_imgs",
+ "ue_unittest_erofs_imgs",
+ "ue_unittest_erofs_imgs",
+ "vts_vndk_abi_dump_zip",
+ "atest_integration_fake_src",
}
SandboxingDenyPathList = []string{
"art/test",
"external/perfetto",
+ "external/cronet",
}
)
diff --git a/jar/jar.go b/jar/jar.go
index f164ee1..54eded9 100644
--- a/jar/jar.go
+++ b/jar/jar.go
@@ -166,10 +166,23 @@
}
s.IsIdentRune = javaIdentRune
- tok := s.Scan()
- if sErr != nil {
- return "", sErr
+ var tok rune
+ for {
+ tok = s.Scan()
+ if sErr != nil {
+ return "", sErr
+ }
+ // If the first token is an annotation, it could be annotating a package declaration, so consume them.
+ // Note that this does not support "complex" annotations with attributes, e.g. @Foo(x=y).
+ if tok != '@' {
+ break
+ }
+ tok = s.Scan()
+ if tok != scanner.Ident || sErr != nil {
+ return "", fmt.Errorf("expected annotation identifier, got @%v", tok)
+ }
}
+
if tok == scanner.Ident {
switch s.TokenText() {
case "package":
@@ -189,9 +202,6 @@
default:
return "", fmt.Errorf(`expected first token of java file to be "package", got %q`, s.TokenText())
}
- } else if tok == '@' {
- // File has no package statement, first token is an annotation
- return "", nil
} else if tok == scanner.EOF {
// File no package statement, it has no non-whitespace non-comment tokens
return "", nil
diff --git a/jar/jar_test.go b/jar/jar_test.go
index c92011e..61da9bb 100644
--- a/jar/jar_test.go
+++ b/jar/jar_test.go
@@ -61,6 +61,16 @@
in: "package 0foo.bar;",
wantErr: true,
},
+ {
+ name: "annotations",
+ in: "@NonNullApi\n@X\npackage foo.bar;",
+ want: "foo.bar",
+ },
+ {
+ name: "complex annotation",
+ in: "@Foo(x=y)\n@package foo.bar;",
+ wantErr: true, // Complex annotation not supported yet.
+ },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
diff --git a/java/aar.go b/java/aar.go
index 8f5deab..44496dc 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -1223,6 +1223,7 @@
type bazelAapt struct {
Manifest bazel.Label
Resource_files bazel.LabelListAttribute
+ Resource_zips bazel.LabelListAttribute
Assets_dir bazel.StringAttribute
Assets bazel.LabelListAttribute
}
@@ -1267,15 +1268,30 @@
assets = bazel.MakeLabelList(android.RootToModuleRelativePaths(ctx, androidResourceGlob(ctx, dir)))
}
+ var resourceZips bazel.LabelList
+ if len(a.aaptProperties.Resource_zips) > 0 {
+ if ctx.ModuleName() == "framework-res" {
+ resourceZips = android.BazelLabelForModuleSrc(ctx, a.aaptProperties.Resource_zips)
+ } else {
+ //TODO: b/301593550 - Implement support for this
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "resource_zips")
+ return &bazelAapt{}, false
+ }
+ }
return &bazelAapt{
android.BazelLabelForModuleSrcSingle(ctx, manifest),
bazel.MakeLabelListAttribute(resourceFiles),
+ bazel.MakeLabelListAttribute(resourceZips),
assetsDir,
bazel.MakeLabelListAttribute(assets),
}, true
}
func (a *AARImport) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ if len(a.properties.Aars) == 0 {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_PROPERTY_UNSUPPORTED, "aars can't be empty")
+ return
+ }
aars := android.BazelLabelForModuleSrcExcludes(ctx, a.properties.Aars, []string{})
exportableStaticLibs := []string{}
// TODO(b/240716882): investigate and handle static_libs deps that are not imports. They are not supported for export by Bazel.
@@ -1340,10 +1356,12 @@
if !commonAttrs.Srcs.IsEmpty() {
deps.Append(depLabels.StaticDeps) // we should only append these if there are sources to use them
} else if !depLabels.Deps.IsEmpty() {
- ctx.MarkBp2buildUnconvertible(
- bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED,
- "Module has direct dependencies but no sources. Bazel will not allow this.")
- return
+ // android_library does not accept deps when there are no srcs because
+ // there is no compilation happening, but it accepts exports.
+ // The non-empty deps here are unnecessary as deps on the android_library
+ // since they aren't being propagated to any dependencies.
+ // So we can drop deps here.
+ deps = bazel.LabelListAttribute{}
}
name := a.Name()
props := AndroidLibraryBazelTargetModuleProperties()
diff --git a/java/app.go b/java/app.go
index 6030500..166c22d 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1683,9 +1683,25 @@
Updatable: a.appProperties.Updatable,
}
- if !BoolDefault(a.dexProperties.Optimize.Enabled, true) {
- appAttrs.Optimize = proptools.BoolPtr(false)
- } else {
+ // As framework-res has no sources, no deps in the Bazel sense, and java compilation, dexing and optimization is skipped by
+ // Soong specifically for it, return early here before any of the conversion work for the above is attempted.
+ if ctx.ModuleName() == "framework-res" {
+ appAttrs.bazelAapt = aapt
+ return true, android.CommonAttributes{Name: a.Name(), SkipData: proptools.BoolPtr(true)}, appAttrs
+ }
+
+ // Optimization is..
+ // - enabled by default for android_app, android_test_helper_app
+ // - disabled by default for android_test
+ //
+ // TODO(b/192032291): Disable android_test_helper_app optimization by
+ // default after auditing downstream usage.
+ if a.dexProperties.Optimize.EnabledByDefault != a.dexer.effectiveOptimizeEnabled() {
+ // Property is explicitly defined by default from default, so emit the Bazel attribute.
+ appAttrs.Optimize = proptools.BoolPtr(a.dexer.effectiveOptimizeEnabled())
+ }
+
+ if a.dexer.effectiveOptimizeEnabled() {
handCraftedFlags := ""
if Bool(a.dexProperties.Optimize.Ignore_warnings) {
handCraftedFlags += "-ignorewarning "
@@ -1775,11 +1791,18 @@
// ConvertWithBp2build is used to convert android_app to Bazel.
func (a *AndroidApp) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
if ok, commonAttrs, appAttrs := convertWithBp2build(ctx, a); ok {
- props := bazel.BazelTargetModuleProperties{
- Rule_class: "android_binary",
- Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
+ var props bazel.BazelTargetModuleProperties
+ if ctx.ModuleName() == "framework-res" {
+ props = bazel.BazelTargetModuleProperties{
+ Rule_class: "framework_resources",
+ Bzl_load_location: "//build/bazel/rules/android:framework_resources.bzl",
+ }
+ } else {
+ props = bazel.BazelTargetModuleProperties{
+ Rule_class: "android_binary",
+ Bzl_load_location: "//build/bazel/rules/android:android_binary.bzl",
+ }
}
-
ctx.CreateBazelTargetModule(props, commonAttrs, appAttrs)
}
@@ -1803,13 +1826,12 @@
// an android_test_helper_app is an android_binary with testonly = True
commonAttrs.Testonly = proptools.BoolPtr(true)
- // additionally, it sets default values differently to android_app,
+ // android_test_helper_app sets default values differently to android_app,
// https://cs.android.com/android/platform/superproject/main/+/main:build/soong/java/app.go;l=1273-1279;drc=e12c083198403ec694af6c625aed11327eb2bf7f
//
// installable: true (settable prop)
// use_embedded_native_libs: true (settable prop)
// lint.test: true (settable prop)
- // optimize EnabledByDefault: true (blueprint mutated prop)
// AlwaysPackageNativeLibs: true (blueprint mutated prop)
// dexpreopt isTest: true (not prop)
diff --git a/java/base.go b/java/base.go
index a110aff..c685fba 100644
--- a/java/base.go
+++ b/java/base.go
@@ -432,6 +432,9 @@
srcJarArgs []string
srcJarDeps android.Paths
+ // the source files of this module and all its static dependencies
+ transitiveSrcFiles *android.DepSet[android.Path]
+
// jar file containing implementation classes and resources including static library
// dependencies
implementationAndResourcesJar android.Path
@@ -638,6 +641,11 @@
return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
case ".generated_srcjars":
return j.properties.Generated_srcjars, nil
+ case ".lint":
+ if j.linter.outputs.xml != nil {
+ return android.Paths{j.linter.outputs.xml}, nil
+ }
+ return nil, fmt.Errorf("%q was requested, but no output file was found.", tag)
default:
return nil, fmt.Errorf("unsupported module reference tag %q", tag)
}
@@ -711,6 +719,10 @@
return j.SdkVersion(ctx).ApiLevel
}
+func (j *Module) GetDeviceProperties() *DeviceProperties {
+ return &j.deviceProperties
+}
+
func (j *Module) MaxSdkVersion(ctx android.EarlyModuleContext) android.ApiLevel {
if j.deviceProperties.Max_sdk_version != nil {
return android.ApiLevelFrom(ctx, *j.deviceProperties.Max_sdk_version)
@@ -1343,10 +1355,17 @@
jars = append(jars, classes)
}
}
+ // Assume approximately 5 sources per srcjar.
+ // For framework-minus-apex in AOSP at the time this was written, there are 266 srcjars, with a mean
+ // of 5.8 sources per srcjar, but a median of 1, a standard deviation of 10, and a max of 48 source files.
if len(srcJars) > 0 {
- classes := j.compileJavaClasses(ctx, jarName, len(shardSrcs),
- nil, srcJars, flags, extraJarDeps)
- jars = append(jars, classes)
+ startIdx := len(shardSrcs)
+ shardSrcJarsList := android.ShardPaths(srcJars, shardSize/5)
+ for idx, shardSrcJars := range shardSrcJarsList {
+ classes := j.compileJavaClasses(ctx, jarName, startIdx+idx,
+ nil, shardSrcJars, flags, extraJarDeps)
+ jars = append(jars, classes)
+ }
}
} else {
classes := j.compileJavaClasses(ctx, jarName, -1, uniqueJavaFiles, srcJars, flags, extraJarDeps)
@@ -1687,6 +1706,8 @@
j.linter.lint(ctx)
}
+ j.collectTransitiveSrcFiles(ctx, srcFiles)
+
ctx.CheckbuildFile(outputFile)
j.collectTransitiveAconfigFiles(ctx)
@@ -1701,6 +1722,7 @@
AidlIncludeDirs: j.exportAidlIncludeDirs,
SrcJarArgs: j.srcJarArgs,
SrcJarDeps: j.srcJarDeps,
+ TransitiveSrcFiles: j.transitiveSrcFiles,
ExportedPlugins: j.exportedPluginJars,
ExportedPluginClasses: j.exportedPluginClasses,
ExportedPluginDisableTurbine: j.exportedDisableTurbine,
@@ -2025,6 +2047,21 @@
return j.jacocoReportClassesFile
}
+func (j *Module) collectTransitiveSrcFiles(ctx android.ModuleContext, mine android.Paths) {
+ var fromDeps []*android.DepSet[android.Path]
+ ctx.VisitDirectDeps(func(module android.Module) {
+ tag := ctx.OtherModuleDependencyTag(module)
+ if tag == staticLibTag {
+ depInfo := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ if depInfo.TransitiveSrcFiles != nil {
+ fromDeps = append(fromDeps, depInfo.TransitiveSrcFiles)
+ }
+ }
+ })
+
+ j.transitiveSrcFiles = android.NewDepSet(android.POSTORDER, mine, fromDeps)
+}
+
func (j *Module) IsInstallable() bool {
return Bool(j.properties.Installable)
}
diff --git a/java/config/kotlin.go b/java/config/kotlin.go
index fc63f4d..e5e187c 100644
--- a/java/config/kotlin.go
+++ b/java/config/kotlin.go
@@ -49,8 +49,5 @@
"-J--add-opens=java.base/java.util=ALL-UNNAMED", // https://youtrack.jetbrains.com/issue/KT-43704
}, " "))
- pctx.StaticVariable("KotlincGlobalFlags", strings.Join([]string{
- // b/222162908: prevent kotlinc from reading /tmp/build.txt
- "-Didea.plugins.compatible.build=999.SNAPSHOT",
- }, " "))
+ pctx.StaticVariable("KotlincGlobalFlags", strings.Join([]string{}, " "))
}
diff --git a/java/dex.go b/java/dex.go
index c1d51c7..348c939 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -110,7 +110,8 @@
`${config.Zip2ZipCmd} -i $in -o $tmpJar -x '**/*.dex' && ` +
`$d8Template${config.D8Cmd} ${config.D8Flags} --output $outDir $d8Flags $tmpJar && ` +
`$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
- `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in`,
+ `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` +
+ `rm -f "$tmpJar" "$outDir/classes*.dex" "$outDir/classes.dex.jar"`,
CommandDeps: []string{
"${config.D8Cmd}",
"${config.Zip2ZipCmd}",
@@ -139,9 +140,7 @@
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` +
`mkdir -p $$(dirname ${outUsage}) && ` +
- `mkdir -p $$(dirname $tmpJar) && ` +
- `${config.Zip2ZipCmd} -i $in -o $tmpJar -x '**/*.dex' && ` +
- `$r8Template${config.R8Cmd} ${config.R8Flags} -injars $tmpJar --output $outDir ` +
+ `$r8Template${config.R8Cmd} ${config.R8Flags} -injars $in --output $outDir ` +
`--no-data-resources ` +
`-printmapping ${outDict} ` +
`-printconfiguration ${outConfig} ` +
@@ -152,7 +151,8 @@
`${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` +
`rm -rf ${outUsageDir} && ` +
`$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
- `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in`,
+ `${config.MergeZipsCmd} -D -stripFile "**/*.class" $mergeZipsFlags $out $outDir/classes.dex.jar $in && ` +
+ `rm -f "$outDir/classes*.dex" "$outDir/classes.dex.jar"`,
Depfile: "${out}.d",
Deps: blueprint.DepsGCC,
CommandDeps: []string{
@@ -185,7 +185,7 @@
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
},
}, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir",
- "r8Flags", "zipFlags", "tmpJar", "mergeZipsFlags"}, []string{"implicits"})
+ "r8Flags", "zipFlags", "mergeZipsFlags"}, []string{"implicits"})
func (d *dexer) dexCommonFlags(ctx android.ModuleContext,
dexParams *compileDexParams) (flags []string, deps android.Paths) {
@@ -368,7 +368,6 @@
// Compile classes.jar into classes.dex and then javalib.jar
javalibJar := android.PathForModuleOut(ctx, "dex", dexParams.jarName).OutputPath
outDir := android.PathForModuleOut(ctx, "dex")
- tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", dexParams.jarName)
zipFlags := "--ignore_missing_files"
if proptools.Bool(d.dexProperties.Uncompress_dex) {
@@ -406,7 +405,6 @@
"outUsage": proguardUsage.String(),
"outUsageZip": proguardUsageZip.String(),
"outDir": outDir.String(),
- "tmpJar": tmpJar.String(),
"mergeZipsFlags": mergeZipsFlags,
}
if ctx.Config().UseRBE() && ctx.Config().IsEnvTrue("RBE_R8") {
@@ -426,6 +424,7 @@
Args: args,
})
} else {
+ tmpJar := android.PathForModuleOut(ctx, "withres-withoutdex", dexParams.jarName)
d8Flags, d8Deps := d8Flags(dexParams.flags)
d8Deps = append(d8Deps, commonDeps...)
rule := d8
diff --git a/java/droiddoc.go b/java/droiddoc.go
index d5547d0..87588f3 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -136,6 +136,9 @@
// At some point, this might be improved to show more warnings.
Todo_file *string `android:"path"`
+ // A file containing a baseline for allowed lint errors.
+ Lint_baseline *string `android:"path"`
+
// directory under current module source that provide additional resources (images).
Resourcesdir *string
@@ -665,6 +668,10 @@
ImplicitOutput(android.PathForModuleOut(ctx, String(d.properties.Todo_file)))
}
+ if String(d.properties.Lint_baseline) != "" {
+ cmd.FlagWithInput("-lintbaseline ", android.PathForModuleSrc(ctx, String(d.properties.Lint_baseline)))
+ }
+
if String(d.properties.Resourcesdir) != "" {
// TODO: should we add files under resourcesDir to the implicits? It seems that
// resourcesDir is one sub dir of htmlDir
diff --git a/java/droidstubs.go b/java/droidstubs.go
index 67a55bd..b059c0a 100644
--- a/java/droidstubs.go
+++ b/java/droidstubs.go
@@ -540,6 +540,10 @@
// See b/285312164 for more information.
cmd.FlagWithArg("--format-defaults ", "overloaded-method-order=source")
+ if ctx.DeviceConfig().HideFlaggedApis() {
+ cmd.FlagWithArg("--hide-annotation ", "android.annotation.FlaggedApi")
+ }
+
return cmd
}
diff --git a/java/droidstubs_test.go b/java/droidstubs_test.go
index 7a04d73..e149b98 100644
--- a/java/droidstubs_test.go
+++ b/java/droidstubs_test.go
@@ -22,6 +22,8 @@
"testing"
"android/soong/android"
+
+ "github.com/google/blueprint/proptools"
)
func TestDroidstubs(t *testing.T) {
@@ -403,3 +405,35 @@
ctx.ModuleForTests("bar", "android_common")
}
+
+func TestDroidstubsHideFlaggedApi(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.NextReleaseHideFlaggedApi = proptools.BoolPtr(true)
+ variables.Release_expose_flagged_api = proptools.BoolPtr(false)
+ }),
+ android.FixtureMergeMockFs(map[string][]byte{
+ "a/A.java": nil,
+ "a/current.txt": nil,
+ "a/removed.txt": nil,
+ }),
+ ).RunTestWithBp(t, `
+ droidstubs {
+ name: "foo",
+ srcs: ["a/A.java"],
+ api_surface: "public",
+ check_api: {
+ current: {
+ api_file: "a/current.txt",
+ removed_api_file: "a/removed.txt",
+ }
+ },
+ }
+ `)
+
+ m := result.ModuleForTests("foo", "android_common")
+ manifest := m.Output("metalava.sbox.textproto")
+ cmdline := String(android.RuleBuilderSboxProtoForTests(t, manifest).Commands[0].Command)
+ android.AssertStringDoesContain(t, "flagged api hide command not included", cmdline, "--hide-annotation android.annotation.FlaggedApi")
+}
diff --git a/java/generated_java_library.go b/java/generated_java_library.go
index 578237e..930bfd2 100644
--- a/java/generated_java_library.go
+++ b/java/generated_java_library.go
@@ -35,6 +35,8 @@
// Called from inside GenerateAndroidBuildActions. Add the build rules to
// make the srcjar, and return the path to it.
GenerateSourceJarBuildActions(module *GeneratedJavaLibraryModule, ctx android.ModuleContext) android.Path
+
+ Bp2build(ctx android.Bp2buildMutatorContext, module *GeneratedJavaLibraryModule)
}
// GeneratedJavaLibraryModuleFactory provides a utility for modules that are generated
@@ -108,3 +110,7 @@
module.Library.properties.Generated_srcjars = append(module.Library.properties.Generated_srcjars, srcJarPath)
module.Library.GenerateAndroidBuildActions(ctx)
}
+
+func (module *GeneratedJavaLibraryModule) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
+ module.callbacks.Bp2build(ctx, module)
+}
diff --git a/java/generated_java_library_test.go b/java/generated_java_library_test.go
index 7f52fd1..7fbbfee 100644
--- a/java/generated_java_library_test.go
+++ b/java/generated_java_library_test.go
@@ -41,6 +41,9 @@
return android.PathForOutput(ctx, "blah.srcjar")
}
+func (callbacks *JavaGenLibTestCallbacks) Bp2build(ctx android.Bp2buildMutatorContext, module *GeneratedJavaLibraryModule) {
+}
+
func testGenLib(t *testing.T, errorHandler android.FixtureErrorHandler, bp string) *android.TestResult {
return android.GroupFixturePreparers(
PrepareForIntegrationTestWithJava,
diff --git a/java/java.go b/java/java.go
index fbad4f3..cac49a2 100644
--- a/java/java.go
+++ b/java/java.go
@@ -278,6 +278,9 @@
// SrcJarDeps is a list of paths to depend on when packaging the sources of this module.
SrcJarDeps android.Paths
+ // The source files of this module and all its transitive static dependencies.
+ TransitiveSrcFiles *android.DepSet[android.Path]
+
// ExportedPlugins is a list of paths that should be used as annotation processors for any
// module that depends on this module.
ExportedPlugins android.Paths
@@ -1667,11 +1670,6 @@
// This is a list of Soong modules
Api_contributions []string
- // list of api.txt files relative to this directory that contribute to the
- // API surface.
- // This is a list of relative paths
- Api_files []string `android:"path"`
-
// List of flags to be passed to the javac compiler to generate jar file
Javacflags []string
@@ -1819,37 +1817,22 @@
}
}
-// API signature file names sorted from
-// the narrowest api scope to the widest api scope
-var scopeOrderedSourceFileNames = allApiScopes.Strings(
- func(s *apiScope) string { return s.apiFilePrefix + "current.txt" })
+// Map where key is the api scope name and value is the int value
+// representing the order of the api scope, narrowest to the widest
+var scopeOrderMap = allApiScopes.MapToIndex(
+ func(s *apiScope) string { return s.name })
-func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo, apiFiles android.Paths) android.Paths {
- var sortedSrcFiles android.Paths
-
- for i, apiScope := range allApiScopes {
- for _, srcFileInfo := range srcFilesInfo {
- if srcFileInfo.ApiFile.Base() == scopeOrderedSourceFileNames[i] || srcFileInfo.ApiSurface == apiScope.name {
- sortedSrcFiles = append(sortedSrcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String()))
- }
- }
- // TODO: b/300964421 - Remove when api_files property is removed
- for _, apiFileName := range apiFiles {
- if apiFileName.Base() == scopeOrderedSourceFileNames[i] {
- sortedSrcFiles = append(sortedSrcFiles, apiFileName)
- }
+func (al *ApiLibrary) sortApiFilesByApiScope(ctx android.ModuleContext, srcFilesInfo []JavaApiImportInfo) []JavaApiImportInfo {
+ for _, srcFileInfo := range srcFilesInfo {
+ if srcFileInfo.ApiSurface == "" {
+ ctx.ModuleErrorf("Api surface not defined for the associated api file %s", srcFileInfo.ApiFile)
}
}
+ sort.Slice(srcFilesInfo, func(i, j int) bool {
+ return scopeOrderMap[srcFilesInfo[i].ApiSurface] < scopeOrderMap[srcFilesInfo[j].ApiSurface]
+ })
- if len(srcFilesInfo)+len(apiFiles) != len(sortedSrcFiles) {
- var srcFiles android.Paths
- for _, srcFileInfo := range srcFilesInfo {
- srcFiles = append(srcFiles, srcFileInfo.ApiFile)
- }
- ctx.ModuleErrorf("Unrecognizable source file found within %s", append(srcFiles, apiFiles...))
- }
-
- return sortedSrcFiles
+ return srcFilesInfo
}
func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
@@ -1892,16 +1875,12 @@
}
})
- // Add the api_files inputs
- // These are api files in the module subdirectory, which are not provided by
- // java_api_contribution but provided directly as module property.
- var apiFiles android.Paths
- for _, api := range al.properties.Api_files {
- apiFiles = append(apiFiles, android.PathForModuleSrc(ctx, api))
+ srcFilesInfo = al.sortApiFilesByApiScope(ctx, srcFilesInfo)
+ var srcFiles android.Paths
+ for _, srcFileInfo := range srcFilesInfo {
+ srcFiles = append(srcFiles, android.PathForSource(ctx, srcFileInfo.ApiFile.String()))
}
- srcFiles := al.sortApiFilesByApiScope(ctx, srcFilesInfo, apiFiles)
-
if srcFiles == nil && !ctx.Config().AllowMissingDependencies() {
ctx.ModuleErrorf("Error: %s has an empty api file.", ctx.ModuleName())
}
diff --git a/java/java_test.go b/java/java_test.go
index 2ee05ec..d51604a 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1885,7 +1885,6 @@
name: "bar2",
api_surface: "system",
api_contributions: ["foo1", "foo2"],
- api_files: ["api1/current.txt", "api2/current.txt"]
}
`,
map[string][]byte{
@@ -1903,7 +1902,7 @@
},
{
moduleName: "bar2",
- sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "api1/current.txt", "api2/current.txt"},
+ sourceTextFileDirs: []string{"a/current.txt", "b/current.txt"},
},
}
for _, c := range testcases {
@@ -1975,7 +1974,6 @@
api_surface: "system",
defaults:["baz1", "baz2"],
api_contributions: ["foo4"],
- api_files: ["api1/current.txt", "api2/current.txt"]
}
`,
map[string][]byte{
@@ -2000,7 +1998,7 @@
{
moduleName: "bar3",
// API text files need to be sorted from the narrower api scope to the wider api scope
- sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "api1/current.txt", "api2/current.txt", "c/system-current.txt", "d/system-current.txt"},
+ sourceTextFileDirs: []string{"a/current.txt", "b/current.txt", "c/system-current.txt", "d/system-current.txt"},
},
}
for _, c := range testcases {
@@ -2265,27 +2263,26 @@
android.AssertStringDoesContain(t, "Command expected to contain full_api_surface_stub output jar", manifestCommand, "lib1.jar")
}
-func TestJavaApiLibraryFilegroupInput(t *testing.T) {
- ctx, _ := testJavaWithFS(t, `
- filegroup {
- name: "default_current.txt",
- srcs: ["current.txt"],
+func TestTransitiveSrcFiles(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_library {
+ name: "a",
+ srcs: ["a.java"],
}
-
- java_api_library {
- name: "foo",
- api_files: [":default_current.txt"],
+ java_library {
+ name: "b",
+ srcs: ["b.java"],
}
- `,
- map[string][]byte{
- "current.txt": nil,
- })
-
- m := ctx.ModuleForTests("foo", "android_common")
- outputs := fmt.Sprint(m.AllOutputs())
- if !strings.Contains(outputs, "foo/foo.jar") {
- t.Errorf("Module output does not contain expected jar %s", "foo/foo.jar")
- }
+ java_library {
+ name: "c",
+ srcs: ["c.java"],
+ libs: ["a"],
+ static_libs: ["b"],
+ }
+ `)
+ c := ctx.ModuleForTests("c", "android_common").Module()
+ transitiveSrcFiles := android.Paths(ctx.ModuleProvider(c, JavaInfoProvider).(JavaInfo).TransitiveSrcFiles.ToList())
+ android.AssertArrayString(t, "unexpected jar deps", []string{"b.java", "c.java"}, transitiveSrcFiles.Strings())
}
func TestTradefedOptions(t *testing.T) {
@@ -2423,3 +2420,30 @@
sourceFilesFlag := "--source-files current.txt"
android.AssertStringDoesContain(t, "source text files not present", manifestCommand, sourceFilesFlag)
}
+
+func TestJavaApiLibraryApiFilesSorting(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_api_library {
+ name: "foo",
+ api_contributions: [
+ "system-server-api-stubs-docs-non-updatable.api.contribution",
+ "test-api-stubs-docs-non-updatable.api.contribution",
+ "system-api-stubs-docs-non-updatable.api.contribution",
+ "module-lib-api-stubs-docs-non-updatable.api.contribution",
+ "api-stubs-docs-non-updatable.api.contribution",
+ ],
+ }
+ `)
+ m := ctx.ModuleForTests("foo", "android_common")
+ manifest := m.Output("metalava.sbox.textproto")
+ sboxProto := android.RuleBuilderSboxProtoForTests(t, manifest)
+ manifestCommand := sboxProto.Commands[0].GetCommand()
+
+ // Api files are sorted from the narrowest api scope to the widest api scope.
+ // test api and module lib api surface do not have subset/superset relationship,
+ // but they will never be passed as inputs at the same time.
+ sourceFilesFlag := "--source-files default/java/api/current.txt " +
+ "default/java/api/system-current.txt default/java/api/test-current.txt " +
+ "default/java/api/module-lib-current.txt default/java/api/system-server-current.txt"
+ android.AssertStringDoesContain(t, "source text files not in api scope order", manifestCommand, sourceFilesFlag)
+}
diff --git a/java/lint.go b/java/lint.go
index f84f1c0..34720e5 100644
--- a/java/lint.go
+++ b/java/lint.go
@@ -66,6 +66,10 @@
// This will be true by default for test module types, false otherwise.
// If soong gets support for testonly, this flag should be replaced with that.
Test *bool
+
+ // Whether to ignore the exit code of Android lint. This is the --exit_code
+ // option. Defaults to false.
+ Suppress_exit_code *bool
}
}
@@ -504,7 +508,8 @@
rule.Temporary(lintPaths.projectXML)
rule.Temporary(lintPaths.configXML)
- if exitCode := ctx.Config().Getenv("ANDROID_LINT_SUPPRESS_EXIT_CODE"); exitCode == "" {
+ suppressExitCode := BoolDefault(l.properties.Lint.Suppress_exit_code, false)
+ if exitCode := ctx.Config().Getenv("ANDROID_LINT_SUPPRESS_EXIT_CODE"); exitCode == "" && !suppressExitCode {
cmd.Flag("--exitcode")
}
diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go
index ade7395..02a2298 100644
--- a/java/platform_bootclasspath.go
+++ b/java/platform_bootclasspath.go
@@ -57,6 +57,9 @@
// Path to the monolithic hiddenapi-unsupported.csv file.
hiddenAPIMetadataCSV android.OutputPath
+
+ // Path to a srcjar containing all the transitive sources of the bootclasspath.
+ srcjar android.OutputPath
}
type platformBootclasspathProperties struct {
@@ -95,6 +98,8 @@
return android.Paths{b.hiddenAPIIndexCSV}, nil
case "hiddenapi-metadata.csv":
return android.Paths{b.hiddenAPIMetadataCSV}, nil
+ case ".srcjar":
+ return android.Paths{b.srcjar}, nil
}
return nil, fmt.Errorf("unknown tag %s", tag)
@@ -173,6 +178,18 @@
allModules = append(allModules, apexModules...)
b.configuredModules = allModules
+ var transitiveSrcFiles android.Paths
+ for _, module := range allModules {
+ depInfo := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo)
+ if depInfo.TransitiveSrcFiles != nil {
+ transitiveSrcFiles = append(transitiveSrcFiles, depInfo.TransitiveSrcFiles.ToList()...)
+ }
+ }
+ jarArgs := resourcePathsToJarArgs(transitiveSrcFiles)
+ jarArgs = append(jarArgs, "-srcjar") // Move srcfiles to the right package
+ b.srcjar = android.PathForModuleOut(ctx, ctx.ModuleName()+"-transitive.srcjar").OutputPath
+ TransformResourcesToJar(ctx, b.srcjar, jarArgs, transitiveSrcFiles)
+
// Gather all the fragments dependencies.
b.fragments = gatherApexModulePairDepsWithTag(ctx, bootclasspathFragmentDepTag)
diff --git a/java/platform_bootclasspath_test.go b/java/platform_bootclasspath_test.go
index ff2da4b..37ff639 100644
--- a/java/platform_bootclasspath_test.go
+++ b/java/platform_bootclasspath_test.go
@@ -81,6 +81,15 @@
RunTest(t)
})
+ fooSourceSrc := "source/a.java"
+ barSrc := "a.java"
+
+ checkSrcJarInputs := func(t *testing.T, result *android.TestResult, name string, expected []string) {
+ t.Helper()
+ srcjar := result.ModuleForTests(name, "android_common").Output(name + "-transitive.srcjar")
+ android.AssertStringDoesContain(t, "srcjar arg", srcjar.Args["jarArgs"], "-srcjar")
+ android.AssertArrayString(t, "srcjar inputs", expected, srcjar.Implicits.Strings())
+ }
t.Run("source", func(t *testing.T) {
result := android.GroupFixturePreparers(
preparer,
@@ -91,6 +100,10 @@
"platform:foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ fooSourceSrc,
+ barSrc,
+ })
})
t.Run("prebuilt", func(t *testing.T) {
@@ -103,6 +116,10 @@
"platform:prebuilt_foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ // TODO(b/151360309): This should also have the srcs for prebuilt_foo
+ barSrc,
+ })
})
t.Run("source+prebuilt - source preferred", func(t *testing.T) {
@@ -116,6 +133,10 @@
"platform:foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ fooSourceSrc,
+ barSrc,
+ })
})
t.Run("source+prebuilt - prebuilt preferred", func(t *testing.T) {
@@ -129,6 +150,10 @@
"platform:prebuilt_foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ // TODO(b/151360309): This should also have the srcs for prebuilt_foo
+ barSrc,
+ })
})
t.Run("dex import", func(t *testing.T) {
@@ -146,6 +171,10 @@
"platform:prebuilt_foo",
"platform:bar",
})
+ checkSrcJarInputs(t, result, "platform-bootclasspath", []string{
+ // TODO(b/151360309): This should also have the srcs for prebuilt_foo
+ barSrc,
+ })
})
}
diff --git a/java/proto.go b/java/proto.go
index 48adadc..c88d3d7 100644
--- a/java/proto.go
+++ b/java/proto.go
@@ -159,6 +159,8 @@
Sdk_version bazel.StringAttribute
Java_version bazel.StringAttribute
+
+ Plugin bazel.LabelAttribute
}
func bp2buildProto(ctx android.Bp2buildMutatorContext, m *Module, protoSrcs bazel.LabelListAttribute, AdditionalProtoDeps bazel.LabelListAttribute) *bazel.Label {
@@ -189,12 +191,18 @@
ctx.PropertyErrorf("proto.type", "cannot handle conversion at this time: %q", typ)
}
+ plugin := bazel.LabelAttribute{}
+ if m.protoProperties.Proto.Plugin != nil {
+ plugin.SetValue(android.BazelLabelForModuleDepSingle(ctx, "protoc-gen-"+*m.protoProperties.Proto.Plugin))
+ }
+
protoAttrs := &protoAttributes{
Deps: bazel.MakeLabelListAttribute(protoInfo.Proto_libs),
Transitive_deps: bazel.MakeLabelListAttribute(protoInfo.Transitive_proto_libs),
Additional_proto_deps: AdditionalProtoDeps,
Java_version: bazel.StringAttribute{Value: m.properties.Java_version},
Sdk_version: bazel.StringAttribute{Value: m.deviceProperties.Sdk_version},
+ Plugin: plugin,
}
name := m.Name() + suffix
diff --git a/java/sdk_library.go b/java/sdk_library.go
index 27f8626..e410a41 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -286,6 +286,17 @@
return list
}
+// Method that maps the apiScopes properties to the index of each apiScopes elements.
+// apiScopes property to be used as the key can be specified with the input accessor.
+// Only a string property of apiScope can be used as the key of the map.
+func (scopes apiScopes) MapToIndex(accessor func(*apiScope) string) map[string]int {
+ ret := make(map[string]int)
+ for i, scope := range scopes {
+ ret[accessor(scope)] = i
+ }
+ return ret
+}
+
var (
scopeByName = make(map[string]*apiScope)
allScopeNames []string
diff --git a/java/testing.go b/java/testing.go
index f2bcccf..98bea7f 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -424,30 +424,80 @@
`, extra)
}
- extraApiLibraryModules := map[string]string{
- "android_stubs_current.from-text": "api/current.txt",
- "android_system_stubs_current.from-text": "api/system-current.txt",
- "android_test_stubs_current.from-text": "api/test-current.txt",
- "android_module_lib_stubs_current.from-text": "api/module-lib-current.txt",
- "android_module_lib_stubs_current_full.from-text": "api/module-lib-current.txt",
- "android_system_server_stubs_current.from-text": "api/system-server-current.txt",
- "core.current.stubs.from-text": "api/current.txt",
- "legacy.core.platform.api.stubs.from-text": "api/current.txt",
- "stable.core.platform.api.stubs.from-text": "api/current.txt",
- "core-lambda-stubs.from-text": "api/current.txt",
- "android-non-updatable.stubs.from-text": "api/current.txt",
- "android-non-updatable.stubs.system.from-text": "api/system-current.txt",
- "android-non-updatable.stubs.test.from-text": "api/test-current.txt",
- "android-non-updatable.stubs.module_lib.from-text": "api/module-lib-current.txt",
+ type apiContributionStruct struct {
+ name string
+ apiSurface string
+ apiFile string
}
- for libName, apiFile := range extraApiLibraryModules {
+ var publicApiContribution = apiContributionStruct{
+ name: "api-stubs-docs-non-updatable.api.contribution",
+ apiSurface: "public",
+ apiFile: "api/current.txt",
+ }
+ var systemApiContribution = apiContributionStruct{
+ name: "system-api-stubs-docs-non-updatable.api.contribution",
+ apiSurface: "system",
+ apiFile: "api/system-current.txt",
+ }
+ var testApiContribution = apiContributionStruct{
+ name: "test-api-stubs-docs-non-updatable.api.contribution",
+ apiSurface: "test",
+ apiFile: "api/test-current.txt",
+ }
+ var moduleLibApiContribution = apiContributionStruct{
+ name: "module-lib-api-stubs-docs-non-updatable.api.contribution",
+ apiSurface: "module-lib",
+ apiFile: "api/module-lib-current.txt",
+ }
+ var systemServerApiContribution = apiContributionStruct{
+ // This module does not exist but is named this way for consistency
+ name: "system-server-api-stubs-docs-non-updatable.api.contribution",
+ apiSurface: "system-server",
+ apiFile: "api/system-server-current.txt",
+ }
+ var apiContributionStructs = []apiContributionStruct{
+ publicApiContribution,
+ systemApiContribution,
+ testApiContribution,
+ moduleLibApiContribution,
+ systemServerApiContribution,
+ }
+
+ extraApiLibraryModules := map[string]apiContributionStruct{
+ "android_stubs_current.from-text": publicApiContribution,
+ "android_system_stubs_current.from-text": systemApiContribution,
+ "android_test_stubs_current.from-text": testApiContribution,
+ "android_module_lib_stubs_current.from-text": moduleLibApiContribution,
+ "android_module_lib_stubs_current_full.from-text": moduleLibApiContribution,
+ "android_system_server_stubs_current.from-text": systemServerApiContribution,
+ "core.current.stubs.from-text": publicApiContribution,
+ "legacy.core.platform.api.stubs.from-text": publicApiContribution,
+ "stable.core.platform.api.stubs.from-text": publicApiContribution,
+ "core-lambda-stubs.from-text": publicApiContribution,
+ "android-non-updatable.stubs.from-text": publicApiContribution,
+ "android-non-updatable.stubs.system.from-text": systemApiContribution,
+ "android-non-updatable.stubs.test.from-text": testApiContribution,
+ "android-non-updatable.stubs.module_lib.from-text": moduleLibApiContribution,
+ }
+
+ for _, apiContribution := range apiContributionStructs {
+ bp += fmt.Sprintf(`
+ java_api_contribution {
+ name: "%s",
+ api_surface: "%s",
+ api_file: "%s",
+ }
+ `, apiContribution.name, apiContribution.apiSurface, apiContribution.apiFile)
+ }
+
+ for libName, apiContribution := range extraApiLibraryModules {
bp += fmt.Sprintf(`
java_api_library {
name: "%s",
- api_files: ["%s"],
+ api_contributions: ["%s"],
}
- `, libName, apiFile)
+ `, libName, apiContribution.name)
}
bp += `
diff --git a/rust/binary.go b/rust/binary.go
index 1408ff1..860dc94 100644
--- a/rust/binary.go
+++ b/rust/binary.go
@@ -77,14 +77,11 @@
func (binary *binaryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags {
flags = binary.baseCompiler.compilerFlags(ctx, flags)
- if ctx.Os().Linux() {
- flags.LinkFlags = append(flags.LinkFlags, "-Wl,--gc-sections")
- }
-
if ctx.toolchain().Bionic() {
// no-undefined-version breaks dylib compilation since __rust_*alloc* functions aren't defined,
// but we can apply this to binaries.
flags.LinkFlags = append(flags.LinkFlags,
+ "-Wl,--gc-sections",
"-Wl,-z,nocopyreloc",
"-Wl,--no-undefined-version")
@@ -138,13 +135,18 @@
func (binary *binaryDecorator) compile(ctx ModuleContext, flags Flags, deps PathDeps) buildOutput {
fileName := binary.getStem(ctx) + ctx.toolchain().ExecutableSuffix()
- srcPath, _ := srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
outputFile := android.PathForModuleOut(ctx, fileName)
ret := buildOutput{outputFile: outputFile}
+ var crateRootPath android.Path
+ if binary.baseCompiler.Properties.Crate_root == nil {
+ crateRootPath, _ = srcPathFromModuleSrcs(ctx, binary.baseCompiler.Properties.Srcs)
+ } else {
+ crateRootPath = android.PathForModuleSrc(ctx, *binary.baseCompiler.Properties.Crate_root)
+ }
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
if binary.stripper.NeedsStrip(ctx) {
strippedOutputFile := outputFile
@@ -155,7 +157,7 @@
}
binary.baseCompiler.unstrippedOutputFile = outputFile
- ret.kytheFile = TransformSrcToBinary(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrcToBinary(ctx, crateRootPath, deps, flags, outputFile).kytheFile
return ret
}
diff --git a/rust/binary_test.go b/rust/binary_test.go
index dff94ac..ef93037 100644
--- a/rust/binary_test.go
+++ b/rust/binary_test.go
@@ -150,7 +150,7 @@
bootstrap: true,
}`)
- foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustLink")
+ foo := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Rule("rustc")
flag := "-Wl,-dynamic-linker,/system/bin/bootstrap/linker64"
if !strings.Contains(foo.Args["linkFlags"], flag) {
@@ -167,11 +167,10 @@
}`)
fizzOut := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustc")
- fizzOutLink := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Rule("rustLink")
fizzMod := ctx.ModuleForTests("fizz", "android_arm64_armv8-a").Module().(*Module)
flags := fizzOut.Args["rustcFlags"]
- linkFlags := fizzOutLink.Args["linkFlags"]
+ linkFlags := fizzOut.Args["linkFlags"]
if !strings.Contains(flags, "-C relocation-model=static") {
t.Errorf("static binary missing '-C relocation-model=static' in rustcFlags, found: %#v", flags)
}
@@ -201,7 +200,7 @@
name: "libfoo",
}`)
- fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustLink")
+ fizzBuzz := ctx.ModuleForTests("fizz-buzz", "android_arm64_armv8-a").Rule("rustc")
linkFlags := fizzBuzz.Args["linkFlags"]
if !strings.Contains(linkFlags, "/libfoo.so") {
t.Errorf("missing shared dependency 'libfoo.so' in linkFlags: %#v", linkFlags)
diff --git a/rust/builder.go b/rust/builder.go
index b1f049d..bea8ff7 100644
--- a/rust/builder.go
+++ b/rust/builder.go
@@ -26,14 +26,14 @@
var (
_ = pctx.SourcePathVariable("rustcCmd", "${config.RustBin}/rustc")
- _ = pctx.SourcePathVariable("mkcraterspCmd", "build/soong/scripts/mkcratersp.py")
rustc = pctx.AndroidStaticRule("rustc",
blueprint.RuleParams{
Command: "$envVars $rustcCmd " +
- "-C linker=$mkcraterspCmd " +
+ "-C linker=${config.RustLinker} " +
+ "-C link-args=\"${crtBegin} ${earlyLinkFlags} ${linkFlags} ${crtEnd}\" " +
"--emit link -o $out --emit dep-info=$out.d.raw $in ${libFlags} $rustcFlags" +
" && grep \"^$out:\" $out.d.raw > $out.d",
- CommandDeps: []string{"$rustcCmd", "$mkcraterspCmd"},
+ CommandDeps: []string{"$rustcCmd"},
// Rustc deps-info writes out make compatible dep files: https://github.com/rust-lang/rust/issues/7633
// Rustc emits unneeded dependency lines for the .d and input .rs files.
// Those extra lines cause ninja warning:
@@ -42,12 +42,7 @@
Deps: blueprint.DepsGCC,
Depfile: "$out.d",
},
- "rustcFlags", "libFlags", "envVars")
- rustLink = pctx.AndroidStaticRule("rustLink",
- blueprint.RuleParams{
- Command: "${config.RustLinker} -o $out ${crtBegin} ${earlyLinkFlags} @$in ${linkFlags} ${crtEnd}",
- },
- "earlyLinkFlags", "linkFlags", "crtBegin", "crtEnd")
+ "rustcFlags", "earlyLinkFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
_ = pctx.SourcePathVariable("rustdocCmd", "${config.RustBin}/rustdoc")
rustdoc = pctx.AndroidStaticRule("rustdoc",
@@ -106,13 +101,14 @@
`KYTHE_CANONICALIZE_VNAME_PATHS=prefer-relative ` +
`$rustExtractor $envVars ` +
`$rustcCmd ` +
- `-C linker=true ` +
+ `-C linker=${config.RustLinker} ` +
+ `-C link-args="${crtBegin} ${linkFlags} ${crtEnd}" ` +
`$in ${libFlags} $rustcFlags`,
CommandDeps: []string{"$rustExtractor", "$kytheVnames"},
Rspfile: "${out}.rsp",
RspfileContent: "$in",
},
- "rustcFlags", "libFlags", "envVars")
+ "rustcFlags", "linkFlags", "libFlags", "crtBegin", "crtEnd", "envVars")
)
type buildOutput struct {
@@ -242,12 +238,6 @@
}
}
- envVars = append(envVars, "AR=${cc_config.ClangBin}/llvm-ar")
-
- if ctx.Darwin() {
- envVars = append(envVars, "ANDROID_RUST_DARWIN=true")
- }
-
return envVars
}
@@ -255,7 +245,8 @@
outputFile android.WritablePath, crateType string) buildOutput {
var inputs android.Paths
- var implicits, linkImplicits, linkOrderOnly android.Paths
+ var implicits android.Paths
+ var orderOnly android.Paths
var output buildOutput
var rustcFlags, linkFlags []string
var earlyLinkFlags string
@@ -319,15 +310,15 @@
implicits = append(implicits, rustLibsToPaths(deps.RLibs)...)
implicits = append(implicits, rustLibsToPaths(deps.DyLibs)...)
implicits = append(implicits, rustLibsToPaths(deps.ProcMacros)...)
- implicits = append(implicits, deps.AfdoProfiles...)
+ implicits = append(implicits, deps.StaticLibs...)
+ implicits = append(implicits, deps.SharedLibDeps...)
implicits = append(implicits, deps.srcProviderFiles...)
- implicits = append(implicits, deps.WholeStaticLibs...)
+ implicits = append(implicits, deps.AfdoProfiles...)
- linkImplicits = append(linkImplicits, deps.LibDeps...)
- linkImplicits = append(linkImplicits, deps.CrtBegin...)
- linkImplicits = append(linkImplicits, deps.CrtEnd...)
+ implicits = append(implicits, deps.CrtBegin...)
+ implicits = append(implicits, deps.CrtEnd...)
- linkOrderOnly = append(linkOrderOnly, deps.linkObjects...)
+ orderOnly = append(orderOnly, deps.SharedLibs...)
if len(deps.SrcDeps) > 0 {
moduleGenDir := ctx.RustModule().compiler.CargoOutDir()
@@ -353,14 +344,29 @@
implicits = append(implicits, outputs.Paths()...)
}
+ envVars = append(envVars, "ANDROID_RUST_VERSION="+config.GetRustVersion(ctx))
+
+ if ctx.RustModule().compiler.CargoEnvCompat() {
+ if _, ok := ctx.RustModule().compiler.(*binaryDecorator); ok {
+ envVars = append(envVars, "CARGO_BIN_NAME="+strings.TrimSuffix(outputFile.Base(), outputFile.Ext()))
+ }
+ envVars = append(envVars, "CARGO_CRATE_NAME="+ctx.RustModule().CrateName())
+ pkgVersion := ctx.RustModule().compiler.CargoPkgVersion()
+ if pkgVersion != "" {
+ envVars = append(envVars, "CARGO_PKG_VERSION="+pkgVersion)
+ }
+ }
+
if flags.Clippy {
clippyFile := android.PathForModuleOut(ctx, outputFile.Base()+".clippy")
ctx.Build(pctx, android.BuildParams{
- Rule: clippyDriver,
- Description: "clippy " + main.Rel(),
- Output: clippyFile,
- Inputs: inputs,
- Implicits: implicits,
+ Rule: clippyDriver,
+ Description: "clippy " + main.Rel(),
+ Output: clippyFile,
+ ImplicitOutputs: nil,
+ Inputs: inputs,
+ Implicits: implicits,
+ OrderOnly: orderOnly,
Args: map[string]string{
"rustcFlags": strings.Join(rustcFlags, " "),
"libFlags": strings.Join(libFlags, " "),
@@ -372,42 +378,24 @@
implicits = append(implicits, clippyFile)
}
- rustcOutputFile := outputFile
- usesLinker := crateType == "bin" || crateType == "dylib" || crateType == "cdylib" || crateType == "proc-macro"
- if usesLinker {
- rustcOutputFile = android.PathForModuleOut(ctx, outputFile.Base()+".rsp")
- }
-
ctx.Build(pctx, android.BuildParams{
Rule: rustc,
Description: "rustc " + main.Rel(),
- Output: rustcOutputFile,
+ Output: outputFile,
Inputs: inputs,
Implicits: implicits,
+ OrderOnly: orderOnly,
Args: map[string]string{
- "rustcFlags": strings.Join(rustcFlags, " "),
- "libFlags": strings.Join(libFlags, " "),
- "envVars": strings.Join(envVars, " "),
+ "rustcFlags": strings.Join(rustcFlags, " "),
+ "earlyLinkFlags": earlyLinkFlags,
+ "linkFlags": strings.Join(linkFlags, " "),
+ "libFlags": strings.Join(libFlags, " "),
+ "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
+ "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
+ "envVars": strings.Join(envVars, " "),
},
})
- if usesLinker {
- ctx.Build(pctx, android.BuildParams{
- Rule: rustLink,
- Description: "rustLink " + main.Rel(),
- Output: outputFile,
- Inputs: android.Paths{rustcOutputFile},
- Implicits: linkImplicits,
- OrderOnly: linkOrderOnly,
- Args: map[string]string{
- "earlyLinkFlags": earlyLinkFlags,
- "linkFlags": strings.Join(linkFlags, " "),
- "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
- "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
- },
- })
- }
-
if flags.EmitXrefs {
kytheFile := android.PathForModuleOut(ctx, outputFile.Base()+".kzip")
ctx.Build(pctx, android.BuildParams{
@@ -416,9 +404,13 @@
Output: kytheFile,
Inputs: inputs,
Implicits: implicits,
+ OrderOnly: orderOnly,
Args: map[string]string{
"rustcFlags": strings.Join(rustcFlags, " "),
+ "linkFlags": strings.Join(linkFlags, " "),
"libFlags": strings.Join(libFlags, " "),
+ "crtBegin": strings.Join(deps.CrtBegin.Strings(), " "),
+ "crtEnd": strings.Join(deps.CrtEnd.Strings(), " "),
"envVars": strings.Join(envVars, " "),
},
})
diff --git a/rust/builder_test.go b/rust/builder_test.go
index 5c11cb7..639f6d4 100644
--- a/rust/builder_test.go
+++ b/rust/builder_test.go
@@ -14,7 +14,11 @@
package rust
-import "testing"
+import (
+ "android/soong/android"
+ "sort"
+ "testing"
+)
func TestSourceProviderCollision(t *testing.T) {
testRustError(t, "multiple source providers generate the same filename output: bindings.rs", `
@@ -40,3 +44,113 @@
}
`)
}
+
+func TestCompilationOutputFiles(t *testing.T) {
+ ctx := testRust(t, `
+ rust_library {
+ name: "libfizz_buzz",
+ crate_name:"fizz_buzz",
+ srcs: ["lib.rs"],
+ }
+ rust_binary {
+ name: "fizz_buzz",
+ crate_name:"fizz_buzz",
+ srcs: ["lib.rs"],
+ }
+ rust_ffi {
+ name: "librust_ffi",
+ crate_name: "rust_ffi",
+ srcs: ["lib.rs"],
+ }
+ `)
+ testcases := []struct {
+ testName string
+ moduleName string
+ variant string
+ expectedFiles []string
+ }{
+ {
+ testName: "dylib",
+ moduleName: "libfizz_buzz",
+ variant: "android_arm64_armv8-a_dylib",
+ expectedFiles: []string{
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/libfizz_buzz.dylib.so.clippy",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/unstripped/libfizz_buzz.dylib.so",
+ "out/soong/target/product/test_device/system/lib64/libfizz_buzz.dylib.so",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_dylib/meta_lic",
+ },
+ },
+ {
+ testName: "rlib dylib-std",
+ moduleName: "libfizz_buzz",
+ variant: "android_arm64_armv8-a_rlib_dylib-std",
+ expectedFiles: []string{
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/libfizz_buzz.rlib",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/libfizz_buzz.rlib.clippy",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_dylib-std/meta_lic",
+ },
+ },
+ {
+ testName: "rlib rlib-std",
+ moduleName: "libfizz_buzz",
+ variant: "android_arm64_armv8-a_rlib_rlib-std",
+ expectedFiles: []string{
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/libfizz_buzz.rlib",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/libfizz_buzz.rlib.clippy",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/meta_lic",
+ "out/soong/.intermediates/libfizz_buzz/android_arm64_armv8-a_rlib_rlib-std/rustdoc.timestamp",
+ },
+ },
+ {
+ testName: "rust_binary",
+ moduleName: "fizz_buzz",
+ variant: "android_arm64_armv8-a",
+ expectedFiles: []string{
+ "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz",
+ "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/fizz_buzz.clippy",
+ "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/unstripped/fizz_buzz",
+ "out/soong/target/product/test_device/system/bin/fizz_buzz",
+ "out/soong/.intermediates/fizz_buzz/android_arm64_armv8-a/meta_lic",
+ },
+ },
+ {
+ testName: "rust_ffi static",
+ moduleName: "librust_ffi",
+ variant: "android_arm64_armv8-a_static",
+ expectedFiles: []string{
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/librust_ffi.a",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/librust_ffi.a.clippy",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/meta_lic",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_static/rustdoc.timestamp",
+ },
+ },
+ {
+ testName: "rust_ffi shared",
+ moduleName: "librust_ffi",
+ variant: "android_arm64_armv8-a_shared",
+ expectedFiles: []string{
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/librust_ffi.so.clippy",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/unstripped/librust_ffi.so",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/unstripped/librust_ffi.so.toc",
+ "out/soong/.intermediates/librust_ffi/android_arm64_armv8-a_shared/meta_lic",
+ "out/soong/target/product/test_device/system/lib64/librust_ffi.so",
+ },
+ },
+ }
+ for _, tc := range testcases {
+ t.Run(tc.testName, func(t *testing.T) {
+ modOutputs := ctx.ModuleForTests(tc.moduleName, tc.variant).AllOutputs()
+ sort.Strings(tc.expectedFiles)
+ sort.Strings(modOutputs)
+ android.AssertStringPathsRelativeToTopEquals(
+ t,
+ "incorrect outputs from rust module",
+ ctx.Config(),
+ tc.expectedFiles,
+ modOutputs,
+ )
+ })
+ }
+}
diff --git a/rust/compiler.go b/rust/compiler.go
index e6a7a93..b3f574d 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -73,6 +73,15 @@
// If no source file is defined, a single generated source module can be defined to be used as the main source.
Srcs []string `android:"path,arch_variant"`
+ // Entry point that is passed to rustc to begin the compilation. E.g. main.rs or lib.rs.
+ // When this property is set,
+ // * sandboxing is enabled for this module, and
+ // * the srcs attribute is interpreted as a list of all source files potentially
+ // used in compilation, including the entrypoint, and
+ // * compile_data can be used to add additional files used in compilation that
+ // not directly used as source files.
+ Crate_root *string `android:"path,arch_variant"`
+
// name of the lint set that should be used to validate this module.
//
// Possible values are "default" (for using a sensible set of lints
@@ -318,10 +327,15 @@
flags.LinkFlags = append(flags.LinkFlags, cc.RpathFlags(ctx)...)
}
- if !ctx.toolchain().Bionic() && ctx.Os() != android.LinuxMusl && !ctx.Windows() {
- // Add -ldl, -lpthread, -lm and -lrt to host builds to match the default behavior of device
- // builds. This is irrelevant for the Windows target as these are Posix specific.
+ if ctx.Os() == android.Linux {
+ // Add -lc, -lrt, -ldl, -lpthread, -lm and -lgcc_s to glibc builds to match
+ // the default behavior of device builds.
+ flags.LinkFlags = append(flags.LinkFlags, config.LinuxHostGlobalLinkFlags...)
+ } else if ctx.Os() == android.Darwin {
+ // Add -lc, -ldl, -lpthread and -lm to glibc darwin builds to match the default
+ // behavior of device builds.
flags.LinkFlags = append(flags.LinkFlags,
+ "-lc",
"-ldl",
"-lpthread",
"-lm",
@@ -511,6 +525,8 @@
ctx.PropertyErrorf("srcs", "only a single generated source module can be defined without a main source file.")
}
+ // TODO: b/297264540 - once all modules are sandboxed, we need to select the proper
+ // entry point file from Srcs rather than taking the first one
paths := android.PathsForModuleSrc(ctx, srcs)
return paths[srcIndex], paths[1:]
}
diff --git a/rust/config/global.go b/rust/config/global.go
index c976617..c37ac4e 100644
--- a/rust/config/global.go
+++ b/rust/config/global.go
@@ -52,11 +52,22 @@
"-C force-unwind-tables=yes",
// Use v0 mangling to distinguish from C++ symbols
"-C symbol-mangling-version=v0",
- "--color always",
+ // This flag requires to have no space so that when it's exported to bazel
+ // it can be removed. See aosp/2768339
+ "--color=always",
"-Zdylib-lto",
"-Z link-native-libraries=no",
}
+ LinuxHostGlobalLinkFlags = []string{
+ "-lc",
+ "-lrt",
+ "-ldl",
+ "-lpthread",
+ "-lm",
+ "-lgcc_s",
+ }
+
deviceGlobalRustFlags = []string{
"-C panic=abort",
// Generate additional debug info for AutoFDO
@@ -81,13 +92,7 @@
func init() {
pctx.SourcePathVariable("RustDefaultBase", RustDefaultBase)
- pctx.VariableConfigMethod("HostPrebuiltTag", func(config android.Config) string {
- if config.UseHostMusl() {
- return "linux-musl-x86"
- } else {
- return config.PrebuiltOS()
- }
- })
+ pctx.VariableConfigMethod("HostPrebuiltTag", HostPrebuiltTag)
pctx.VariableFunc("RustBase", func(ctx android.PackageVarContext) string {
if override := ctx.Config().Getenv("RUST_PREBUILTS_BASE"); override != "" {
@@ -107,6 +112,16 @@
pctx.StaticVariable("DeviceGlobalLinkFlags", strings.Join(deviceGlobalLinkFlags, " "))
exportedVars.ExportStringStaticVariable("RUST_DEFAULT_VERSION", RustDefaultVersion)
+ exportedVars.ExportStringListStaticVariable("GLOBAL_RUSTC_FLAGS", GlobalRustFlags)
+ exportedVars.ExportStringListStaticVariable("LINUX_HOST_GLOBAL_LINK_FLAGS", LinuxHostGlobalLinkFlags)
+}
+
+func HostPrebuiltTag(config android.Config) string {
+ if config.UseHostMusl() {
+ return "linux-musl-x86"
+ } else {
+ return config.PrebuiltOS()
+ }
}
func getRustVersionPctx(ctx android.PackageVarContext) string {
diff --git a/rust/coverage.go b/rust/coverage.go
index 5216d60..bc6504d 100644
--- a/rust/coverage.go
+++ b/rust/coverage.go
@@ -65,7 +65,7 @@
"-C instrument-coverage", "-g")
flags.LinkFlags = append(flags.LinkFlags,
profileInstrFlag, "-g", coverage.OutputFile().Path().String(), "-Wl,--wrap,open")
- deps.LibDeps = append(deps.LibDeps, coverage.OutputFile().Path())
+ deps.StaticLibs = append(deps.StaticLibs, coverage.OutputFile().Path())
// no_std modules are missing libprofiler_builtins which provides coverage, so we need to add it as a dependency.
if rustModule, ok := ctx.Module().(*Module); ok && rustModule.compiler.noStdlibs() {
diff --git a/rust/coverage_test.go b/rust/coverage_test.go
index 64077cf..0f599d7 100644
--- a/rust/coverage_test.go
+++ b/rust/coverage_test.go
@@ -55,10 +55,6 @@
libbarNoCov := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustc")
fizzCov := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustc")
buzzNoCov := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustc")
- libfooCovLink := ctx.ModuleForTests("libfoo_cov", "android_arm64_armv8-a_dylib_cov").Rule("rustLink")
- libbarNoCovLink := ctx.ModuleForTests("libbar_nocov", "android_arm64_armv8-a_dylib").Rule("rustLink")
- fizzCovLink := ctx.ModuleForTests("fizz_cov", "android_arm64_armv8-a_cov").Rule("rustLink")
- buzzNoCovLink := ctx.ModuleForTests("buzzNoCov", "android_arm64_armv8-a").Rule("rustLink")
rustcCoverageFlags := []string{"-C instrument-coverage", " -g "}
for _, flag := range rustcCoverageFlags {
@@ -84,17 +80,17 @@
missingErrorStr := "missing rust linker flag '%s' for '%s' module with coverage enabled; rustcFlags: %#v"
containsErrorStr := "contains rust linker flag '%s' for '%s' module with coverage disabled; rustcFlags: %#v"
- if !strings.Contains(fizzCovLink.Args["linkFlags"], flag) {
- t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCovLink.Args["linkFlags"])
+ if !strings.Contains(fizzCov.Args["linkFlags"], flag) {
+ t.Fatalf(missingErrorStr, flag, "fizz_cov", fizzCov.Args["linkFlags"])
}
- if !strings.Contains(libfooCovLink.Args["linkFlags"], flag) {
- t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCovLink.Args["linkFlags"])
+ if !strings.Contains(libfooCov.Args["linkFlags"], flag) {
+ t.Fatalf(missingErrorStr, flag, "libfoo_cov dylib", libfooCov.Args["linkFlags"])
}
- if strings.Contains(buzzNoCovLink.Args["linkFlags"], flag) {
- t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCovLink.Args["linkFlags"])
+ if strings.Contains(buzzNoCov.Args["linkFlags"], flag) {
+ t.Fatalf(containsErrorStr, flag, "buzzNoCov", buzzNoCov.Args["linkFlags"])
}
- if strings.Contains(libbarNoCovLink.Args["linkFlags"], flag) {
- t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCovLink.Args["linkFlags"])
+ if strings.Contains(libbarNoCov.Args["linkFlags"], flag) {
+ t.Fatalf(containsErrorStr, flag, "libbar_cov", libbarNoCov.Args["linkFlags"])
}
}
@@ -107,7 +103,7 @@
srcs: ["foo.rs"],
}`)
- fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustLink")
+ fizz := ctx.ModuleForTests("fizz", "android_arm64_armv8-a_cov").Rule("rustc")
if !strings.Contains(fizz.Args["linkFlags"], "libprofile-clang-extras.a") {
t.Fatalf("missing expected coverage 'libprofile-clang-extras' dependency in linkFlags: %#v", fizz.Args["linkFlags"])
}
diff --git a/rust/library.go b/rust/library.go
index 0357086..c598473 100644
--- a/rust/library.go
+++ b/rust/library.go
@@ -489,7 +489,7 @@
var outputFile android.ModuleOutPath
var ret buildOutput
var fileName string
- srcPath := library.srcPath(ctx, deps)
+ crateRootPath := library.crateRootPath(ctx, deps)
if library.sourceProvider != nil {
deps.srcProviderFiles = append(deps.srcProviderFiles, library.sourceProvider.Srcs()...)
@@ -525,7 +525,7 @@
flags.RustFlags = append(flags.RustFlags, deps.depFlags...)
flags.LinkFlags = append(flags.LinkFlags, deps.depLinkFlags...)
- flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects.Strings()...)
+ flags.LinkFlags = append(flags.LinkFlags, deps.linkObjects...)
if library.dylib() {
// We need prefer-dynamic for now to avoid linking in the static stdlib. See:
@@ -536,19 +536,18 @@
// Call the appropriate builder for this library type
if library.rlib() {
- ret.kytheFile = TransformSrctoRlib(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrctoRlib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
} else if library.dylib() {
- ret.kytheFile = TransformSrctoDylib(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrctoDylib(ctx, crateRootPath, deps, flags, outputFile).kytheFile
} else if library.static() {
- ret.kytheFile = TransformSrctoStatic(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrctoStatic(ctx, crateRootPath, deps, flags, outputFile).kytheFile
} else if library.shared() {
- ret.kytheFile = TransformSrctoShared(ctx, srcPath, deps, flags, outputFile).kytheFile
+ ret.kytheFile = TransformSrctoShared(ctx, crateRootPath, deps, flags, outputFile).kytheFile
}
if library.rlib() || library.dylib() {
library.flagExporter.exportLinkDirs(deps.linkDirs...)
library.flagExporter.exportLinkObjects(deps.linkObjects...)
- library.flagExporter.exportLibDeps(deps.LibDeps...)
}
if library.static() || library.shared() {
@@ -585,13 +584,15 @@
return ret
}
-func (library *libraryDecorator) srcPath(ctx ModuleContext, _ PathDeps) android.Path {
+func (library *libraryDecorator) crateRootPath(ctx ModuleContext, _ PathDeps) android.Path {
if library.sourceProvider != nil {
// Assume the first source from the source provider is the library entry point.
return library.sourceProvider.Srcs()[0]
- } else {
+ } else if library.baseCompiler.Properties.Crate_root == nil {
path, _ := srcPathFromModuleSrcs(ctx, library.baseCompiler.Properties.Srcs)
return path
+ } else {
+ return android.PathForModuleSrc(ctx, *library.baseCompiler.Properties.Crate_root)
}
}
@@ -606,7 +607,7 @@
return android.OptionalPath{}
}
- return android.OptionalPathForPath(Rustdoc(ctx, library.srcPath(ctx, deps),
+ return android.OptionalPathForPath(Rustdoc(ctx, library.crateRootPath(ctx, deps),
deps, flags))
}
diff --git a/rust/library_test.go b/rust/library_test.go
index 30ef333..e03074d 100644
--- a/rust/library_test.go
+++ b/rust/library_test.go
@@ -148,7 +148,7 @@
libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared")
- libfooOutput := libfoo.Rule("rustLink")
+ libfooOutput := libfoo.Rule("rustc")
if !strings.Contains(libfooOutput.Args["linkFlags"], "-Wl,-soname=libfoo.so") {
t.Errorf("missing expected -Wl,-soname linker flag for libfoo shared lib, linkFlags: %#v",
libfooOutput.Args["linkFlags"])
diff --git a/rust/protobuf.go b/rust/protobuf.go
index c8d2bda..2982efd 100644
--- a/rust/protobuf.go
+++ b/rust/protobuf.go
@@ -20,6 +20,7 @@
"android/soong/android"
"android/soong/bazel"
+ "android/soong/cc"
"github.com/google/blueprint/proptools"
)
@@ -59,14 +60,18 @@
// Use protobuf version 3.x. This will be deleted once we migrate all current users
// of protobuf off of 2.x.
Use_protobuf3 *bool
+
+ // List of exported include paths containing proto files for dependent rust_protobuf modules.
+ Exported_include_dirs []string
}
type protobufDecorator struct {
*BaseSourceProvider
- Properties ProtobufProperties
- protoNames []string
- grpcNames []string
+ Properties ProtobufProperties
+ protoNames []string
+ additionalCrates []string
+ grpcNames []string
grpcProtoFlags android.ProtoFlags
protoFlags android.ProtoFlags
@@ -184,6 +189,10 @@
// stemFile must be first here as the first path in BaseSourceProvider.OutputFiles is the library entry-point.
proto.BaseSourceProvider.OutputFiles = append(android.Paths{stemFile}, outputs.Paths()...)
+ ctx.SetProvider(cc.FlagExporterInfoProvider, cc.FlagExporterInfo{
+ IncludeDirs: android.PathsForModuleSrc(ctx, proto.Properties.Exported_include_dirs),
+ })
+
// mod_stem.rs is the entry-point for our library modules, so this is what we return.
return stemFile
}
@@ -192,10 +201,16 @@
lines := []string{
"// @Soong generated Source",
}
+
for _, protoName := range proto.protoNames {
lines = append(lines, fmt.Sprintf("pub mod %s;", protoName))
}
+ for _, crate := range proto.additionalCrates {
+ lines = append(lines, fmt.Sprintf("pub use %s::*;", crate))
+
+ }
+
for _, grpcName := range proto.grpcNames {
lines = append(lines, fmt.Sprintf("pub mod %s;", grpcName))
lines = append(lines, fmt.Sprintf("pub mod %s%s;", grpcName, grpcSuffix))
@@ -305,7 +320,11 @@
},
}
- ctx.CreateBazelTargetModule(
+ // TODO(b/295918553): Remove androidRestriction after rust toolchain for android is checked in.
+ var androidRestriction bazel.BoolAttribute
+ androidRestriction.SetSelectValue(bazel.OsConfigurationAxis, "android", proptools.BoolPtr(false))
+
+ ctx.CreateBazelTargetModuleWithRestrictions(
bazel.BazelTargetModuleProperties{
Rule_class: "proto_library",
},
@@ -317,9 +336,10 @@
android.BazelLabelForModuleSrc(ctx, protoFiles),
),
},
+ androidRestriction,
)
- ctx.CreateBazelTargetModule(
+ ctx.CreateBazelTargetModuleWithRestrictions(
bazel.BazelTargetModuleProperties{
Rule_class: "rust_proto_library",
Bzl_load_location: "@rules_rust//proto/protobuf:defs.bzl",
@@ -333,5 +353,6 @@
},
Deps: protoDeps,
},
+ androidRestriction,
)
}
diff --git a/rust/protobuf_test.go b/rust/protobuf_test.go
index b723f3f..9dca029 100644
--- a/rust/protobuf_test.go
+++ b/rust/protobuf_test.go
@@ -118,6 +118,58 @@
}
}
+func TestRustProtobufInclude(t *testing.T) {
+ ctx := testRust(t, `
+ rust_protobuf {
+ name: "librust_proto",
+ protos: ["proto.proto"],
+ crate_name: "rust_proto",
+ source_stem: "proto",
+ use_protobuf3: true,
+ rustlibs: ["librust_exported_proto", "libfoo"],
+ }
+ rust_protobuf {
+ name: "librust_exported_proto",
+ protos: ["proto.proto"],
+ crate_name: "rust_exported_proto",
+ source_stem: "exported_proto",
+ use_protobuf3: true,
+ exported_include_dirs: ["proto"]
+ }
+ rust_library {
+ name: "libfoo",
+ crate_name: "foo",
+ srcs: ["foo.rs"],
+ }
+ `)
+ // Check that librust_exported_proto is added as additional crate to generate source.
+ librust_proto := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Module().(*Module).sourceProvider.(*protobufDecorator)
+ if !android.InList("rust_exported_proto", librust_proto.additionalCrates) {
+ t.Errorf("librust_proto should have librust_exported_proto included as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
+ }
+
+ // Make sure the default crates aren't being included.
+ if android.InList("std", librust_proto.additionalCrates) {
+ t.Errorf("librust_proto should not have included libstd as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
+ }
+ if android.InList("protobuf", librust_proto.additionalCrates) {
+ t.Errorf("librust_proto should not have included libprotobuf as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
+ }
+
+ // And make sure that non-protobuf crates aren't getting included either.
+ if android.InList("foo", librust_proto.additionalCrates) {
+ t.Errorf("librust_proto should not have included libfoo as an additional crate for generated source, instead got: %#v", librust_proto.additionalCrates)
+ }
+
+ // Check librust_proto args includes -Iproto
+ librust_proto_rule := ctx.ModuleForTests("librust_proto", "android_arm64_armv8-a_source").Output("proto.rs")
+ cmd := librust_proto_rule.RuleParams.Command
+ if w := "-Iproto"; !strings.Contains(cmd, w) {
+ t.Errorf("expected %q in %q", w, cmd)
+ }
+
+}
+
func TestRustGrpc(t *testing.T) {
ctx := testRust(t, `
rust_protobuf {
diff --git a/rust/rust.go b/rust/rust.go
index 3b24484..ba63613 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -267,6 +267,15 @@
return false
}
+func (mod *Module) Source() bool {
+ if mod.compiler != nil {
+ if library, ok := mod.compiler.(libraryInterface); ok && mod.sourceProvider != nil {
+ return library.source()
+ }
+ }
+ return false
+}
+
func (mod *Module) RlibStd() bool {
if mod.compiler != nil {
if library, ok := mod.compiler.(libraryInterface); ok && library.rlib() {
@@ -438,12 +447,13 @@
}
type PathDeps struct {
- DyLibs RustLibraries
- RLibs RustLibraries
- LibDeps android.Paths
- WholeStaticLibs android.Paths
- ProcMacros RustLibraries
- AfdoProfiles android.Paths
+ DyLibs RustLibraries
+ RLibs RustLibraries
+ SharedLibs android.Paths
+ SharedLibDeps android.Paths
+ StaticLibs android.Paths
+ ProcMacros RustLibraries
+ AfdoProfiles android.Paths
// depFlags and depLinkFlags are rustc and linker (clang) flags.
depFlags []string
@@ -452,7 +462,7 @@
// linkDirs are link paths passed via -L to rustc. linkObjects are objects passed directly to the linker.
// Both of these are exported and propagate to dependencies.
linkDirs []string
- linkObjects android.Paths
+ linkObjects []string
// Used by bindgen modules which call clang
depClangFlags []string
@@ -515,7 +525,7 @@
type exportedFlagsProducer interface {
exportLinkDirs(...string)
- exportLinkObjects(...android.Path)
+ exportLinkObjects(...string)
}
type xref interface {
@@ -524,27 +534,21 @@
type flagExporter struct {
linkDirs []string
- linkObjects android.Paths
- libDeps android.Paths
+ linkObjects []string
}
func (flagExporter *flagExporter) exportLinkDirs(dirs ...string) {
flagExporter.linkDirs = android.FirstUniqueStrings(append(flagExporter.linkDirs, dirs...))
}
-func (flagExporter *flagExporter) exportLinkObjects(flags ...android.Path) {
- flagExporter.linkObjects = android.FirstUniquePaths(append(flagExporter.linkObjects, flags...))
-}
-
-func (flagExporter *flagExporter) exportLibDeps(paths ...android.Path) {
- flagExporter.libDeps = android.FirstUniquePaths(append(flagExporter.libDeps, paths...))
+func (flagExporter *flagExporter) exportLinkObjects(flags ...string) {
+ flagExporter.linkObjects = android.FirstUniqueStrings(append(flagExporter.linkObjects, flags...))
}
func (flagExporter *flagExporter) setProvider(ctx ModuleContext) {
ctx.SetProvider(FlagExporterInfoProvider, FlagExporterInfo{
LinkDirs: flagExporter.linkDirs,
LinkObjects: flagExporter.linkObjects,
- LibDeps: flagExporter.libDeps,
})
}
@@ -557,8 +561,7 @@
type FlagExporterInfo struct {
Flags []string
LinkDirs []string // TODO: this should be android.Paths
- LinkObjects android.Paths
- LibDeps android.Paths
+ LinkObjects []string // TODO: this should be android.Paths
}
var FlagExporterInfoProvider = blueprint.NewProvider(FlagExporterInfo{})
@@ -1156,6 +1159,13 @@
return cc.MakeLibName(ctx, c, dep, depName)
}
+func collectIncludedProtos(mod *Module, dep *Module) {
+ if protoMod, ok := mod.sourceProvider.(*protobufDecorator); ok {
+ if _, ok := dep.sourceProvider.(*protobufDecorator); ok {
+ protoMod.additionalCrates = append(protoMod.additionalCrates, dep.CrateName())
+ }
+ }
+}
func (mod *Module) depsToPaths(ctx android.ModuleContext) PathDeps {
var depPaths PathDeps
@@ -1268,6 +1278,11 @@
case procMacroDepTag:
directProcMacroDeps = append(directProcMacroDeps, rustDep)
mod.Properties.AndroidMkProcMacroLibs = append(mod.Properties.AndroidMkProcMacroLibs, makeLibName)
+
+ case sourceDepTag:
+ if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
+ collectIncludedProtos(mod, rustDep)
+ }
}
transitiveAndroidMkSharedLibs = append(transitiveAndroidMkSharedLibs, rustDep.transitiveAndroidMkSharedLibs)
@@ -1298,7 +1313,6 @@
depPaths.linkDirs = append(depPaths.linkDirs, exportedInfo.LinkDirs...)
depPaths.depFlags = append(depPaths.depFlags, exportedInfo.Flags...)
depPaths.linkObjects = append(depPaths.linkObjects, exportedInfo.LinkObjects...)
- depPaths.LibDeps = append(depPaths.LibDeps, exportedInfo.LibDeps...)
}
if depTag == dylibDepTag || depTag == rlibDepTag || depTag == procMacroDepTag {
@@ -1308,7 +1322,14 @@
lib.exportLinkDirs(linkDir)
}
}
-
+ if depTag == sourceDepTag {
+ if _, ok := mod.sourceProvider.(*protobufDecorator); ok && mod.Source() {
+ if _, ok := rustDep.sourceProvider.(*protobufDecorator); ok {
+ exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
+ depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
+ }
+ }
+ }
} else if ccDep, ok := dep.(cc.LinkableInterface); ok {
//Handle C dependencies
makeLibName := cc.MakeLibName(ctx, mod, ccDep, depName)
@@ -1347,7 +1368,6 @@
depPaths.depLinkFlags = append(depPaths.depLinkFlags, []string{"-Wl,--whole-archive", linkObject.Path().String(), "-Wl,--no-whole-archive"}...)
} else if libName, ok := libNameFromFilePath(linkObject.Path()); ok {
depPaths.depFlags = append(depPaths.depFlags, "-lstatic="+libName)
- depPaths.WholeStaticLibs = append(depPaths.WholeStaticLibs, linkObject.Path())
} else {
ctx.ModuleErrorf("'%q' cannot be listed as a whole_static_library in Rust modules unless the output is prefixed by 'lib'", depName, ctx.ModuleName())
}
@@ -1355,7 +1375,7 @@
// Add this to linkObjects to pass the library directly to the linker as well. This propagates
// to dependencies to avoid having to redeclare static libraries for dependents of the dylib variant.
- depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
+ depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
exportedInfo := ctx.OtherModuleProvider(dep, cc.FlagExporterInfoProvider).(cc.FlagExporterInfo)
@@ -1389,7 +1409,7 @@
linkPath = linkPathFromFilePath(linkObject.Path())
depPaths.linkDirs = append(depPaths.linkDirs, linkPath)
- depPaths.linkObjects = append(depPaths.linkObjects, linkObject.AsPaths()...)
+ depPaths.linkObjects = append(depPaths.linkObjects, linkObject.String())
depPaths.depIncludePaths = append(depPaths.depIncludePaths, exportedInfo.IncludeDirs...)
depPaths.depSystemIncludePaths = append(depPaths.depSystemIncludePaths, exportedInfo.SystemIncludeDirs...)
depPaths.depClangFlags = append(depPaths.depClangFlags, exportedInfo.Flags...)
@@ -1415,9 +1435,7 @@
// Make sure these dependencies are propagated
if lib, ok := mod.compiler.(exportedFlagsProducer); ok && exportDep {
lib.exportLinkDirs(linkPath)
- if linkObject.Valid() {
- lib.exportLinkObjects(linkObject.Path())
- }
+ lib.exportLinkObjects(linkObject.String())
}
} else {
switch {
@@ -1451,16 +1469,19 @@
procMacroDepFiles = append(procMacroDepFiles, RustLibrary{Path: dep.UnstrippedOutputFile(), CrateName: dep.CrateName()})
}
- var libDepFiles android.Paths
+ var staticLibDepFiles android.Paths
for _, dep := range directStaticLibDeps {
- libDepFiles = append(libDepFiles, dep.OutputFile().Path())
+ staticLibDepFiles = append(staticLibDepFiles, dep.OutputFile().Path())
}
+ var sharedLibFiles android.Paths
+ var sharedLibDepFiles android.Paths
for _, dep := range directSharedLibDeps {
+ sharedLibFiles = append(sharedLibFiles, dep.SharedLibrary)
if dep.TableOfContents.Valid() {
- libDepFiles = append(libDepFiles, dep.TableOfContents.Path())
+ sharedLibDepFiles = append(sharedLibDepFiles, dep.TableOfContents.Path())
} else {
- libDepFiles = append(libDepFiles, dep.SharedLibrary)
+ sharedLibDepFiles = append(sharedLibDepFiles, dep.SharedLibrary)
}
}
@@ -1476,13 +1497,15 @@
depPaths.RLibs = append(depPaths.RLibs, rlibDepFiles...)
depPaths.DyLibs = append(depPaths.DyLibs, dylibDepFiles...)
- depPaths.LibDeps = append(depPaths.LibDeps, libDepFiles...)
+ depPaths.SharedLibs = append(depPaths.SharedLibs, sharedLibFiles...)
+ depPaths.SharedLibDeps = append(depPaths.SharedLibDeps, sharedLibDepFiles...)
+ depPaths.StaticLibs = append(depPaths.StaticLibs, staticLibDepFiles...)
depPaths.ProcMacros = append(depPaths.ProcMacros, procMacroDepFiles...)
depPaths.SrcDeps = append(depPaths.SrcDeps, srcProviderDepFiles...)
// Dedup exported flags from dependencies
depPaths.linkDirs = android.FirstUniqueStrings(depPaths.linkDirs)
- depPaths.linkObjects = android.FirstUniquePaths(depPaths.linkObjects)
+ depPaths.linkObjects = android.FirstUniqueStrings(depPaths.linkObjects)
depPaths.depFlags = android.FirstUniqueStrings(depPaths.depFlags)
depPaths.depClangFlags = android.FirstUniqueStrings(depPaths.depClangFlags)
depPaths.depIncludePaths = android.FirstUniquePaths(depPaths.depIncludePaths)
@@ -1572,30 +1595,43 @@
}
// rustlibs
- if deps.Rustlibs != nil && !mod.compiler.Disabled() {
- autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
- for _, lib := range deps.Rustlibs {
- if autoDep.depTag == rlibDepTag {
- // Handle the rlib deptag case
- addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations)
- } else {
- // autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however.
- // Check for the existence of the dylib deptag variant. Select it if available,
- // otherwise select the rlib variant.
- autoDepVariations := append(commonDepVariations,
- blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
-
- replacementLib := cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Dylibs)
-
- if actx.OtherModuleDependencyVariantExists(autoDepVariations, replacementLib) {
- addDylibDependency(actx, lib, mod, &snapshotInfo, autoDepVariations, autoDep.depTag)
- } else {
- // If there's no dylib dependency available, try to add the rlib dependency instead.
+ if deps.Rustlibs != nil {
+ if !mod.compiler.Disabled() {
+ for _, lib := range deps.Rustlibs {
+ autoDep := mod.compiler.(autoDeppable).autoDep(ctx)
+ if autoDep.depTag == rlibDepTag {
+ // Handle the rlib deptag case
addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations)
+ } else {
+ // autoDep.depTag is a dylib depTag. Not all rustlibs may be available as a dylib however.
+ // Check for the existence of the dylib deptag variant. Select it if available,
+ // otherwise select the rlib variant.
+ autoDepVariations := append(commonDepVariations,
+ blueprint.Variation{Mutator: "rust_libraries", Variation: autoDep.variation})
+
+ replacementLib := cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Dylibs)
+
+ if actx.OtherModuleDependencyVariantExists(autoDepVariations, replacementLib) {
+ addDylibDependency(actx, lib, mod, &snapshotInfo, autoDepVariations, autoDep.depTag)
+ } else {
+ // If there's no dylib dependency available, try to add the rlib dependency instead.
+ addRlibDependency(actx, lib, mod, &snapshotInfo, rlibDepVariations)
+ }
+ }
+ }
+ } else if _, ok := mod.sourceProvider.(*protobufDecorator); ok {
+ for _, lib := range deps.Rustlibs {
+ replacementLib := cc.GetReplaceModuleName(lib, cc.GetSnapshot(mod, &snapshotInfo, actx).Dylibs)
+ srcProviderVariations := append(commonDepVariations,
+ blueprint.Variation{Mutator: "rust_libraries", Variation: "source"})
+
+ if actx.OtherModuleDependencyVariantExists(srcProviderVariations, replacementLib) {
+ actx.AddVariationDependencies(srcProviderVariations, sourceDepTag, lib)
}
}
}
}
+
// stdlibs
if deps.Stdlibs != nil {
if mod.compiler.stdLinkage(ctx) == RlibLinkage {
@@ -1853,7 +1889,7 @@
procMacroBp2build(ctx, m)
} else if ctx.ModuleType() == "rust_binary_host" {
binaryBp2build(ctx, m)
- } else if ctx.ModuleType() == "rust_protobuf_host" {
+ } else if ctx.ModuleType() == "rust_protobuf_host" || ctx.ModuleType() == "rust_protobuf" {
protoLibraryBp2build(ctx, m)
} else {
ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_TYPE_UNSUPPORTED, "")
diff --git a/rust/rust_test.go b/rust/rust_test.go
index 835114c..d609c2f 100644
--- a/rust/rust_test.go
+++ b/rust/rust_test.go
@@ -40,7 +40,6 @@
PrepareForTestWithRustIncludeVndk,
android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
- variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("29")
}),
)
@@ -105,7 +104,6 @@
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr(device_version)
- variables.ProductVndkVersion = StringPtr(product_version)
variables.Platform_vndk_version = StringPtr(vndk_version)
},
),
@@ -173,7 +171,6 @@
android.FixtureModifyProductVariables(
func(variables android.FixtureProductVariables) {
variables.DeviceVndkVersion = StringPtr("current")
- variables.ProductVndkVersion = StringPtr("current")
variables.Platform_vndk_version = StringPtr("VER")
},
),
@@ -256,7 +253,6 @@
`)
module := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Module().(*Module)
rustc := ctx.ModuleForTests("librlib", "linux_glibc_x86_64_rlib_rlib-std").Rule("rustc")
- rustLink := ctx.ModuleForTests("fizz-buzz", "linux_glibc_x86_64").Rule("rustLink")
// Since dependencies are added to AndroidMk* properties, we can check these to see if they've been picked up.
if !android.InList("librlib.rlib-std", module.Properties.AndroidMkRlibs) {
@@ -279,16 +275,16 @@
t.Errorf("-lstatic flag not being passed to rustc for static library %#v", rustc.Args["rustcFlags"])
}
- if !strings.Contains(rustLink.Args["linkFlags"], "cc_stubs_dep.so") {
- t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustLink.Args["linkFlags"])
+ if !strings.Contains(rustc.Args["linkFlags"], "cc_stubs_dep.so") {
+ t.Errorf("shared cc_library not being passed to rustc linkFlags %#v", rustc.Args["linkFlags"])
}
- if !android.SuffixInList(rustLink.OrderOnly.Strings(), "cc_stubs_dep.so") {
- t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustLink.OrderOnly.Strings())
+ if !android.SuffixInList(rustc.OrderOnly.Strings(), "cc_stubs_dep.so") {
+ t.Errorf("shared cc dep not being passed as order-only to rustc %#v", rustc.OrderOnly.Strings())
}
- if !android.SuffixInList(rustLink.Implicits.Strings(), "cc_stubs_dep.so.toc") {
- t.Errorf("shared cc dep TOC not being passed as implicit to rustc %#v", rustLink.Implicits.Strings())
+ if !android.SuffixInList(rustc.Implicits.Strings(), "cc_stubs_dep.so.toc") {
+ t.Errorf("shared cc dep TOC not being passed as implicit to rustc %#v", rustc.Implicits.Strings())
}
}
diff --git a/rust/sanitize_test.go b/rust/sanitize_test.go
index 43e95f4..d6a14b2 100644
--- a/rust/sanitize_test.go
+++ b/rust/sanitize_test.go
@@ -35,7 +35,7 @@
note_sync := "note_memtag_heap_sync"
found := None
- implicits := m.Rule("rustLink").Implicits
+ implicits := m.Rule("rustc").Implicits
for _, lib := range implicits {
if strings.Contains(lib.Rel(), note_async) {
found = Async
diff --git a/rust/toolchain_library.go b/rust/toolchain_library.go
index 326d529..054104c 100644
--- a/rust/toolchain_library.go
+++ b/rust/toolchain_library.go
@@ -18,9 +18,12 @@
import (
"path"
+ "path/filepath"
"android/soong/android"
"android/soong/rust/config"
+
+ "github.com/google/blueprint/proptools"
)
// This module is used to compile the rust toolchain libraries
@@ -33,11 +36,15 @@
rustToolchainLibraryRlibFactory)
android.RegisterModuleType("rust_toolchain_library_dylib",
rustToolchainLibraryDylibFactory)
+ android.RegisterModuleType("rust_toolchain_rustc_prebuilt",
+ rustToolchainRustcPrebuiltFactory)
}
type toolchainLibraryProperties struct {
- // path to the toolchain source, relative to the top of the toolchain source
- Toolchain_src *string `android:"arch_variant"`
+ // path to the toolchain crate root, relative to the top of the toolchain source
+ Toolchain_crate_root *string `android:"arch_variant"`
+ // path to the rest of the toolchain srcs, relative to the top of the toolchain source
+ Toolchain_srcs []string `android:"arch_variant"`
}
type toolchainLibraryDecorator struct {
@@ -82,16 +89,21 @@
func rustSetToolchainSource(ctx android.LoadHookContext) {
if toolchainLib, ok := ctx.Module().(*Module).compiler.(*toolchainLibraryDecorator); ok {
- prefix := "linux-x86/" + GetRustPrebuiltVersion(ctx)
- newSrcs := []string{path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_src))}
+ prefix := filepath.Join("linux-x86", GetRustPrebuiltVersion(ctx))
+ versionedCrateRoot := path.Join(prefix, android.String(toolchainLib.Properties.Toolchain_crate_root))
+ versionedSrcs := make([]string, len(toolchainLib.Properties.Toolchain_srcs))
+ for i, src := range toolchainLib.Properties.Toolchain_srcs {
+ versionedSrcs[i] = path.Join(prefix, src)
+ }
type props struct {
- Srcs []string
+ Crate_root *string
+ Srcs []string
}
p := &props{}
- p.Srcs = newSrcs
+ p.Crate_root = &versionedCrateRoot
+ p.Srcs = versionedSrcs
ctx.AppendProperties(p)
-
} else {
ctx.ModuleErrorf("Called rustSetToolchainSource on a non-Rust Module.")
}
@@ -101,3 +113,47 @@
func GetRustPrebuiltVersion(ctx android.LoadHookContext) string {
return ctx.AConfig().GetenvWithDefault("RUST_PREBUILTS_VERSION", config.RustDefaultVersion)
}
+
+type toolchainRustcPrebuiltProperties struct {
+ // path to rustc prebuilt, relative to the top of the toolchain source
+ Toolchain_prebuilt_src *string
+ // path to deps, relative to the top of the toolchain source
+ Toolchain_deps []string
+ // path to deps, relative to module directory
+ Deps []string
+}
+
+func rustToolchainRustcPrebuiltFactory() android.Module {
+ module := android.NewPrebuiltBuildTool()
+ module.AddProperties(&toolchainRustcPrebuiltProperties{})
+ android.AddLoadHook(module, func(ctx android.LoadHookContext) {
+ var toolchainProps *toolchainRustcPrebuiltProperties
+ for _, p := range ctx.Module().GetProperties() {
+ toolchainProperties, ok := p.(*toolchainRustcPrebuiltProperties)
+ if ok {
+ toolchainProps = toolchainProperties
+ }
+ }
+
+ if toolchainProps.Toolchain_prebuilt_src == nil {
+ ctx.PropertyErrorf("toolchain_prebuilt_src", "must set path to rustc prebuilt")
+ }
+
+ prefix := filepath.Join(config.HostPrebuiltTag(ctx.Config()), GetRustPrebuiltVersion(ctx))
+ deps := make([]string, 0, len(toolchainProps.Toolchain_deps)+len(toolchainProps.Deps))
+ for _, d := range toolchainProps.Toolchain_deps {
+ deps = append(deps, path.Join(prefix, d))
+ }
+ deps = append(deps, toolchainProps.Deps...)
+
+ props := struct {
+ Src *string
+ Deps []string
+ }{
+ Src: proptools.StringPtr(path.Join(prefix, *toolchainProps.Toolchain_prebuilt_src)),
+ Deps: deps,
+ }
+ ctx.AppendProperties(&props)
+ })
+ return module
+}
diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go
index 1e7e7d3..4f45799 100644
--- a/rust/vendor_snapshot_test.go
+++ b/rust/vendor_snapshot_test.go
@@ -1051,7 +1051,7 @@
ctx := testRustVndkFsVersions(t, "", mockFS, "30", "current", "31")
// libclient uses libvndk.vndk.30.arm64, libvendor.vendor_static.30.arm64, libvendor_without_snapshot
- libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustLink").Args["linkFlags"]
+ libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("rustc").Args["linkFlags"]
for _, input := range [][]string{
[]string{sharedVariant, "libvndk.vndk.30.arm64"},
[]string{staticVariant, "libvendor.vendor_static.30.arm64"},
@@ -1119,7 +1119,7 @@
t.Errorf("Unexpected rust rlib name in AndroidMk: %q, expected: %q\n", rustVendorBinMkDylibName, expectedRustVendorSnapshotName)
}
- binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustLink").Args["linkFlags"]
+ binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("rustc").Args["linkFlags"]
libVndkStaticOutputPaths := cc.GetOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.30.arm64"})
if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
diff --git a/scripts/conv_linker_config.py b/scripts/conv_linker_config.py
index c6aa3d0..c6e6e30 100644
--- a/scripts/conv_linker_config.py
+++ b/scripts/conv_linker_config.py
@@ -62,8 +62,8 @@
if args.source:
for input in args.source.split(':'):
pb.MergeFrom(LoadJsonMessage(input))
- with open(args.output, 'wb') as f:
- f.write(pb.SerializeToString())
+
+ ValidateAndWriteAsPbFile(pb, args.output)
def Print(args):
@@ -90,8 +90,8 @@
for item in installed_libraries:
if item not in getattr(pb, 'provideLibs'):
getattr(pb, 'provideLibs').append(item)
- with open(args.output, 'wb') as f:
- f.write(pb.SerializeToString())
+
+ ValidateAndWriteAsPbFile(pb, args.output)
def Append(args):
@@ -106,8 +106,8 @@
else:
setattr(pb, args.key, args.value)
- with open(args.output, 'wb') as f:
- f.write(pb.SerializeToString())
+ ValidateAndWriteAsPbFile(pb, args.output)
+
def Merge(args):
@@ -116,8 +116,7 @@
with open(other, 'rb') as f:
pb.MergeFromString(f.read())
- with open(args.out, 'wb') as f:
- f.write(pb.SerializeToString())
+ ValidateAndWriteAsPbFile(pb, args.output)
def Validate(args):
@@ -151,6 +150,29 @@
sys.exit(f'Unknown type: {args.type}')
+def ValidateAndWriteAsPbFile(pb, output_path):
+ ValidateConfiguration(pb)
+ with open(output_path, 'wb') as f:
+ f.write(pb.SerializeToString())
+
+
+def ValidateConfiguration(pb):
+ """
+ Validate if the configuration is valid to be used as linker configuration
+ """
+
+ # Validate if provideLibs and requireLibs have common module
+ provideLibs = set(getattr(pb, 'provideLibs'))
+ requireLibs = set(getattr(pb, 'requireLibs'))
+
+ intersectLibs = provideLibs.intersection(requireLibs)
+
+ if intersectLibs:
+ for lib in intersectLibs:
+ print(f'{lib} exists both in requireLibs and provideLibs', file=sys.stderr)
+ sys.exit(1)
+
+
def GetArgParser():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
diff --git a/scripts/mkcratersp.py b/scripts/mkcratersp.py
deleted file mode 100755
index 6ef01eb..0000000
--- a/scripts/mkcratersp.py
+++ /dev/null
@@ -1,85 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2023 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.
-#
-
-"""
-This script is used as a replacement for the Rust linker. It converts a linker
-command line into a rspfile that can be used during the link phase.
-"""
-
-import os
-import shutil
-import subprocess
-import sys
-
-def create_archive(out, objects, archives):
- mricmd = f'create {out}\n'
- for o in objects:
- mricmd += f'addmod {o}\n'
- for a in archives:
- mricmd += f'addlib {a}\n'
- mricmd += 'save\nend\n'
- subprocess.run([os.getenv('AR'), '-M'], encoding='utf-8', input=mricmd, check=True)
-
-objects = []
-archives = []
-linkdirs = []
-libs = []
-temp_archives = []
-version_script = None
-
-for i, arg in enumerate(sys.argv):
- if arg == '-o':
- out = sys.argv[i+1]
- if arg == '-L':
- linkdirs.append(sys.argv[i+1])
- if arg.startswith('-l') or arg == '-shared':
- libs.append(arg)
- if os.getenv('ANDROID_RUST_DARWIN') and (arg == '-dylib' or arg == '-dynamiclib'):
- libs.append(arg)
- if arg.startswith('-Wl,--version-script='):
- version_script = arg[21:]
- if arg[0] == '-':
- continue
- if arg.endswith('.o') or arg.endswith('.rmeta'):
- objects.append(arg)
- if arg.endswith('.rlib'):
- if arg.startswith(os.getenv('TMPDIR')):
- temp_archives.append(arg)
- else:
- archives.append(arg)
-
-create_archive(f'{out}.whole.a', objects, [])
-create_archive(f'{out}.a', [], temp_archives)
-
-with open(out, 'w') as f:
- if os.getenv("ANDROID_RUST_DARWIN"):
- print(f'-force_load', file=f)
- print(f'{out}.whole.a', file=f)
- else:
- print(f'-Wl,--whole-archive', file=f)
- print(f'{out}.whole.a', file=f)
- print(f'-Wl,--no-whole-archive', file=f)
- print(f'{out}.a', file=f)
- for a in archives:
- print(a, file=f)
- for linkdir in linkdirs:
- print(f'-L{linkdir}', file=f)
- for l in libs:
- print(l, file=f)
- if version_script:
- shutil.copyfile(version_script, f'{out}.version_script')
- print(f'-Wl,--version-script={out}.version_script', file=f)
diff --git a/sysprop/Android.bp b/sysprop/Android.bp
index e5263fe..7f51000 100644
--- a/sysprop/Android.bp
+++ b/sysprop/Android.bp
@@ -12,6 +12,7 @@
"soong-bp2build",
"soong-cc",
"soong-java",
+ "soong-sysprop-bp2build",
],
srcs: [
"sysprop_library.go",
diff --git a/sysprop/bp2build/Android.bp b/sysprop/bp2build/Android.bp
new file mode 100644
index 0000000..1b9eda8
--- /dev/null
+++ b/sysprop/bp2build/Android.bp
@@ -0,0 +1,16 @@
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+bootstrap_go_package {
+ name: "soong-sysprop-bp2build",
+ pkgPath: "android/soong/sysprop/bp2build",
+ deps: [
+ "soong-android",
+ "soong-bazel",
+ ],
+ srcs: [
+ "bp2build.go",
+ ],
+ pluginFor: ["soong_build"],
+}
diff --git a/sysprop/bp2build/bp2build.go b/sysprop/bp2build/bp2build.go
new file mode 100644
index 0000000..18991de
--- /dev/null
+++ b/sysprop/bp2build/bp2build.go
@@ -0,0 +1,106 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package bp2build
+
+import (
+ "android/soong/android"
+ "android/soong/bazel"
+)
+
+type SyspropLibraryLabels struct {
+ SyspropLibraryLabel string
+ CcSharedLibraryLabel string
+ CcStaticLibraryLabel string
+ JavaLibraryLabel string
+}
+
+// TODO(b/240463568): Additional properties will be added for API validation
+type bazelSyspropLibraryAttributes struct {
+ Srcs bazel.LabelListAttribute
+ Tags bazel.StringListAttribute
+}
+
+func Bp2buildBaseSyspropLibrary(ctx android.Bp2buildMutatorContext, name string, srcs bazel.LabelListAttribute) {
+ apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.Bp2buildMutatorContext), ctx.Module())
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "sysprop_library",
+ Bzl_load_location: "//build/bazel/rules/sysprop:sysprop_library.bzl",
+ },
+ android.CommonAttributes{Name: name},
+ &bazelSyspropLibraryAttributes{
+ Srcs: srcs,
+ Tags: apexAvailableTags,
+ },
+ )
+}
+
+type bazelCcSyspropLibraryAttributes struct {
+ Dep bazel.LabelAttribute
+ Min_sdk_version *string
+ Tags bazel.StringListAttribute
+}
+
+func Bp2buildSyspropCc(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLabels, minSdkVersion *string) {
+ apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.Bp2buildMutatorContext), ctx.Module())
+
+ attrs := &bazelCcSyspropLibraryAttributes{
+ Dep: *bazel.MakeLabelAttribute(":" + labels.SyspropLibraryLabel),
+ Min_sdk_version: minSdkVersion,
+ Tags: apexAvailableTags,
+ }
+
+ if labels.CcSharedLibraryLabel != "" {
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_sysprop_library_shared",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
+ },
+ android.CommonAttributes{Name: labels.CcSharedLibraryLabel},
+ attrs)
+ }
+ if labels.CcStaticLibraryLabel != "" {
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "cc_sysprop_library_static",
+ Bzl_load_location: "//build/bazel/rules/cc:cc_sysprop_library.bzl",
+ },
+ android.CommonAttributes{Name: labels.CcStaticLibraryLabel},
+ attrs)
+ }
+}
+
+type bazelJavaLibraryAttributes struct {
+ Dep bazel.LabelAttribute
+ Min_sdk_version *string
+ Tags bazel.StringListAttribute
+}
+
+func Bp2buildSyspropJava(ctx android.Bp2buildMutatorContext, labels SyspropLibraryLabels, minSdkVersion *string) {
+ apexAvailableTags := android.ApexAvailableTagsWithoutTestApexes(ctx.(android.Bp2buildMutatorContext), ctx.Module())
+
+ ctx.CreateBazelTargetModule(
+ bazel.BazelTargetModuleProperties{
+ Rule_class: "java_sysprop_library",
+ Bzl_load_location: "//build/bazel/rules/java:java_sysprop_library.bzl",
+ },
+ android.CommonAttributes{Name: labels.JavaLibraryLabel},
+ &bazelJavaLibraryAttributes{
+ Dep: *bazel.MakeLabelAttribute(":" + labels.SyspropLibraryLabel),
+ Min_sdk_version: minSdkVersion,
+ Tags: apexAvailableTags,
+ })
+}
diff --git a/sysprop/sysprop_library.go b/sysprop/sysprop_library.go
index d16bf32..13cf68f 100644
--- a/sysprop/sysprop_library.go
+++ b/sysprop/sysprop_library.go
@@ -24,6 +24,8 @@
"sync"
"android/soong/bazel"
+ "android/soong/sysprop/bp2build"
+ "android/soong/ui/metrics/bp2build_metrics_proto"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -230,6 +232,10 @@
return m.BaseModuleName() + "_java_gen_public"
}
+func (m *syspropLibrary) bp2buildJavaImplementationModuleName() string {
+ return m.BaseModuleName() + "_java_library"
+}
+
func (m *syspropLibrary) BaseModuleName() string {
return m.ModuleBase.Name()
}
@@ -431,6 +437,7 @@
Min_sdk_version *string
Bazel_module struct {
Bp2build_available *bool
+ Label *string
}
}
@@ -551,8 +558,10 @@
Min_sdk_version: m.properties.Java.Min_sdk_version,
Bazel_module: struct {
Bp2build_available *bool
+ Label *string
}{
- Bp2build_available: proptools.BoolPtr(false),
+ Label: proptools.StringPtr(
+ fmt.Sprintf("//%s:%s", ctx.ModuleDir(), m.bp2buildJavaImplementationModuleName())),
},
})
@@ -573,6 +582,7 @@
Stem: proptools.StringPtr(m.BaseModuleName()),
Bazel_module: struct {
Bp2build_available *bool
+ Label *string
}{
Bp2build_available: proptools.BoolPtr(false),
},
@@ -592,13 +602,17 @@
// TODO(b/240463568): Additional properties will be added for API validation
func (m *syspropLibrary) ConvertWithBp2build(ctx android.Bp2buildMutatorContext) {
- labels := cc.SyspropLibraryLabels{
- SyspropLibraryLabel: m.BaseModuleName(),
- SharedLibraryLabel: m.CcImplementationModuleName(),
- StaticLibraryLabel: cc.BazelLabelNameForStaticModule(m.CcImplementationModuleName()),
+ if m.Owner() != "Platform" {
+ ctx.MarkBp2buildUnconvertible(bp2build_metrics_proto.UnconvertedReasonType_UNSUPPORTED, "Only sysprop libraries owned by platform are supported at this time")
+ return
}
- cc.Bp2buildSysprop(ctx,
- labels,
- bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)),
- m.properties.Cpp.Min_sdk_version)
+ labels := bp2build.SyspropLibraryLabels{
+ SyspropLibraryLabel: m.BaseModuleName(),
+ CcSharedLibraryLabel: m.CcImplementationModuleName(),
+ CcStaticLibraryLabel: cc.BazelLabelNameForStaticModule(m.CcImplementationModuleName()),
+ JavaLibraryLabel: m.bp2buildJavaImplementationModuleName(),
+ }
+ bp2build.Bp2buildBaseSyspropLibrary(ctx, labels.SyspropLibraryLabel, bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Srcs)))
+ bp2build.Bp2buildSyspropCc(ctx, labels, m.properties.Cpp.Min_sdk_version)
+ bp2build.Bp2buildSyspropJava(ctx, labels, m.properties.Java.Min_sdk_version)
}
diff --git a/sysprop/sysprop_library_conversion_test.go b/sysprop/sysprop_library_conversion_test.go
index 89adf7d..dabcc92 100644
--- a/sysprop/sysprop_library_conversion_test.go
+++ b/sysprop/sysprop_library_conversion_test.go
@@ -58,13 +58,18 @@
bp2build.AttrNameToString{
"dep": `":sysprop_foo"`,
}),
+ bp2build.MakeBazelTargetNoRestrictions("java_sysprop_library",
+ "sysprop_foo_java_library",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ }),
},
})
}
func TestSyspropLibraryCppMinSdkVersion(t *testing.T) {
bp2build.RunBp2BuildTestCaseSimple(t, bp2build.Bp2buildTestCase{
- Description: "sysprop_library with min_sdk_version",
+ Description: "sysprop_library with cpp min_sdk_version",
ModuleTypeUnderTest: "sysprop_library",
ModuleTypeUnderTestFactory: syspropLibraryFactory,
Filesystem: map[string]string{
@@ -105,6 +110,86 @@
"dep": `":sysprop_foo"`,
"min_sdk_version": `"5"`,
}),
+ bp2build.MakeBazelTargetNoRestrictions("java_sysprop_library",
+ "sysprop_foo_java_library",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ }),
},
})
}
+
+func TestSyspropLibraryJavaMinSdkVersion(t *testing.T) {
+ bp2build.RunBp2BuildTestCaseSimple(t, bp2build.Bp2buildTestCase{
+ Description: "sysprop_library with java min_sdk_version",
+ ModuleTypeUnderTest: "sysprop_library",
+ ModuleTypeUnderTestFactory: syspropLibraryFactory,
+ Filesystem: map[string]string{
+ "foo.sysprop": "",
+ "bar.sysprop": "",
+ },
+ Blueprint: `
+sysprop_library {
+ name: "sysprop_foo",
+ srcs: [
+ "foo.sysprop",
+ "bar.sysprop",
+ ],
+ java: {
+ min_sdk_version: "5",
+ },
+ property_owner: "Platform",
+}
+`,
+ ExpectedBazelTargets: []string{
+ bp2build.MakeBazelTargetNoRestrictions("sysprop_library",
+ "sysprop_foo",
+ bp2build.AttrNameToString{
+ "srcs": `[
+ "foo.sysprop",
+ "bar.sysprop",
+ ]`,
+ }),
+ bp2build.MakeBazelTargetNoRestrictions("cc_sysprop_library_shared",
+ "libsysprop_foo",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ }),
+ bp2build.MakeBazelTargetNoRestrictions("cc_sysprop_library_static",
+ "libsysprop_foo_bp2build_cc_library_static",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ }),
+ bp2build.MakeBazelTargetNoRestrictions("java_sysprop_library",
+ "sysprop_foo_java_library",
+ bp2build.AttrNameToString{
+ "dep": `":sysprop_foo"`,
+ "min_sdk_version": `"5"`,
+ }),
+ },
+ })
+}
+
+func TestSyspropLibraryOwnerNotPlatformUnconvertible(t *testing.T) {
+ bp2build.RunBp2BuildTestCaseSimple(t, bp2build.Bp2buildTestCase{
+ Description: "sysprop_library simple",
+ ModuleTypeUnderTest: "sysprop_library",
+ ModuleTypeUnderTestFactory: syspropLibraryFactory,
+ Filesystem: map[string]string{
+ "foo.sysprop": "",
+ "bar.sysprop": "",
+ },
+ Blueprint: `
+sysprop_library {
+ name: "sysprop_foo",
+ srcs: [
+ "foo.sysprop",
+ "bar.sysprop",
+ ],
+ property_owner: "Vendor",
+ device_specific: true,
+}
+`,
+ ExpectedBazelTargets: []string{},
+ })
+}
diff --git a/sysprop/sysprop_test.go b/sysprop/sysprop_test.go
index 80b86e0..e51fe39 100644
--- a/sysprop/sysprop_test.go
+++ b/sysprop/sysprop_test.go
@@ -42,6 +42,7 @@
cc_library_headers {
name: "libbase_headers",
vendor_available: true,
+ product_available: true,
recovery_available: true,
}
@@ -250,6 +251,16 @@
result.ModuleForTests("libsysprop-odm", variant)
}
+ // product variant of vendor-owned sysprop_library
+ for _, variant := range []string{
+ "android_product.29_arm_armv7-a-neon_shared",
+ "android_product.29_arm_armv7-a-neon_static",
+ "android_product.29_arm64_armv8-a_shared",
+ "android_product.29_arm64_armv8-a_static",
+ } {
+ result.ModuleForTests("libsysprop-vendor-on-product", variant)
+ }
+
for _, variant := range []string{
"android_arm_armv7-a-neon_shared",
"android_arm_armv7-a-neon_static",
@@ -259,9 +270,6 @@
library := result.ModuleForTests("libsysprop-platform", variant).Module().(*cc.Module)
expectedApexAvailableOnLibrary := []string{"//apex_available:platform"}
android.AssertDeepEquals(t, "apex available property on libsysprop-platform", expectedApexAvailableOnLibrary, library.ApexProperties.Apex_available)
-
- // product variant of vendor-owned sysprop_library
- result.ModuleForTests("libsysprop-vendor-on-product", variant)
}
result.ModuleForTests("sysprop-platform", "android_common")
@@ -272,15 +280,15 @@
// Check for exported includes
coreVariant := "android_arm64_armv8-a_static"
vendorVariant := "android_vendor.29_arm64_armv8-a_static"
+ productVariant := "android_product.29_arm64_armv8-a_static"
platformInternalPath := "libsysprop-platform/android_arm64_armv8-a_static/gen/sysprop/include"
- platformPublicCorePath := "libsysprop-platform/android_arm64_armv8-a_static/gen/sysprop/public/include"
platformPublicVendorPath := "libsysprop-platform/android_vendor.29_arm64_armv8-a_static/gen/sysprop/public/include"
- platformOnProductPath := "libsysprop-platform-on-product/android_arm64_armv8-a_static/gen/sysprop/public/include"
+ platformOnProductPath := "libsysprop-platform-on-product/android_product.29_arm64_armv8-a_static/gen/sysprop/public/include"
vendorInternalPath := "libsysprop-vendor/android_vendor.29_arm64_armv8-a_static/gen/sysprop/include"
- vendorPublicPath := "libsysprop-vendor-on-product/android_arm64_armv8-a_static/gen/sysprop/public/include"
+ vendorOnProductPath := "libsysprop-vendor-on-product/android_product.29_arm64_armv8-a_static/gen/sysprop/public/include"
platformClient := result.ModuleForTests("cc-client-platform", coreVariant)
platformFlags := platformClient.Rule("cc").Args["cFlags"]
@@ -294,14 +302,14 @@
// platform-static should use platform's internal header
android.AssertStringDoesContain(t, "flags for platform-static", platformStaticFlags, platformInternalPath)
- productClient := result.ModuleForTests("cc-client-product", coreVariant)
+ productClient := result.ModuleForTests("cc-client-product", productVariant)
productFlags := productClient.Rule("cc").Args["cFlags"]
// Product should use platform's and vendor's public headers
if !strings.Contains(productFlags, platformOnProductPath) ||
- !strings.Contains(productFlags, vendorPublicPath) {
+ !strings.Contains(productFlags, vendorOnProductPath) {
t.Errorf("flags for product must contain %#v and %#v, but was %#v.",
- platformPublicCorePath, vendorPublicPath, productFlags)
+ platformOnProductPath, vendorOnProductPath, productFlags)
}
vendorClient := result.ModuleForTests("cc-client-vendor", vendorVariant)
diff --git a/tests/lib.sh b/tests/lib.sh
index 0766d85..fb3b374 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -8,6 +8,11 @@
REAL_TOP="$(readlink -f "$(dirname "$0")"/../../..)"
+function make_mock_top {
+ mock=$(mktemp -t -d st.XXXXX)
+ echo "$mock"
+}
+
if [[ -n "$HARDWIRED_MOCK_TOP" ]]; then
MOCK_TOP="$HARDWIRED_MOCK_TOP"
else
@@ -158,6 +163,7 @@
symlink_directory external/bazelbuild-rules_python
symlink_directory external/bazelbuild-rules_java
symlink_directory external/bazelbuild-rules_rust
+ symlink_directory external/bazelbuild-rules_testing
symlink_directory external/rust/crates/tinyjson
symlink_file WORKSPACE
@@ -197,3 +203,11 @@
info "Completed test case \e[96;1m$f\e[0m"
done
}
+
+function move_mock_top {
+ MOCK_TOP2=$(make_mock_top)
+ rm -rf $MOCK_TOP2
+ mv $MOCK_TOP $MOCK_TOP2
+ MOCK_TOP=$MOCK_TOP2
+ trap cleanup_mock_top EXIT
+}
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index 6b9ff8b..223baa4 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -23,4 +23,4 @@
"$TOP/build/soong/tests/apex_cc_module_arch_variant_tests.sh" "aosp_cf_arm64_phone" "armv8-a" "cortex-a53"
"$TOP/build/bazel/ci/b_test.sh"
-
+"$TOP/build/soong/tests/symlinks_path_test.sh"
diff --git a/tests/sbom_test.sh b/tests/sbom_test.sh
index 73fbeab..8dc1630 100755
--- a/tests/sbom_test.sh
+++ b/tests/sbom_test.sh
@@ -35,14 +35,15 @@
}
function run_soong {
- target_product="$1";shift
- out_dir="$1"; shift
- targets="$1"; shift
+ local out_dir="$1"; shift
+ local targets="$1"; shift
if [ "$#" -ge 1 ]; then
- apps=$1; shift
- TARGET_PRODUCT="${target_product}" TARGET_BUILD_VARIANT=userdebug OUT_DIR="${out_dir}" TARGET_BUILD_UNBUNDLED=true TARGET_BUILD_APPS=$apps build/soong/soong_ui.bash --make-mode ${targets}
+ local apps=$1; shift
+ TARGET_PRODUCT="${target_product}" TARGET_RELEASE="${target_release}" TARGET_BUILD_VARIANT="${target_build_variant}" OUT_DIR="${out_dir}" TARGET_BUILD_UNBUNDLED=true TARGET_BUILD_APPS=$apps \
+ build/soong/soong_ui.bash --make-mode ${targets}
else
- TARGET_PRODUCT="${target_product}" TARGET_BUILD_VARIANT=userdebug OUT_DIR="${out_dir}" build/soong/soong_ui.bash --make-mode ${targets}
+ TARGET_PRODUCT="${target_product}" TARGET_RELEASE="${target_release}" TARGET_BUILD_VARIANT="${target_build_variant}" OUT_DIR="${out_dir}" \
+ build/soong/soong_ui.bash --make-mode ${targets}
fi
}
@@ -67,7 +68,7 @@
# Test
# m droid, build sbom later in case additional dependencies might be built and included in partition images.
- run_soong "aosp_cf_x86_64_phone" "${out_dir}" "droid dump.erofs lz4"
+ run_soong "${out_dir}" "droid dump.erofs lz4"
product_out=$out_dir/target/product/vsoc_x86_64
sbom_test=$product_out/sbom_test
@@ -75,7 +76,7 @@
cp $product_out/*.img $sbom_test
# m sbom
- run_soong "aosp_cf_x86_64_phone" "${out_dir}" sbom
+ run_soong "${out_dir}" sbom
# Generate installed file list from .img files in PRODUCT_OUT
dump_erofs=$out_dir/host/linux-x86/bin/dump.erofs
@@ -217,7 +218,7 @@
out_dir="$(setup)"
# run_soong to build com.android.adbd.apex
- run_soong "module_arm64" "${out_dir}" "sbom deapexer" "com.android.adbd"
+ run_soong "${out_dir}" "sbom deapexer" "com.android.adbd"
deapexer=${out_dir}/host/linux-x86/bin/deapexer
debugfs=${out_dir}/host/linux-x86/bin/debugfs_static
@@ -249,7 +250,7 @@
out_dir="$(setup)"
# run_soong to build Browser2.apk
- run_soong "module_arm64" "${out_dir}" "sbom" "Browser2"
+ run_soong "${out_dir}" "sbom" "Browser2"
sbom_file=${out_dir}/target/product/module_arm64/system/product/app/Browser2/Browser2.apk.spdx.json
echo "============ Diffing files in Browser2.apk and SBOM"
@@ -271,6 +272,41 @@
cleanup "${out_dir}"
}
-test_sbom_aosp_cf_x86_64_phone
-test_sbom_unbundled_apex
-test_sbom_unbundled_apk
\ No newline at end of file
+target_product=aosp_cf_x86_64_phone
+target_release=trunk_staging
+target_build_variant=userdebug
+for i in "$@"; do
+ case $i in
+ TARGET_PRODUCT=*)
+ target_product=${i#*=}
+ shift
+ ;;
+ TARGET_RELEASE=*)
+ target_release=${i#*=}
+ shift
+ ;;
+ TARGET_BUILD_VARIANT=*)
+ target_build_variant=${i#*=}
+ shift
+ ;;
+ *)
+ echo "Unknown command line arguments: $i"
+ exit 1
+ ;;
+ esac
+done
+
+echo "target product: $target_product, target_release: $target_release, target build variant: $target_build_variant"
+case $target_product in
+ aosp_cf_x86_64_phone)
+ test_sbom_aosp_cf_x86_64_phone
+ ;;
+ module_arm64)
+ test_sbom_unbundled_apex
+ test_sbom_unbundled_apk
+ ;;
+ *)
+ echo "Unknown TARGET_PRODUCT: $target_product"
+ exit 1
+ ;;
+esac
\ No newline at end of file
diff --git a/tests/symlinks_path_test.sh b/tests/symlinks_path_test.sh
new file mode 100755
index 0000000..ed42911
--- /dev/null
+++ b/tests/symlinks_path_test.sh
@@ -0,0 +1,51 @@
+#!/bin/bash -eu
+
+set -o pipefail
+
+# Test that relative symlinks work by recreating the bug in b/259191764
+# In some cases, developers prefer to move their checkouts. This causes
+# issues in that symlinked files (namely, the bazel wrapper script)
+# cannot be found. As such, we implemented relative symlinks so that a
+# moved checkout doesn't need a full clean before rebuilding.
+# The bazel output base will still need to be removed, as Starlark
+# doesn't seem to support relative symlinks yet.
+
+source "$(dirname "$0")/lib.sh"
+
+function check_link_has_mock_top_prefix {
+ input_link=$1
+ link_target=`readlink $input_link`
+ if [[ $link_target != "$MOCK_TOP"* ]]; then
+ echo "Symlink for file $input_link -> $link_target doesn't start with $MOCK_TOP"
+ exit 1
+ fi
+}
+
+function test_symlinks_updated_when_top_dir_changed {
+ setup
+
+ mkdir -p a
+ touch a/g.txt
+ cat > a/Android.bp <<'EOF'
+filegroup {
+ name: "g",
+ srcs: ["g.txt"],
+ bazel_module: {bp2build_available: true},
+}
+EOF
+ # A directory under $MOCK_TOP
+ outdir=out2
+
+ # Modify OUT_DIR in a subshell so it doesn't affect the top level one.
+ (export OUT_DIR=$MOCK_TOP/$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
+
+ g_txt="out2/soong/workspace/a/g.txt"
+ check_link_has_mock_top_prefix "$g_txt"
+
+ move_mock_top
+
+ (export OUT_DIR=$MOCK_TOP/$outdir; run_soong bp2build && run_bazel build --config=bp2build --config=ci //a:g)
+ check_link_has_mock_top_prefix "$g_txt"
+}
+
+scan_and_run_tests
\ No newline at end of file
diff --git a/ui/build/build.go b/ui/build/build.go
index 14d23a7..9d5c330 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -15,11 +15,13 @@
package build
import (
+ "fmt"
"io/ioutil"
"os"
"path/filepath"
"sync"
"text/template"
+ "time"
"android/soong/ui/metrics"
)
@@ -29,6 +31,7 @@
func SetupOutDir(ctx Context, config Config) {
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "Android.mk"))
ensureEmptyFileExists(ctx, filepath.Join(config.OutDir(), "CleanSpec.mk"))
+ ensureEmptyDirectoriesExist(ctx, config.TempDir())
// Potentially write a marker file for whether kati is enabled. This is used by soong_build to
// potentially run the AndroidMk singleton and postinstall commands.
@@ -56,6 +59,31 @@
} else {
ctx.Fatalln("Missing BUILD_DATETIME_FILE")
}
+
+ // BUILD_NUMBER should be set to the source control value that
+ // represents the current state of the source code. E.g., a
+ // perforce changelist number or a git hash. Can be an arbitrary string
+ // (to allow for source control that uses something other than numbers),
+ // but must be a single word and a valid file name.
+ //
+ // If no BUILD_NUMBER is set, create a useful "I am an engineering build
+ // from this date/time" value. Make it start with a non-digit so that
+ // anyone trying to parse it as an integer will probably get "0".
+ buildNumber, ok := config.environ.Get("BUILD_NUMBER")
+ if ok {
+ writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber)
+ } else {
+ var username string
+ if username, ok = config.environ.Get("BUILD_USERNAME"); !ok {
+ ctx.Fatalln("Missing BUILD_USERNAME")
+ }
+ buildNumber = fmt.Sprintf("eng.%.6s.%s", username, time.Now().Format("20060102.150405" /* YYYYMMDD.HHMMSS */))
+ writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
+ }
+ // Write the build number to a file so it can be read back in
+ // without changing the command line every time. Avoids rebuilds
+ // when using ninja.
+ writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
}
var combinedBuildNinjaTemplate = template.Must(template.New("combined").Parse(`
@@ -246,8 +274,6 @@
// checkCaseSensitivity issues a warning if a case-insensitive file system is being used.
checkCaseSensitivity(ctx, config)
- ensureEmptyDirectoriesExist(ctx, config.TempDir())
-
SetupPath(ctx, config)
what := evaluateWhatToRun(config, ctx.Verboseln)
diff --git a/ui/build/config.go b/ui/build/config.go
index 084d28d..f80868c 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -22,6 +22,7 @@
"math/rand"
"os"
"os/exec"
+ "os/user"
"path/filepath"
"runtime"
"strconv"
@@ -455,6 +456,16 @@
ret.environ.Set("BUILD_DATETIME_FILE", buildDateTimeFile)
+ if _, ok := ret.environ.Get("BUILD_USERNAME"); !ok {
+ username := "unknown"
+ if u, err := user.Current(); err == nil {
+ username = u.Username
+ } else {
+ ctx.Println("Failed to get current user:", err)
+ }
+ ret.environ.Set("BUILD_USERNAME", username)
+ }
+
if ret.UseRBE() {
for k, v := range getRBEVars(ctx, Config{ret}) {
ret.environ.Set(k, v)
diff --git a/ui/build/kati.go b/ui/build/kati.go
index aea56d3..31e7440 100644
--- a/ui/build/kati.go
+++ b/ui/build/kati.go
@@ -15,6 +15,8 @@
package build
import (
+ "android/soong/ui/metrics"
+ "android/soong/ui/status"
"crypto/md5"
"fmt"
"io/ioutil"
@@ -22,10 +24,6 @@
"os/user"
"path/filepath"
"strings"
- "time"
-
- "android/soong/ui/metrics"
- "android/soong/ui/status"
)
var spaceSlashReplacer = strings.NewReplacer("/", "_", " ", "_")
@@ -198,32 +196,14 @@
}
}
writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_hostname.txt", hostname)
-
- // BUILD_NUMBER should be set to the source control value that
- // represents the current state of the source code. E.g., a
- // perforce changelist number or a git hash. Can be an arbitrary string
- // (to allow for source control that uses something other than numbers),
- // but must be a single word and a valid file name.
- //
- // If no BUILD_NUMBER is set, create a useful "I am an engineering build
- // from this date/time" value. Make it start with a non-digit so that
- // anyone trying to parse it as an integer will probably get "0".
- cmd.Environment.Unset("HAS_BUILD_NUMBER")
- buildNumber, ok := cmd.Environment.Get("BUILD_NUMBER")
+ _, ok = cmd.Environment.Get("BUILD_NUMBER")
// Unset BUILD_NUMBER during kati run to avoid kati rerun, kati will use BUILD_NUMBER from a file.
cmd.Environment.Unset("BUILD_NUMBER")
if ok {
cmd.Environment.Set("HAS_BUILD_NUMBER", "true")
- writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", buildNumber)
} else {
- buildNumber = fmt.Sprintf("eng.%.6s.%s", username, time.Now().Format("20060102.150405" /* YYYYMMDD.HHMMSS */))
cmd.Environment.Set("HAS_BUILD_NUMBER", "false")
- writeValueIfChanged(ctx, config, config.OutDir(), "file_name_tag.txt", username)
}
- // Write the build number to a file so it can be read back in
- // without changing the command line every time. Avoids rebuilds
- // when using ninja.
- writeValueIfChanged(ctx, config, config.SoongOutDir(), "build_number.txt", buildNumber)
// Apply the caller's function closure to mutate the environment variables.
envFunc(cmd.Environment)
diff --git a/ui/build/soong.go b/ui/build/soong.go
index 44c20a0..ac9bf3a 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -16,10 +16,13 @@
import (
"fmt"
+ "io/fs"
"os"
"path/filepath"
"strconv"
"strings"
+ "sync"
+ "sync/atomic"
"android/soong/bazel"
"android/soong/ui/metrics"
@@ -50,6 +53,13 @@
bootstrapEpoch = 1
)
+var (
+ // Used during parallel update of symlinks in out directory to reflect new
+ // TOP dir.
+ symlinkWg sync.WaitGroup
+ numFound, numUpdated uint32
+)
+
func writeEnvironmentFile(_ Context, envFile string, envDeps map[string]string) error {
data, err := shared.EnvFileContents(envDeps)
if err != nil {
@@ -465,10 +475,118 @@
}
}
+func updateSymlinks(ctx Context, dir, prevCWD, cwd string) error {
+ defer symlinkWg.Done()
+
+ visit := func(path string, d fs.DirEntry, err error) error {
+ if d.IsDir() && path != dir {
+ symlinkWg.Add(1)
+ go updateSymlinks(ctx, path, prevCWD, cwd)
+ return filepath.SkipDir
+ }
+ f, err := d.Info()
+ if err != nil {
+ return err
+ }
+ // If the file is not a symlink, we don't have to update it.
+ if f.Mode()&os.ModeSymlink != os.ModeSymlink {
+ return nil
+ }
+
+ atomic.AddUint32(&numFound, 1)
+ target, err := os.Readlink(path)
+ if err != nil {
+ return err
+ }
+ if strings.HasPrefix(target, prevCWD) &&
+ (len(target) == len(prevCWD) || target[len(prevCWD)] == '/') {
+ target = filepath.Join(cwd, target[len(prevCWD):])
+ if err := os.Remove(path); err != nil {
+ return err
+ }
+ if err := os.Symlink(target, path); err != nil {
+ return err
+ }
+ atomic.AddUint32(&numUpdated, 1)
+ }
+ return nil
+ }
+
+ if err := filepath.WalkDir(dir, visit); err != nil {
+ return err
+ }
+ return nil
+}
+
+func fixOutDirSymlinks(ctx Context, config Config, outDir string) error {
+ cwd, err := os.Getwd()
+ if err != nil {
+ return err
+ }
+
+ // Record the .top as the very last thing in the function.
+ tf := filepath.Join(outDir, ".top")
+ defer func() {
+ if err := os.WriteFile(tf, []byte(cwd), 0644); err != nil {
+ fmt.Fprintf(os.Stderr, fmt.Sprintf("Unable to log CWD: %v", err))
+ }
+ }()
+
+ // Find the previous working directory if it was recorded.
+ var prevCWD string
+ pcwd, err := os.ReadFile(tf)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // No previous working directory recorded, nothing to do.
+ return nil
+ }
+ return err
+ }
+ prevCWD = strings.Trim(string(pcwd), "\n")
+
+ if prevCWD == cwd {
+ // We are in the same source dir, nothing to update.
+ return nil
+ }
+
+ symlinkWg.Add(1)
+ if err := updateSymlinks(ctx, outDir, prevCWD, cwd); err != nil {
+ return err
+ }
+ symlinkWg.Wait()
+ ctx.Println(fmt.Sprintf("Updated %d/%d symlinks in dir %v", numUpdated, numFound, outDir))
+ return nil
+}
+
+func migrateOutputSymlinks(ctx Context, config Config) error {
+ // Figure out the real out directory ("out" could be a symlink).
+ outDir := config.OutDir()
+ s, err := os.Lstat(outDir)
+ if err != nil {
+ if os.IsNotExist(err) {
+ // No out dir exists, no symlinks to migrate.
+ return nil
+ }
+ return err
+ }
+ if s.Mode()&os.ModeSymlink == os.ModeSymlink {
+ target, err := filepath.EvalSymlinks(outDir)
+ if err != nil {
+ return err
+ }
+ outDir = target
+ }
+ return fixOutDirSymlinks(ctx, config, outDir)
+}
+
func runSoong(ctx Context, config Config) {
ctx.BeginTrace(metrics.RunSoong, "soong")
defer ctx.EndTrace()
+ if err := migrateOutputSymlinks(ctx, config); err != nil {
+ ctx.Fatalf("failed to migrate output directory to current TOP dir: %v", err)
+ }
+
// We have two environment files: .available is the one with every variable,
// .used with the ones that were actually used. The latter is used to
// determine whether Soong needs to be re-run since why re-run it if only