Use RBE for run-test builds

This makes the build of run-test data over 10x faster
(from >300 cpu-minutes to <30 cpu-minutes; wall-time)

Test: generated test data is bit for bit identical as before
Change-Id: Ie8a9b30cb4d026d0de138f1fbc6c04990e55f8af
diff --git a/test/art_build_rules.py b/test/art_build_rules.py
index 4e4a959..c8053b7 100644
--- a/test/art_build_rules.py
+++ b/test/art_build_rules.py
@@ -58,10 +58,16 @@
   def parse_bool(text):
     return {"true": True, "false": False}[text.lower()]
 
+  ANDROID_BUILD_TOP = os.environ["ANDROID_BUILD_TOP"]
+  SBOX_PATH = os.environ["SBOX_PATH"]
+  CWD = os.getcwd()
   TEST_NAME = os.environ["TEST_NAME"]
-  ART_TEST_RUN_TEST_BOOTCLASSPATH = os.environ["ART_TEST_RUN_TEST_BOOTCLASSPATH"]
+  ART_TEST_RUN_TEST_BOOTCLASSPATH = path.relpath(os.environ["ART_TEST_RUN_TEST_BOOTCLASSPATH"], CWD)
   NEED_DEX = parse_bool(os.environ["NEED_DEX"]) if need_dex is None else need_dex
 
+  RBE_exec_root = os.environ.get("RBE_exec_root")
+  RBE_rewrapper = path.join(ANDROID_BUILD_TOP, "prebuilts/remoteexecution-client/live/rewrapper")
+
   # Set default values for directories.
   HAS_SMALI = path.exists("smali") if has_smali is None else has_smali
   HAS_JASMIN = path.exists("jasmin") if has_jasmin is None else has_jasmin
@@ -131,6 +137,35 @@
   d8 = functools.partial(run, os.environ["D8"])
   hiddenapi = functools.partial(run, os.environ["HIDDENAPI"])
 
+  if "RBE_server_address" in os.environ:
+    def rbe_wrap(args, inputs=set()):
+      with tempfile.NamedTemporaryFile(mode="w+t", dir=RBE_exec_root) as input_list:
+        for arg in args:
+          inputs.update(filter(path.exists, arg.split(":")))
+        input_list.writelines([path.relpath(i, RBE_exec_root)+"\n" for i in inputs])
+        input_list.flush()
+        return run(RBE_rewrapper, [
+          "--platform=" + os.environ["RBE_platform"],
+          "--input_list_paths=" + input_list.name,
+        ] + args)
+
+    def javac(args):
+      output = path.relpath(path.join(CWD, args[args.index("-d") + 1]), RBE_exec_root)
+      return rbe_wrap([
+        "--output_directories", output,
+        os.path.relpath(os.environ["JAVAC"], CWD),
+      ] + args)
+
+    def d8(args):
+      inputs = set([path.join(SBOX_PATH, "tools/out/framework/d8.jar")])
+      output = path.relpath(path.join(CWD, args[args.index("--output") + 1]), RBE_exec_root)
+      return rbe_wrap([
+        "--output_files" if output.endswith(".jar") else "--output_directories", output,
+        "--toolchain_inputs=prebuilts/jdk/jdk11/linux-x86/bin/java"
+        # TODO(dsrbecky): Work around bug b/227376947 ; Remove this when it is fixed.
+        + ",../../../../../../../../prebuilts/jdk/jdk11/linux-x86/bin/java",
+        os.path.relpath(os.environ["D8"], CWD)] + args, inputs)
+
   # If wrapper script exists, use it instead of the default javac.
   if os.path.exists("javac_wrapper.sh"):
     javac = functools.partial(run, "javac_wrapper.sh")
@@ -202,12 +237,14 @@
     # NB: We merge even if there is just single input.
     # It is useful to normalize non-deterministic smali output.
 
-    with tempfile.TemporaryDirectory(dir=".") as tmp_dir:
-      d8(["--min-api", str(api_level), "--output", tmp_dir] + dex_files_to_merge)
-      assert not path.exists(path.join(tmp_dir, "classes2.dex"))
-      for input_dex in dex_files_to_merge:
-        os.remove(input_dex)
-      os.rename(path.join(tmp_dir, "classes.dex"), dst_file)
+    tmp_dir = "dexmerge"
+    os.makedirs(tmp_dir)
+    d8(["--min-api", api_level, "--output", tmp_dir] + dex_files_to_merge)
+    assert not path.exists(path.join(tmp_dir, "classes2.dex"))
+    for input_dex in dex_files_to_merge:
+      os.remove(input_dex)
+    os.rename(path.join(tmp_dir, "classes.dex"), dst_file)
+    os.rmdir(tmp_dir)
 
 
   def make_hiddenapi(*dex_files):