From 07ace6f55fb7348d64c42d365c4509378b4fde09 Mon Sep 17 00:00:00 2001 From: Prasanna Swaminathan Date: Thu, 26 Dec 2024 15:47:27 -0500 Subject: [PATCH 1/7] [databinding] Use symlinks for databinding copy_{file,dir} functions As illustrated in #223, BSD `cp` does not support `--reflink=auto` flag. These functions are only used in the data binding rules, so we can actually just remove them. Instead, we can use symlinks in the data binding actions. n.b. Solely replacing the calls with symlinks and leaving the originals is something I'm not entirely opposed to. I do think it is a bad idea, however, because it is not cross-platform-compatible. It leaves the door open for future usages to call these copy functions and break things downstream for non-Linux users. However, if reverting utils.bzl is the only way to get this merged in, I'll do it. stacked-branch: databinding-symlinks --- rules/data_binding.bzl | 14 ++++++++++---- rules/utils.bzl | 4 ++-- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/rules/data_binding.bzl b/rules/data_binding.bzl index 9039cba35..3dbc1dded 100644 --- a/rules/data_binding.bzl +++ b/rules/data_binding.bzl @@ -54,7 +54,7 @@ def _copy_annotation_file(ctx, output_dir, annotation_template): annotation_out = ctx.actions.declare_file( output_dir + "/android/databinding/layouts/DataBindingInfo.java", ) - _utils.copy_file(ctx, annotation_template, annotation_out) + ctx.actions.symlink(output = annotation_out, target_file = annotation_template) return annotation_out def _gen_sources(ctx, output_dir, java_package, deps, layout_info, data_binding_exec): @@ -117,9 +117,15 @@ def _setup_dependent_lib_artifacts(ctx, output_dir, deps): path = artifact.short_path if path.startswith("../"): path = path[3:] - dep_lib_artifact = ctx.actions.declare_file( - output_dir + "dependent-lib-artifacts/" + path, - ) + dep_lib_artifact_path = output_dir + "dependent-lib-artifacts/" + path + if artifact.is_directory: + dep_lib_artifact = ctx.actions.declare_directory( + output_dir + "dependent-lib-artifacts/" + path, + ) + else: + dep_lib_artifact = ctx.actions.declare_file( + output_dir + "dependent-lib-artifacts/" + path, + ) # Copy file to a location required by the DataBinding annotation # processor. diff --git a/rules/utils.bzl b/rules/utils.bzl index d0f5b555d..2e4d3c080 100644 --- a/rules/utils.bzl +++ b/rules/utils.bzl @@ -212,7 +212,7 @@ def _copy_file(ctx, src, dest): if src.is_directory or dest.is_directory: fail("Cannot use copy_file with directories") ctx.actions.run_shell( - command = "cp --reflink=auto $1 $2", + command = "cp $1 $2", arguments = [src.path, dest.path], inputs = [src], outputs = [dest], @@ -224,7 +224,7 @@ def _copy_dir(ctx, src, dest): if not src.is_directory: fail("copy_dir src must be a directory") ctx.actions.run_shell( - command = "cp -r --reflink=auto $1 $2", + command = "cp -r $1 $2", arguments = [src.path, dest.path], inputs = [src], outputs = [dest], From b591c072f40c0797a7d9b8e61749b3d9a9fffc87 Mon Sep 17 00:00:00 2001 From: Prasanna Swaminathan Date: Tue, 4 Mar 2025 16:32:20 -0500 Subject: [PATCH 2/7] [databinding] Include other necessary prefixes in databinding_exec.jar Without these prefixes, `StarlarkProcessDatabinding` fails with errors about missing classes. These are all embedded in android_tools.jar, but don't get pulled into the final jar. ``` ERROR: /Users/p/Code/bazel/rules_android/examples/databinding/java/com/basicapp/BUILD:10:16: Processing data binding failed: (Exit 1): java failed: error executing StarlarkProcessDatabinding command (from target //java/com/basicapp:basic_lib) (cd /private/var/tmp/_bazel_p/828537623772ec0b3f803c69d3e68e34/sandbox/darwin-sandbox/211/execroot/_main && \ exec env - \ external/rules_java~~toolchains~remotejdk11_macos_aarch64/bin/java -Xms4G -Xmx4G -XX:+ExitOnOutOfMemoryError -jar bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_android~/src/tools/java/com/google/devtools/build/android/ResourceProcessorBusyBox_deploy.jar --tool PROCESS_DATABINDING -- --output_resource_directory bazel-out/darwin_arm64-fastbuild-android-ST-80dd4ae33d52/bin/java/com/basicapp/Databinding-processed-resources/basic_lib --resource_root java/com/basicapp/res --dataBindingInfoOut bazel-out/darwin_arm64-fastbuild-android-ST-80dd4ae33d52/bin/java/com/basicapp/databinding/basic_lib/layout-info.zip --appId com.basicapp --useDataBindingAndroidX true) Use --sandbox_debug to see verbose messages from the sandbox and retain the sandbox build root for debugging Dec 26, 2024 4:38:32 PM com.google.devtools.build.android.ResourceProcessorBusyBox processRequest SEVERE: Error during processing java.lang.RuntimeException: java.lang.NoClassDefFoundError: org/antlr/v4/runtime/ParserRuleContext at com.google.devtools.build.android.AndroidResourceProcessor.processDataBindings(AndroidResourceProcessor.java:318) at com.google.devtools.build.android.AndroidDataBindingProcessingAction.main(AndroidDataBindingProcessingAction.java:113) at com.google.devtools.build.android.ResourceProcessorBusyBox$Tool$13.call(ResourceProcessorBusyBox.java:140) at com.google.devtools.build.android.ResourceProcessorBusyBox.processRequest(ResourceProcessorBusyBox.java:238) at com.google.devtools.build.android.ResourceProcessorBusyBox.main(ResourceProcessorBusyBox.java:175) Caused by: java.lang.NoClassDefFoundError: org/antlr/v4/runtime/ParserRuleContext at android.databinding.tool.LayoutXmlProcessor.(LayoutXmlProcessor.java:52) at android.databinding.AndroidDataBinding.createXmlProcessor(AndroidDataBinding.kt:188) at android.databinding.AndroidDataBinding.processResources(AndroidDataBinding.kt:113) at android.databinding.AndroidDataBinding.doRun(AndroidDataBinding.kt:107) at com.google.devtools.build.android.AndroidDataBindingWrapper.doRun(AndroidDataBindingWrapper.java:33) at com.google.devtools.build.android.AndroidResourceProcessor.processDataBindings(AndroidResourceProcessor.java:316) ... 4 more Caused by: java.lang.ClassNotFoundException: org.antlr.v4.runtime.ParserRuleContext at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527) ... 10 more Exception in thread "main" java.lang.RuntimeException: java.lang.NoClassDefFoundError: org/antlr/v4/runtime/ParserRuleContext at com.google.devtools.build.android.AndroidResourceProcessor.processDataBindings(AndroidResourceProcessor.java:318) at com.google.devtools.build.android.AndroidDataBindingProcessingAction.main(AndroidDataBindingProcessingAction.java:113) at com.google.devtools.build.android.ResourceProcessorBusyBox$Tool$13.call(ResourceProcessorBusyBox.java:140) at com.google.devtools.build.android.ResourceProcessorBusyBox.processRequest(ResourceProcessorBusyBox.java:238) at com.google.devtools.build.android.ResourceProcessorBusyBox.main(ResourceProcessorBusyBox.java:175) Caused by: java.lang.NoClassDefFoundError: org/antlr/v4/runtime/ParserRuleContext at android.databinding.tool.LayoutXmlProcessor.(LayoutXmlProcessor.java:52) at android.databinding.AndroidDataBinding.createXmlProcessor(AndroidDataBinding.kt:188) at android.databinding.AndroidDataBinding.processResources(AndroidDataBinding.kt:113) at android.databinding.AndroidDataBinding.doRun(AndroidDataBinding.kt:107) at com.google.devtools.build.android.AndroidDataBindingWrapper.doRun(AndroidDataBindingWrapper.java:33) at com.google.devtools.build.android.AndroidResourceProcessor.processDataBindings(AndroidResourceProcessor.java:316) ... 4 more Caused by: java.lang.ClassNotFoundException: org.antlr.v4.runtime.ParserRuleContext at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:527) ... 10 more options ProcessXmlOptions{appId='com.basicapp', resInput=java/com/basicapp/res, resOutput=bazel-out/darwin_arm64-fastbuild-android-ST-80dd4ae33d52/bin/java/com/basicapp/Databinding-processed-resources/basic_lib/java/com/basicapp/res, layoutInfoOutput=/var/folders/mn/gbs17z997jvgrk53m0g2fgrh0000gn/T/android_data_binding_layout_info_tmp3836744348019465023, zipLayoutInfo=false, useAndroidX=true, enableDebugLogs=false} Target //java/com/basicapp:basic_app failed to build ERROR: /Users/p/Code/bazel/rules_android/examples/databinding/java/com/basicapp/BUILD:10:16 Compiling Android Resources in java/com/basicapp/basic_lib_symbols/symbols.zip failed: (Exit 1): java failed: error executing StarlarkProcessDatabinding command (from target //java/com/basicapp:basic_lib) (cd /private/var/tmp/_bazel_p/828537623772ec0b3f803c69d3e68e34/sandbox/darwin-sandbox/211/execroot/_main && \ exec env - \ external/rules_java~~toolchains~remotejdk11_macos_aarch64/bin/java -Xms4G -Xmx4G -XX:+ExitOnOutOfMemoryError -jar bazel-out/darwin_arm64-opt-exec-ST-d57f47055a04/bin/external/rules_android~/src/tools/java/com/google/devtools/build/android/ResourceProcessorBusyBox_deploy.jar --tool PROCESS_DATABINDING -- --output_resource_directory bazel-out/darwin_arm64-fastbuild-android-ST-80dd4ae33d52/bin/java/com/basicapp/Databinding-processed-resources/basic_lib --resource_root java/com/basicapp/res --dataBindingInfoOut bazel-out/darwin_arm64-fastbuild-android-ST-80dd4ae33d52/bin/java/com/basicapp/databinding/basic_lib/layout-info.zip --appId com.basicapp --useDataBindingAndroidX true) ``` stacked-branch: databinding_exec_jar-fixes --- .../com/google/devtools/build/android/BUILD | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/tools/java/com/google/devtools/build/android/BUILD b/src/tools/java/com/google/devtools/build/android/BUILD index 2fe7d4136..e54576089 100644 --- a/src/tools/java/com/google/devtools/build/android/BUILD +++ b/src/tools/java/com/google/devtools/build/android/BUILD @@ -59,6 +59,26 @@ run_singlejar( out = "databinding_exec.jar", include_prefixes = [ "android/databinding/", + "androidx/databinding/", + "api-versions.xml", + "com/android/tools/build/", + "com/beust/jcommander/", + "com/google/auto/common/", + "com/google/common/base/", + "com/google/common/collect/", + "com/google/common/primitives/", + "com/google/gson/", + "com/squareup/javapoet/", + "com/sun/istack/", + "com/sun/xml/", + "default.generated.config", + "javax/activation/", + "javax/xml/", + "kotlin/", + "org/antlr/v4/", + "org/apache/commons/io/", + "org/objectweb/asm", + "org/mozilla/universalchardet/", ], ) From f74aebac6c6d35dbc43d2ee929fe4b53af99a79d Mon Sep 17 00:00:00 2001 From: Prasanna Swaminathan Date: Wed, 5 Mar 2025 16:22:52 -0500 Subject: [PATCH 3/7] [databinding] Fix databinding templates and resources for AndroidX This adds a flag for AndroidX and wires it through to the processing steps. Additionally, the shell command run to fix databinding compiled resources was not cross-platform: * BSD `head` won't take a negative int as its argument (GNU does). The better way to accomplish this goal here (listing all files in the archive) is just to use `zipinfo(1)`. `zipinfo -1` shows in its man page to be intended for exactly this purpose. * BSD `sed` requires passsing an argument to the `-i` flag for a file extension to use when writing a back-up. A file without a back-up must be explicitly signaled by using an empty argument, i.e. `sed -i '' file`. However, a spaced argument to `-i` on GNU sed is interpreted as the next positional argument to `sed`, which is an error. The only cross-platform way to accomplish this appears to be to combine it into one like `-i.bak`. This then needs to be removed. (From [StackOverflow](https://stackoverflow.com/a/22084103/1819790)) * Using `sed` to change a string in an otherwise binary file may require changing the localization variables. At least, it does on standard BSD/macOS: otherwise, `sed` assumes files are encoded as text, and the class files contain invalid bytes. `LC_ALL` overrides all categories not set. --- .bazelrc | 3 ++- rules/BUILD | 3 ++- rules/android_binary/attrs.bzl | 3 +++ rules/android_binary/impl.bzl | 10 ++++++++-- rules/android_library/attrs.bzl | 3 +++ rules/android_library/impl.bzl | 11 +++++++++-- rules/busybox.bzl | 2 ++ rules/data_binding.bzl | 7 ++++--- rules/data_binding_annotation_template_androidx.txt | 13 +++++++++++++ ...ata_binding_annotation_template_support_lib.txt} | 0 rules/flags/additional_flags.bzl | 10 ++++++++-- rules/resources.bzl | 5 +++-- .../build/android/AndroidResourceProcessor.java | 2 +- toolchains/android/toolchain.bzl | 8 ++++++-- 14 files changed, 64 insertions(+), 16 deletions(-) create mode 100644 rules/data_binding_annotation_template_androidx.txt rename rules/{data_binding_annotation_template.txt => data_binding_annotation_template_support_lib.txt} (100%) diff --git a/.bazelrc b/.bazelrc index 941c20361..1f1d54c5a 100644 --- a/.bazelrc +++ b/.bazelrc @@ -1 +1,2 @@ -common --java_runtime_version=17 +common --java_runtime_version=remotejdk_17 +common --tool_java_runtime_version=remotejdk_17 diff --git a/rules/BUILD b/rules/BUILD index 502bc94b3..faabccf23 100644 --- a/rules/BUILD +++ b/rules/BUILD @@ -3,7 +3,8 @@ load("@bazel_skylib//rules:common_settings.bzl", "int_setting") load("@rules_java//java:defs.bzl", "java_library") exports_files([ - "data_binding_annotation_template.txt", + "data_binding_annotation_template_androidx.txt", + "data_binding_annotation_template_support_lib.txt", "res_v3_dummy_AndroidManifest.xml", "res_v3_dummy_R.txt", "robolectric_properties_template.txt", diff --git a/rules/android_binary/attrs.bzl b/rules/android_binary/attrs.bzl index bc7512aa7..cbf5c005d 100644 --- a/rules/android_binary/attrs.bzl +++ b/rules/android_binary/attrs.bzl @@ -247,6 +247,9 @@ ATTRS = _attrs.replace( Allow for the optimizer to process resources. This is not supported in proguard. """, ), + _databinding_use_androidx = attr.label( + default = "//rules/flags:databinding_use_androidx", + ), ), _attrs.compilation_attributes(apply_android_transition = True), _attrs.DATA_CONTEXT, diff --git a/rules/android_binary/impl.bzl b/rules/android_binary/impl.bzl index d6ee4bb5e..96f07aa6f 100644 --- a/rules/android_binary/impl.bzl +++ b/rules/android_binary/impl.bzl @@ -188,6 +188,13 @@ def _process_proto(_unused_ctx, **_unused_ctxs): def _process_data_binding(ctx, java_package, packaged_resources_ctx, **_unused_ctxs): if ctx.attr.enable_data_binding and not acls.in_databinding_allowed(str(ctx.label)): fail("This target is not allowed to use databinding and enable_data_binding is True.") + + if ctx.attr._databinding_use_androidx[BuildSettingInfo].value: + template = get_android_toolchain(ctx).data_binding_annotation_template_androidx + else: + template = get_android_toolchain(ctx).data_binding_annotation_template_support_lib + data_binding_annotation_template = utils.only(template.files.to_list()) + return ProviderInfo( name = "db_ctx", value = data_binding.process( @@ -201,8 +208,7 @@ def _process_data_binding(ctx, java_package, packaged_resources_ctx, **_unused_c data_binding_exec = get_android_toolchain(ctx).data_binding_exec.files_to_run, data_binding_annotation_processor = get_android_toolchain(ctx).data_binding_annotation_processor[JavaPluginInfo], - data_binding_annotation_template = - utils.only(get_android_toolchain(ctx).data_binding_annotation_template.files.to_list()), + data_binding_annotation_template = data_binding_annotation_template, ), ) diff --git a/rules/android_library/attrs.bzl b/rules/android_library/attrs.bzl index f9ccc2a2c..44911e40b 100644 --- a/rules/android_library/attrs.bzl +++ b/rules/android_library/attrs.bzl @@ -243,6 +243,9 @@ ATTRS = _attrs.add( _aidl_lib = attr.label( default = Label("//rules:aidl_lib"), ), + _databinding_use_androidx = attr.label( + default = "//rules/flags:databinding_use_androidx", + ), ), _attrs.compilation_attributes(), _attrs.DATA_CONTEXT, diff --git a/rules/android_library/impl.bzl b/rules/android_library/impl.bzl index b2daed512..d1a4a7c3e 100644 --- a/rules/android_library/impl.bzl +++ b/rules/android_library/impl.bzl @@ -31,6 +31,7 @@ load("//rules:resources.bzl", _resources = "resources") load("//rules:utils.bzl", "get_android_sdk", "get_android_toolchain", "log", "utils") load("//rules:visibility.bzl", "PROJECT_VISIBILITY") load("//rules/flags:flags.bzl", _flags = "flags") +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("@rules_java//java/common:java_info.bzl", "JavaInfo") load("@rules_java//java/common:java_plugin_info.bzl", "JavaPluginInfo") load("@rules_java//java/common:proguard_spec_info.bzl", "ProguardSpecInfo") @@ -234,6 +235,13 @@ def _process_idl(ctx, **unused_sub_ctxs): def _process_data_binding(ctx, java_package, resources_ctx, **unused_sub_ctxs): if ctx.attr.enable_data_binding and not acls.in_databinding_allowed(str(ctx.label)): fail("This target is not allowed to use databinding and enable_data_binding is True.") + + if ctx.attr._databinding_use_androidx[BuildSettingInfo].value: + template = get_android_toolchain(ctx).data_binding_annotation_template_androidx + else: + template = get_android_toolchain(ctx).data_binding_annotation_template_support_lib + data_binding_annotation_template = utils.only(template.files.to_list()) + return ProviderInfo( name = "db_ctx", value = _data_binding.process( @@ -247,8 +255,7 @@ def _process_data_binding(ctx, java_package, resources_ctx, **unused_sub_ctxs): data_binding_exec = get_android_toolchain(ctx).data_binding_exec.files_to_run, data_binding_annotation_processor = get_android_toolchain(ctx).data_binding_annotation_processor, - data_binding_annotation_template = - utils.only(get_android_toolchain(ctx).data_binding_annotation_template.files.to_list()), + data_binding_annotation_template = data_binding_annotation_template, ), ) diff --git a/rules/busybox.bzl b/rules/busybox.bzl index 2c3ececfc..a57c6cc09 100644 --- a/rules/busybox.bzl +++ b/rules/busybox.bzl @@ -13,6 +13,7 @@ # limitations under the License. """Bazel ResourcesBusyBox Commands.""" +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("//rules:visibility.bzl", "PROJECT_VISIBILITY") load(":java.bzl", _java = "java") @@ -978,6 +979,7 @@ def _process_databinding( args.add_all(res_dirs, before_each = "--resource_root") args.add("--dataBindingInfoOut", out_databinding_info) args.add("--appId", java_package) + args.add("--useDataBindingAndroidX", ctx.attr._databinding_use_androidx[BuildSettingInfo].value) _set_warning_level(ctx, args) diff --git a/rules/data_binding.bzl b/rules/data_binding.bzl index 3dbc1dded..7324477a7 100644 --- a/rules/data_binding.bzl +++ b/rules/data_binding.bzl @@ -13,6 +13,7 @@ # limitations under the License. """Bazel Android Data Binding.""" +load("@bazel_skylib//rules:common_settings.bzl", "BuildSettingInfo") load("//providers:providers.bzl", "DataBindingV2Info") load("//rules:visibility.bzl", "PROJECT_VISIBILITY") load(":utils.bzl", "ANDROID_TOOLCHAIN_TYPE", _utils = "utils") @@ -67,7 +68,7 @@ def _gen_sources(ctx, output_dir, java_package, deps, layout_info, data_binding_ args.add("-classInfoOut", class_info) args.add("-sourceOut", srcjar) args.add("-zipSourceOutput", "true") - args.add("-useAndroidX", "false") + args.add("-useAndroidX", ctx.attr._databinding_use_androidx[BuildSettingInfo].value) if deps: if type(deps[0].class_infos) == "depset": @@ -260,11 +261,11 @@ def _process( if defines_resources: # Outputs of the Data Binding annotation processor. br_out = ctx.actions.declare_file( - output_dir + "bin-files/%s-br.bin" % java_package, + output_dir + "bin-files/%s--br.bin" % java_package, ) db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS].append(br_out) setter_store_out = ctx.actions.declare_file( - output_dir + "bin-files/%s-setter_store.json" % java_package, + output_dir + "bin-files/%s--setter_store.json" % java_package, ) db_info[_JAVA_ANNOTATION_PROCESSOR_ADDITIONAL_OUTPUTS].append( setter_store_out, diff --git a/rules/data_binding_annotation_template_androidx.txt b/rules/data_binding_annotation_template_androidx.txt new file mode 100644 index 000000000..6625f5254 --- /dev/null +++ b/rules/data_binding_annotation_template_androidx.txt @@ -0,0 +1,13 @@ +package android.databinding.layouts; + +import androidx.databinding.BindingBuildInfo; + +/** + * Template for the file that feeds data binding's annotation processor. The + * processor reads the values set here to generate .java files that link XML + * data binding declarations (from layoutInfoDir) to app code. + */ +@BindingBuildInfo +public class DataBindingInfo { + /* This only exists for annotation processing. */ +} diff --git a/rules/data_binding_annotation_template.txt b/rules/data_binding_annotation_template_support_lib.txt similarity index 100% rename from rules/data_binding_annotation_template.txt rename to rules/data_binding_annotation_template_support_lib.txt diff --git a/rules/flags/additional_flags.bzl b/rules/flags/additional_flags.bzl index 687ff9f00..c7481021d 100644 --- a/rules/flags/additional_flags.bzl +++ b/rules/flags/additional_flags.bzl @@ -13,7 +13,7 @@ # limitations under the License. """Additional flag definitions.""" -load("@bazel_skylib//rules:common_settings.bzl", "string_flag") +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "string_flag") def additional_flags(): @@ -28,4 +28,10 @@ def additional_flags(): "dependency", ], visibility = ["//visibility:public"], - ) \ No newline at end of file + ) + + bool_flag( + name = "databinding_use_androidx", + build_setting_default = False, + visibility = ["//visibility:public"], + ) diff --git a/rules/resources.bzl b/rules/resources.bzl index 8c1e90d9a..04afdb921 100644 --- a/rules/resources.bzl +++ b/rules/resources.bzl @@ -381,7 +381,7 @@ OUT_DIR=$(mktemp -d) CUR_PWD=$(pwd) if zipinfo -t "$1"; then - ORDERED_LIST=`(unzip -l "$1" | sed -e '1,3d' | head -n -2 | tr -s " " | cut -d " " -f5)` + ORDERED_LIST=`(zipinfo -1 "$1" | sort)` unzip -q "$1" -d "$IN_DIR" @@ -390,7 +390,8 @@ if zipinfo -t "$1"; then for FILE in $ORDERED_LIST; do cd "$IN_DIR" if [ -f "$FILE" ]; then - sed -i 's/Databinding\\-processed\\-resources/databinding\\-processed\\-resources/g' "$FILE" + LC_ALL=C sed -i.bak 's/Databinding\\-processed\\-resources/databinding\\-processed\\-resources/g' "$FILE" + rm "${FILE}.bak" NEW_NAME=`echo "$FILE" | sed 's/Databinding\\-processed\\-resources/databinding\\-processed\\-resources/g' | sed 's#'"$IN_DIR"'/##g'` mkdir -p `dirname "$OUT_DIR/$NEW_NAME"` && touch "$OUT_DIR/$NEW_NAME" cp -p "$FILE" "$OUT_DIR/$NEW_NAME" diff --git a/src/tools/java/com/google/devtools/build/android/AndroidResourceProcessor.java b/src/tools/java/com/google/devtools/build/android/AndroidResourceProcessor.java index b0f0d4b45..830bfa372 100644 --- a/src/tools/java/com/google/devtools/build/android/AndroidResourceProcessor.java +++ b/src/tools/java/com/google/devtools/build/android/AndroidResourceProcessor.java @@ -305,7 +305,7 @@ static Path processDataBindings( ProcessXmlOptionsWrapper options = new ProcessXmlOptionsWrapper(); options.setAppId(packagePath); - options.setResInput(inputResourcesDir.toFile()); + options.setResInput(inputResourcesDir.toFile().getAbsoluteFile()); options.setResOutput(processedResourceDir.toFile()); options.setLayoutInfoOutput(dataBindingInfoOut.toFile()); options.setUseAndroidX(useDataBindingAndroidX); diff --git a/toolchains/android/toolchain.bzl b/toolchains/android/toolchain.bzl index 7e42cd49b..524682f89 100644 --- a/toolchains/android/toolchain.bzl +++ b/toolchains/android/toolchain.bzl @@ -112,8 +112,12 @@ _ATTRS = dict( cfg = "exec", default = "//tools/android:compiler_annotation_processor", ), - data_binding_annotation_template = attr.label( - default = "//rules:data_binding_annotation_template.txt", + data_binding_annotation_template_androidx = attr.label( + default = "//rules:data_binding_annotation_template_androidx.txt", + allow_files = True, + ), + data_binding_annotation_template_support_lib = attr.label( + default = "//rules:data_binding_annotation_template_support_lib.txt", allow_files = True, ), data_binding_exec = attr.label( From b342df8f0cbdfc273e8ff7fde19f3178c9aa36b6 Mon Sep 17 00:00:00 2001 From: Prasanna Swaminathan Date: Wed, 5 Mar 2025 12:32:28 -0500 Subject: [PATCH 4/7] [databinding] Add example that builds with data binding --- examples/databinding/.bazelrc | 9 +++ examples/databinding/.gitignore | 1 + examples/databinding/BUILD | 1 + examples/databinding/MODULE.bazel | 51 +++++++++++++++ examples/databinding/README.md | 8 +++ examples/databinding/WORKSPACE | 60 ++++++++++++++++++ examples/databinding/WORKSPACE.bzlmod | 1 + .../com/databindingapp/AndroidManifest.xml | 22 +++++++ .../databinding/java/com/databindingapp/BUILD | 23 +++++++ .../DataBindingMainActivity.java | 51 +++++++++++++++ .../res/drawable-hdpi/ic_launcher.png | Bin 0 -> 1678 bytes .../res/drawable-mdpi/ic_launcher.png | Bin 0 -> 1283 bytes .../res/drawable-xhdpi/ic_launcher.png | Bin 0 -> 1817 bytes .../res/drawable-xxhdpi/ic_launcher.png | Bin 0 -> 2137 bytes .../res/layout/activity_data_binding.xml | 39 ++++++++++++ .../java/com/databindingapp/res/menu/menu.xml | 8 +++ .../com/databindingapp/res/values/dimens.xml | 5 ++ .../com/databindingapp/res/values/strings.xml | 8 +++ 18 files changed, 287 insertions(+) create mode 100644 examples/databinding/.bazelrc create mode 100644 examples/databinding/.gitignore create mode 100644 examples/databinding/BUILD create mode 100644 examples/databinding/MODULE.bazel create mode 100644 examples/databinding/README.md create mode 100644 examples/databinding/WORKSPACE create mode 100644 examples/databinding/WORKSPACE.bzlmod create mode 100644 examples/databinding/java/com/databindingapp/AndroidManifest.xml create mode 100644 examples/databinding/java/com/databindingapp/BUILD create mode 100644 examples/databinding/java/com/databindingapp/DataBindingMainActivity.java create mode 100644 examples/databinding/java/com/databindingapp/res/drawable-hdpi/ic_launcher.png create mode 100644 examples/databinding/java/com/databindingapp/res/drawable-mdpi/ic_launcher.png create mode 100644 examples/databinding/java/com/databindingapp/res/drawable-xhdpi/ic_launcher.png create mode 100644 examples/databinding/java/com/databindingapp/res/drawable-xxhdpi/ic_launcher.png create mode 100644 examples/databinding/java/com/databindingapp/res/layout/activity_data_binding.xml create mode 100644 examples/databinding/java/com/databindingapp/res/menu/menu.xml create mode 100644 examples/databinding/java/com/databindingapp/res/values/dimens.xml create mode 100644 examples/databinding/java/com/databindingapp/res/values/strings.xml diff --git a/examples/databinding/.bazelrc b/examples/databinding/.bazelrc new file mode 100644 index 000000000..d381541ae --- /dev/null +++ b/examples/databinding/.bazelrc @@ -0,0 +1,9 @@ +common:core_library_desugaring --desugar_java8_libs + +common --java_runtime_version=remotejdk_17 +common --tool_java_runtime_version=remotejdk_17 + +# Flags to enable mobile-install v3 +mobile-install --mode=skylark --mobile_install_aspect=@rules_android//mobile_install:mi.bzl --mobile_install_supported_rules=android_binary +# Required to invoke the Studio deployer jar +mobile-install --tool_java_runtime_version=17 diff --git a/examples/databinding/.gitignore b/examples/databinding/.gitignore new file mode 100644 index 000000000..63f1fef0e --- /dev/null +++ b/examples/databinding/.gitignore @@ -0,0 +1 @@ +*.lock diff --git a/examples/databinding/BUILD b/examples/databinding/BUILD new file mode 100644 index 000000000..a09fce916 --- /dev/null +++ b/examples/databinding/BUILD @@ -0,0 +1 @@ +# Empty build file to satisfy gazelle for rules_go. \ No newline at end of file diff --git a/examples/databinding/MODULE.bazel b/examples/databinding/MODULE.bazel new file mode 100644 index 000000000..d2ff2f683 --- /dev/null +++ b/examples/databinding/MODULE.bazel @@ -0,0 +1,51 @@ +module( + name = "databinding", +) + +bazel_dep(name = "rules_java", version = "7.12.2") +bazel_dep(name = "bazel_skylib", version = "1.3.0") +bazel_dep(name = "rules_jvm_external", version = "6.6") + +bazel_dep( + name = "rules_android", + version = "0.6.3", +) + +local_path_override( + module_name = "rules_android", + path = "../../", +) + +remote_android_extensions = use_extension( + "@rules_android//bzlmod_extensions:android_extensions.bzl", + "remote_android_tools_extensions") +use_repo(remote_android_extensions, "android_gmaven_r8", "android_tools") + +android_sdk_repository_extension = use_extension("@rules_android//rules/android_sdk_repository:rule.bzl", "android_sdk_repository_extension") +use_repo(android_sdk_repository_extension, "androidsdk") + +register_toolchains("@androidsdk//:sdk-toolchain", "@androidsdk//:all") + + +maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven") +maven.install( + name = "maven", + aar_import_bzl_label = "@rules_android//rules:rules.bzl", + artifacts = [ + "androidx.annotation:annotation-jvm:1.9.1", + "androidx.databinding:databinding-runtime:8.7.0", + ], + repositories = [ + "https://maven.google.com", + "https://repo1.maven.org/maven2", + "https://repo.gradle.org/gradle/libs-releases", + ], + # To generate, run: + # REPIN=1 bazelisk run --enable_bzlmod @maven//:pin + # lock_file = "//:maven_install.json", + use_starlark_android_rules = True, +) +use_repo( + maven, + "maven", +) diff --git a/examples/databinding/README.md b/examples/databinding/README.md new file mode 100644 index 000000000..183e122ed --- /dev/null +++ b/examples/databinding/README.md @@ -0,0 +1,8 @@ +To build, ensure that the `ANDROID_HOME` environment variable is set to the path +to an Android SDK, and run: + +``` +bazel build java/com/basicapp:basic_app +``` + +See the `.bazelrc` file for flags needed to build the app. \ No newline at end of file diff --git a/examples/databinding/WORKSPACE b/examples/databinding/WORKSPACE new file mode 100644 index 000000000..85827cb9e --- /dev/null +++ b/examples/databinding/WORKSPACE @@ -0,0 +1,60 @@ +local_repository( + name = "rules_android", + path = "../..", # rules_android's WORKSPACE relative to this inner workspace +) + +# --SNIP--: Everything below this line goes into the example WORKSPACE snippet in the release notes. + +# Android rules dependencies +load("@rules_android//:prereqs.bzl", "rules_android_prereqs") +rules_android_prereqs() + +##### rules_java setup for rules_android ##### +load("@rules_java//java:rules_java_deps.bzl", "rules_java_dependencies") +rules_java_dependencies() +# note that the following line is what is minimally required from protobuf for the java rules +# consider using the protobuf_deps() public API from @com_google_protobuf//:protobuf_deps.bzl +load("@com_google_protobuf//bazel/private:proto_bazel_features.bzl", "proto_bazel_features") # buildifier: disable=bzl-visibility +proto_bazel_features(name = "proto_bazel_features") +# register toolchains +load("@rules_java//java:repositories.bzl", "rules_java_toolchains") +rules_java_toolchains() + +##### rules_jvm_external setup for rules_android ##### +load("@rules_jvm_external//:repositories.bzl", "rules_jvm_external_deps") +rules_jvm_external_deps() +load("@rules_jvm_external//:setup.bzl", "rules_jvm_external_setup") +rules_jvm_external_setup() + +load("@rules_jvm_external//:defs.bzl", "maven_install") + +maven_install( + name = "maven", + artifacts = [ + "androidx.annotation:annotation-jvm:1.9.1", + "androidx.databinding:databinding-adapters:8.7.0", + "androidx.databinding:databinding-runtime:8.7.0", + "com.google.protobuf:protobuf-java:4.27.2", + "com.google.protobuf:protobuf-java-util:4.27.2", + ], + repositories = [ + "https://maven.google.com", + "https://repo1.maven.org/maven2", + "https://repo.gradle.org/gradle/libs-releases", + ], +) + +##### rules_android setup ##### +load("@rules_android//:defs.bzl", "rules_android_workspace") +rules_android_workspace() + +# Android SDK setup +load("@rules_android//rules:rules.bzl", "android_sdk_repository") +android_sdk_repository( + name = "androidsdk", +) + +register_toolchains( + "@rules_android//toolchains/android:android_default_toolchain", + "@rules_android//toolchains/android_sdk:android_sdk_tools", +) diff --git a/examples/databinding/WORKSPACE.bzlmod b/examples/databinding/WORKSPACE.bzlmod new file mode 100644 index 000000000..172da6f27 --- /dev/null +++ b/examples/databinding/WORKSPACE.bzlmod @@ -0,0 +1 @@ +workspace(name = "basicapp") diff --git a/examples/databinding/java/com/databindingapp/AndroidManifest.xml b/examples/databinding/java/com/databindingapp/AndroidManifest.xml new file mode 100644 index 000000000..19e9358df --- /dev/null +++ b/examples/databinding/java/com/databindingapp/AndroidManifest.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + diff --git a/examples/databinding/java/com/databindingapp/BUILD b/examples/databinding/java/com/databindingapp/BUILD new file mode 100644 index 000000000..8f6076b32 --- /dev/null +++ b/examples/databinding/java/com/databindingapp/BUILD @@ -0,0 +1,23 @@ +load("@rules_android//android:rules.bzl", "android_binary", "android_library") + +android_binary( + name = "databindingapp", + manifest = "AndroidManifest.xml", + enable_data_binding = True, + deps = [ + ":databinding_lib", + "@maven//:androidx_databinding_databinding_runtime", + ], +) + +android_library( + name = "databinding_lib", + srcs = ["DataBindingMainActivity.java"], + manifest = "AndroidManifest.xml", + resource_files = glob(["res/**"]), + enable_data_binding = True, + deps = [ + "@maven//:androidx_annotation_annotation_jvm", + "@maven//:androidx_databinding_databinding_runtime", + ], +) diff --git a/examples/databinding/java/com/databindingapp/DataBindingMainActivity.java b/examples/databinding/java/com/databindingapp/DataBindingMainActivity.java new file mode 100644 index 000000000..48fe1de0b --- /dev/null +++ b/examples/databinding/java/com/databindingapp/DataBindingMainActivity.java @@ -0,0 +1,51 @@ +// Copyright 2022 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.databindingapp; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.View; +import android.widget.Button; +import android.widget.TextView; +import com.databindingapp.databinding.ActivityDataBindingBinding; + +import java.util.Random; + +/** + * The main activity of the Basic Sample App. + */ +public class DataBindingMainActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + ActivityDataBindingBinding binding = ActivityDataBindingBinding.inflate(getLayoutInflater()); + + Random random = new Random(); + binding.setShowFizz(random.nextDouble() < 0.5); + binding.setShowBuzz(random.nextDouble() < 0.5); + + setContentView(binding.getRoot()); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu, menu); + return true; + } +} diff --git a/examples/databinding/java/com/databindingapp/res/drawable-hdpi/ic_launcher.png b/examples/databinding/java/com/databindingapp/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..6ab2adde210fde3d980a0d3d9c551dcf61a96a86 GIT binary patch literal 1678 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 Q1ysb~>FVdQ&MBb@0DAuQWB>pF literal 0 HcmV?d00001 diff --git a/examples/databinding/java/com/databindingapp/res/drawable-xhdpi/ic_launcher.png b/examples/databinding/java/com/databindingapp/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..014b0f1064d5d3a51451970d0bb39b954e805264 GIT binary patch literal 1817 zcmZ`&3se(l7XBj)nUGe3&>|=#C>U8Eq#%m~2zfuM;Ss=7dC5Bkwj_mtNF-rQWvi>Z zu+b_D%46NG-Lkt#6)9B_wOVRn6~q!(d5INufj})x+7Rp?XnW4?IXmb6|NZYb-@W&n zJ2Qu3qb098dpQFDUX@9O3h2}A3w40|J@NbY8;(kzoCiQ_6?Gv4fiWXXs*nSq-2ec7 z0DvDLgg*tKgayF!bO6{j0C=cReij!20BIn0XMzY4O8ZJm`>@h}EccpHd0i>{tNhI~ za(;tY&?pf!NcfG=#IEK3u1Twa$_wxTNLdMXQGd#^=l+zwbXW@e?bYmIKbC$ev&3G! z1iMoV4IW^aaXC|b`pvY@_CO^0)6}$!dwBIC*eJt^F%{Z+(q?#~2BvvVk=4Ek>aVMpF6 z5nbg=iE&;gkknp`_X8Q~btC}^A|#=Gw-2FF!mj1<8pP~l96^&r(Hs~2L4*_LL$BQG zw38fsI5h6UE>FWIp!NbPPf*|iqz?8e2}z#0YwQzSHi-OUkeUCwownBpo!C`CIH@ucdE}@g}(dj8DZn5kqP(){W&p_yrwWh`IO!SfOZG?^ZeuO?YMz?tn&(GUz z!`_IFu))K;&7w!p3P^y4qc#FEZ4{z{uvu`lf*=SSg>G??z$wr}j6zr}lyV&fK|GF9 z-Jl9m<_?Jv97MdOFrcWVyNdx>dELH9U#LFHh9DV}$wlNRD?Hq`AafH#@T+yu$b`Iv zw}+?hD3jfI?#O6c{AB9cOaV=lfWAFBWV+#VV>qrgvt^CJ@R6_cm9Kj@TnsNZpZZf> z_KT~MZ{N5bHZjz3JmgzzRmJJtp0(bkiu~T%Nab{m`lzBHEpcuEIq4G>P?4B8=TUce zoXIO_np)_I)UWFN_l2-uoKf4>@kLC3%dh7wvU|;Qk$QzKKeei1;BwN?ICHLL7liLN zKl6#o(}&y}XNI-hjMN*6eA76ygZSgV1;3Y^%&LZ-2@VhLW=@*QH9WvM%Omh_GIjo; z+7G`v9(;7uu0OokKik%<{f#&4F4_2`{^H1kuV_JEX74EO0K%Tjllq`9<>Krv(~J3D{#FV}5NMj%;MzEK$lBxQ zv@No%;e;Q^ahX16bZ>k*ri(T@cKfv5miB|b(?qWf!L=XjvJ?njuN^s-utE{ju9ALC zYC1DA$PB?pf~N|OvKfQH=KmOz7!R^03ykYx`@EX8?;O#E-WU6?|Ho^b*p9s5zQcw0 zZ<#d42Y-%xwBv%gW;F=cOx?T@xsUJ<3zSYrscA30!?Eq)@3+=VT4&}=vu?Rfp=F=g z20|}Y{BY!K3{_`S-u6V4FBdA!4m0NMCT3;lB3=4xG8u1hsBzRpePH0e zqKgXH-qo1aJ$=TP#w1#+N$2^6^c4d-=~ZN#q1^?qd1P&^MvfV-1UkIi%b^wFe01KQ ztD|q;3j$E-*aJ-f@}j{f!0VF?XXyUlb`XUyYNZ(6tW-Y5s`@w@bxPs_gv1wq#mFEvEl zI!Yt2m^GDaLRGvj*TVMGHthMohW3@2lfV9p^^}WKpLuNk`G#rjLUz%j^?1lP&(2Mt ztG&csho?`(Q}3TaUcp|w6yuCOeXdWO;rMeKXRI3?fqOAMse1pTX@T>q*h$?+p5yPX zxcH*n)x=dkI8aRYvvA)c_8Z6tG<3#eoMm25-OYGtl^UoAbo97xFg7Bgt!;ECW-A8; z*FWs2Vq%?T$)7-t8go?n=CRHkx%Im;Z2%$BzkF;CwCG3j(k6S#;9u#FiQdApGq44h6N|-WvD$`bW&f4%jw(AZx9tBXeEyzn4kmco rJH)GUF-=BM4$x>cTk{GFinB7*Ia^gl%DU+YFGvD1QMB-%{B*;QT66hG literal 0 HcmV?d00001 diff --git a/examples/databinding/java/com/databindingapp/res/drawable-xxhdpi/ic_launcher.png b/examples/databinding/java/com/databindingapp/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..20703a15c6809f4919a823ff4b5f571b02c5e88f GIT binary patch literal 2137 zcmZ`(c~p~E7JmUk5)czKmHi_S6qEvy%?Jr5A(*g85;j}v0z{y|AX`WRC=d_<#Q>us zRSra9O6-gas68%N9Y7GODBD4yDvN9~f)<}m`RyI}_^2gO{jzFOo&)mTTpsC#Ok7zVJlZ4!m9ROr+03iPm09pv; z&j64~0pL{>0AAGqn55R+6wm-bUFHXc`9TM9Z>G3UBz`Ow_dz8?{7541OaFPcN!TTf zxxeqy+>c>RJ0qIE@l|kGb=!UGI4r0rwu2ONzye@59z+3IDQ36~1Q%)uZ%v3a-rXTw znZRd)bASZ()K8SS4sdmW1OahG5Qqj|07MZ$C=QNyWq=9}yguyT_bdmNvnh75NhQOI zHYF6W-xM%_O&S^20`OH~HeUc>Hjd6pewY)0y+H;mkD4V42@Zwwe=QUa<qB?rTMt@{k>O?al4fZb8CzCskZ}!S`TUJq^TG;!P@__-RhnFVT&_l=R_Eie z8ns4~3t2ucPXiZ3av{S(Yzdch5Qj#aI!|tfl~FN)95yIHTXEq5m&*M%1Ax_SD;w3B zqTB~TjL3h7A7)C&WUZ6_-{#BU7pphz&t`^6hhGoGODw_(`cY5YJqLql^jM^`<~p9E z{F;1R1q;*f&srb^uqum^?=mbc-fxND8F^v;xwo67J8@@C{qj$XJy}!F20hK&%z9D} zFW#xHwAkO0aP?;?^;FsXFUwU{LXUfGX4cO#k}?*Oy*DJ5`eHU1o|z38tn8qsM}^+* zGv(k1F1mMg6`elWA*GV%Th#%*FNRFZEvtK8pCcc8J0t5OA4}_yHJkj~6d!LH`D9<- zcv;$%><@^lWxt*5xIW5w9w6Lxo$^Z`bU3uf^!y1NALNTUkNXAG?P1}3de;TLzgc< zt*Q0Aw{YvvO?daLQ5nX_Fg`Bc+O^#}_vPIN%<0qKOUm5I2g1O>a*OdRn7ZoUEl!^q zx)emaP_@x#+ZMBe$iQNe<4A4Q#?^%z4X|B_;dv!u0qmTwKW zl|Hh5J}VQ`mx;UIxArIU)@*A|Jyf=B@jrt;GdJoxtIpqlyEdDbG`Vb|tUI;$z-+Ab zz!O#XKTmwGDj(W2l(X)|(xOZE;?#FCd*j};icm{g>kU^0#Iy#kEgx>#ftQ6=)S zWv~Q8g|czvYP~bpuA5FN>BWCUCP^~oG>RF7?-StL*KI|x?drR>n0Dd~1lYaF=RHI> zvC%y2nkwynnt0$w$a7^Aw` zC+yKDrxPUa5LDt(E>9=>4x6{hE9(eYf3CkFUihI9|LZ%ubLBoCU+S#azH{ro@^;x| zZ`G>=_lwJ~=29Gbr}Dl#F+H+y(P`*-Nl(SOhp#Ur(wpQC{5)Ev9Lv8$6LF}@JfxXS z9N^&xjrCt$Dkj({a&z7^>KAGknBF?faOq_^iSL0lkU`i<%)EnM_%zDffDxXpkRRY* zLlk6u*fo3NSIohjg2o6iIQG^%ovD(x$SwK1YhyTc{=r%nXR9)}d_-UpcBymLL3i-= zY~}!JaG}dD`7ud)ljnpsI&44ZfHFGL_^elRW~6Y!-&;G@S*L#=c3k^@`4sARck`hS z+7VTz#bLLau~m&VH?aF1t}iWmT@QkP!Sy1)Z$$f|MX_GO^jIi>E5+5-iQ?+y>K3+n ztCzcn7sb<&Lh+(d4tdTE{3RecWnV&E*8dMsC53(u1I$(`gr>xaB+==yKq8SiC+ttk b5JsoQI;W(^pP8qbLnq+x7tFrMiYoXov?hQf literal 0 HcmV?d00001 diff --git a/examples/databinding/java/com/databindingapp/res/layout/activity_data_binding.xml b/examples/databinding/java/com/databindingapp/res/layout/activity_data_binding.xml new file mode 100644 index 000000000..d4bc445e2 --- /dev/null +++ b/examples/databinding/java/com/databindingapp/res/layout/activity_data_binding.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + +