[embedder] arm64 support.

Introduces a `--cpu arm64` flag to build_and_run_example.sh.
This required changes to compile an arm64 libflutter_engine.so
and switch between this and the x64 libflutter_engine.so based
on the build's CPU architecture.

Tested: build_and_run_example.sh compiles, but haven't tested it
yet.

Change-Id: I7be39d3de8fe181472b3a59be0d8fa832ca3cd5e
Reviewed-on: https://fuchsia-review.googlesource.com/c/flutter-embedder/+/762976
Reviewed-by: Ben Bergkamp <benbergkamp@google.com>
diff --git a/README.md b/README.md
index 2f39f96..53e851f 100644
--- a/README.md
+++ b/README.md
@@ -72,6 +72,12 @@
 
    This can also be done from VSCode by following [this guide](https://fuchsia.googlesource.com/flutter-embedder/+/refs/heads/main/docs/debugging.md#attaching-a-debugger-from-vscode).
 
+   - For an arm64 device, run:
+
+     ```sh
+     $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh hello_flutter --cpu arm64
+     ```
+
    - To watch logs for the example component, run:
 
      ```sh
diff --git a/scripts/build_and_copy_engine_artifacts.sh b/scripts/build_and_copy_engine_artifacts.sh
index ca06a4d..3eb910f 100755
--- a/scripts/build_and_copy_engine_artifacts.sh
+++ b/scripts/build_and_copy_engine_artifacts.sh
@@ -26,6 +26,7 @@
 goma=0
 goma_flags=""
 ninja_cmd="ninja"
+cpu="x64"
 extra_gn_args=()
 while [[ $# -gt 0 ]]; do
   case $1 in
@@ -35,6 +36,11 @@
       ninja_cmd="autoninja"
       shift # past argument
       ;;
+    --cpu)
+      shift # past argument
+      cpu="$1"
+      shift # past value
+      ;;
     *)
       extra_gn_args+=("$1") # forward argument
       shift # past argument
@@ -42,16 +48,16 @@
   esac
 done
 
-all_gn_args="--fuchsia --embedder-for-target --unopt ${goma_flags} ${extra_gn_args[@]}"
+all_gn_args="--fuchsia --embedder-for-target --unopt ${goma_flags} ${extra_gn_args[@]} --fuchsia-cpu ${cpu}"
 
-echo-info "Building the debug Flutter Engine embedding for Fuchsia (libflutter_engine.so)..."
+echo-info "Building the debug Flutter Engine embedding for Fuchsia (libflutter_engine.so) for ${cpu}..."
 echo-info "... GN args: ${all_gn_args}"
 "${embedder_engine_dir}"/flutter/tools/gn ${all_gn_args}
-debug_out_dir="${embedder_engine_dir}"/out/fuchsia_debug_unopt_x64
+debug_out_dir="${embedder_engine_dir}"/out/fuchsia_debug_unopt_${cpu}
 "${embedder_depot_tools}"/"${ninja_cmd}" -C "${debug_out_dir}"
 
-echo-info "Copying debug Flutter Engine artifacts to ${FUCHSIA_EMBEDDER_DIR}/src/embedder/engine/debug_x64..."
-cp "${debug_out_dir}"/so.unstripped/libflutter_engine.so "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/engine/debug_x64/libflutter_engine.so
+echo-info "Copying debug Flutter Engine artifacts to ${FUCHSIA_EMBEDDER_DIR}/src/embedder/engine/debug_${cpu}..."
+cp "${debug_out_dir}"/so.unstripped/libflutter_engine.so "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/engine/debug_${cpu}/libflutter_engine.so  
 
 echo-info "Copying embedder.h to ${FUCHSIA_EMBEDDER_DIR}/src/embedder/engine..."
 cp "${embedder_engine_dir}"/flutter/shell/platform/embedder/embedder.h "${FUCHSIA_EMBEDDER_DIR}"/src/embedder/engine
diff --git a/scripts/build_and_run_example.sh b/scripts/build_and_run_example.sh
index b01de6b..562c22f 100755
--- a/scripts/build_and_run_example.sh
+++ b/scripts/build_and_run_example.sh
@@ -47,6 +47,7 @@
 goma_flags=""
 no_prebuilt_dart_sdk_flags=""
 app_name="hello_flutter"
+cpu="x64"
 while [[ $# -gt 0 ]]; do
   case $1 in
     --headless)
@@ -80,6 +81,15 @@
       no_prebuilt_dart_sdk_flags="--no-prebuilt-dart-sdk"
       shift # past argument
       ;;
+    --cpu)
+      shift # past argument
+      cpu="$1"
+      if [[ "${cpu}" != "x64" && "${cpu}" != "arm64" ]]
+      then
+        echo-error "Unknown value for cpu: $cpu. Valid values: x64, arm64"
+      fi
+      shift # past value
+      ;;
     *)
       app_name="$1"
       shift # past value
@@ -115,7 +125,7 @@
 
 if [[ "${with_engine}" != 0 ]]
 then
-  "${FUCHSIA_EMBEDDER_DIR}"/scripts/build_and_copy_engine_artifacts.sh ${goma_flags} ${no_prebuilt_dart_sdk_flags}
+  "${FUCHSIA_EMBEDDER_DIR}"/scripts/build_and_copy_engine_artifacts.sh ${goma_flags} ${no_prebuilt_dart_sdk_flags} --cpu "${cpu}"
 fi
 
 if [[ "${with_fuchsia}" != 0 ]]
@@ -143,10 +153,10 @@
 
 echo-info "Running Flutter sample app."
 "${FUCHSIA_EMBEDDER_DIR}"/tools/ffx repository server start
-"${FUCHSIA_EMBEDDER_DIR}"/tools/bazel run --config=fuchsia_x64 //src/examples/"${app_name}":"${app_name}"_pkg.component ${session_args}
+"${FUCHSIA_EMBEDDER_DIR}"/tools/bazel run --config=fuchsia_"${cpu}" //src/examples/"${app_name}":"${app_name}"_pkg.component ${session_args}
 
 echo-info "Package contents for debugging:"
-"${FUCHSIA_EMBEDDER_DIR}"/tools/bazel build --config=fuchsia_x64 //src/examples/"${app_name}":"${app_name}"_pkg
+"${FUCHSIA_EMBEDDER_DIR}"/tools/bazel build --config=fuchsia_"${cpu}" //src/examples/"${app_name}":"${app_name}"_pkg
 "${far_tool}" extract --archive="$(find -L ${FUCHSIA_EMBEDDER_DIR}/bazel-out -name "${app_name}".far | head -n 1)" --output="${far_debug_dir}"
 "${far_tool}" extract --archive="${far_debug_dir}"/meta.far --output="${far_debug_dir}"
 cat "${far_debug_dir}"/meta/contents
diff --git a/scripts/tests/build_and_copy_engine_artifacts_test.sh b/scripts/tests/build_and_copy_engine_artifacts_test.sh
index 7c4d77f..ff4c075 100755
--- a/scripts/tests/build_and_copy_engine_artifacts_test.sh
+++ b/scripts/tests/build_and_copy_engine_artifacts_test.sh
@@ -23,6 +23,9 @@
 echo-info 'Testing build_and_copy_engine_artifacts.sh --no-prebuilt-dart-sdk ...'
 $FUCHSIA_EMBEDDER_DIR/scripts/build_and_copy_engine_artifacts.sh --no-prebuilt-dart-sdk
 
+echo-info 'Testing build_and_copy_engine_artifacts.sh --cpu arm64 ...'
+$FUCHSIA_EMBEDDER_DIR/scripts/build_and_copy_engine_artifacts.sh --cpu arm64
+
 popd  # $FUCHSIA_EMBEDDER_DIR
 
 echo-info 'Testing build_and_copy_engine_artifacts.sh from $HOME ...'
diff --git a/scripts/tests/build_and_run_example_test.sh b/scripts/tests/build_and_run_example_test.sh
index dea3bb6..75c6c72 100755
--- a/scripts/tests/build_and_run_example_test.sh
+++ b/scripts/tests/build_and_run_example_test.sh
@@ -17,28 +17,34 @@
 echo-info 'Testing build_and_run_example.sh with no arguments ...'
 $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh
 
+echo-info 'Testing build_and_run_example.sh --cpu arm64 ...'
+$FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --cpu arm64
+
 if [[ -d "${embedder_engine_dir}" ]]
 then
-    echo-info 'Testing build_and_run_example.sh --with-engine ...'
-    $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-engine
+  echo-info 'Testing build_and_run_example.sh --with-engine ...'
+  $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-engine
 
-    echo-info 'Testing build_and_run_example.sh --with-engine --goma ...'
-    $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-engine --goma
+  echo-info 'Testing build_and_run_example.sh --with-engine --goma ...'
+  $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-engine --goma
 
-    echo-info 'Testing build_and_run_example.sh --with-engine --goma --no-prebuilt-dart-sdk ...'
-    $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-engine --goma --no-prebuilt-dart-sdk
+  echo-info 'Testing build_and_run_example.sh --with-engine --goma --no-prebuilt-dart-sdk ...'
+  $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-engine --goma --no-prebuilt-dart-sdk
+
+  echo-info 'Testing build_and_run_example.sh --with-engine --goma --cpu arm64 ...'
+  $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-engine --goma --cpu arm64
 else
-    echo-warning "Skipping --with-engine tests because ${embedder_engine_dir} doesn't exist."
-    echo-warning "To run these tests, follow the setup from https://fuchsia.googlesource.com/flutter-embedder/+/refs/heads/main/docs/making_engine_changes.md."
+  echo-warning "Skipping --with-engine tests because ${embedder_engine_dir} doesn't exist."
+  echo-warning "To run these tests, follow the setup from https://fuchsia.googlesource.com/flutter-embedder/+/refs/heads/main/docs/making_engine_changes.md."
 fi
 
 if ! [ -z "${LOCAL_FUCHSIA_PLATFORM_BUILD}" ]
 then
-    echo-info 'Testing build_and_run_example.sh --with-fuchsia ...'
-    $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-fuchsia
+  echo-info 'Testing build_and_run_example.sh --with-fuchsia ...'
+  $FUCHSIA_EMBEDDER_DIR/scripts/build_and_run_example.sh --with-fuchsia
 else
-    echo-warning "Skipping --with-fuchsia tests because ${LOCAL_FUCHSIA_PLATFORM_BUILD} isn't set."
-    echo-warning "To run these tests, follow the setup from https://fuchsia.googlesource.com/flutter-embedder/+/refs/heads/main/docs/testing_fuchsia_sdk_changes.md."
+  echo-warning "Skipping --with-fuchsia tests because ${LOCAL_FUCHSIA_PLATFORM_BUILD} isn't set."
+  echo-warning "To run these tests, follow the setup from https://fuchsia.googlesource.com/flutter-embedder/+/refs/heads/main/docs/testing_fuchsia_sdk_changes.md."
 fi
 
 popd  # $FUCHSIA_EMBEDDER_DIR
diff --git a/scripts/update_dependencies.sh b/scripts/update_dependencies.sh
index ef595d1..63eb71c 100755
--- a/scripts/update_dependencies.sh
+++ b/scripts/update_dependencies.sh
@@ -46,7 +46,8 @@
 
 # Then bump Flutter Engine to match Flutter.
 "${FUCHSIA_EMBEDDER_DIR}"/scripts/sync_engine_to_revision.sh "$(cat ${FUCHSIA_EMBEDDER_DIR}/third_party/dart-pkg/internal/flutter/flutter/bin/internal/engine.version)"
-"${FUCHSIA_EMBEDDER_DIR}"/scripts/build_and_copy_engine_artifacts.sh ${goma_args}
+"${FUCHSIA_EMBEDDER_DIR}"/scripts/build_and_copy_engine_artifacts.sh ${goma_args} --cpu x64
+"${FUCHSIA_EMBEDDER_DIR}"/scripts/build_and_copy_engine_artifacts.sh ${goma_args} --cpu arm64
 
 # Bump the Embedder's Fuchsia SDK to whatever is the latest version and pray that the
 # Engine's Fuchsia SDK is close enough to prevent incompatibility issues.
diff --git a/src/embedder/BUILD.bazel b/src/embedder/BUILD.bazel
index 24d10ed..f6a992a 100644
--- a/src/embedder/BUILD.bazel
+++ b/src/embedder/BUILD.bazel
@@ -39,10 +39,7 @@
     visibility = ["//visibility:public"],
     deps = [
         "//src/embedder/engine:embedder_header",
-        # TODO(akbiggs): Enable switching between debug and profile
-        # builds of libflutter_engine.so without manually editing this
-        # file.
-        "//src/embedder/engine/debug_x64:libflutter_engine",
+        "//src/embedder/engine:libflutter_engine_for_platform",
         "@rapidjson",
         "@fuchsia_sdk//fidl/fuchsia.fonts:fuchsia.fonts_cc",
         "@fuchsia_sdk//fidl/fuchsia.sysmem:fuchsia.sysmem_cc",
diff --git a/src/embedder/engine/BUILD.bazel b/src/embedder/engine/BUILD.bazel
index 4615b13..d64ab28 100644
--- a/src/embedder/engine/BUILD.bazel
+++ b/src/embedder/engine/BUILD.bazel
@@ -4,9 +4,51 @@
 #
 # Artifacts from the Flutter Engine repository: https://github.com/flutter/engine
 
+load(
+    "@rules_fuchsia//fuchsia:defs.bzl",
+    "fuchsia_package_resource",
+)
+
 # ABI-stable interface for the Flutter embedder platform. Copied from the Flutter Engine.
 cc_library(
     name = "embedder_header",
     hdrs = ["embedder.h"],
     visibility = ["//src/embedder:__pkg__"],
 )
+
+# A debug version of libflutter_engine.so for the build's
+# CPU architecture.
+# TODO(akbiggs): Switch between debug vs. release builds.
+cc_library(
+    name = "libflutter_engine_for_platform",
+    deps = select({
+        ":arm64_cpu": ["//src/embedder/engine/debug_arm64:libflutter_engine"],
+        ":x64_cpu": ["//src/embedder/engine/debug_x64:libflutter_engine"],
+    }),
+    visibility = ["//visibility:public"],
+)
+
+# Package resource to include libflutter_engine.so into a Fuchsia package's
+# libraries.
+#
+# You must include this in your package's dependencies if your package's binary
+# has a dependency on `:libflutter_engine_for_platform`.
+fuchsia_package_resource(
+    name = "libflutter_engine_pkg_resource",
+    src = select({
+        ":arm64_cpu": "//src/embedder/engine/debug_arm64:libflutter_engine.so",
+        ":x64_cpu": "//src/embedder/engine/debug_x64:libflutter_engine.so",
+    }),
+    dest = "lib/libflutter_engine.so",
+    visibility = ["//visibility:public"],
+)
+
+config_setting(
+    name = "arm64_cpu",
+    values = {"cpu": "aarch64"},
+)
+
+config_setting(
+    name = "x64_cpu",
+    values = {"cpu": "x86_64"},
+)
diff --git a/src/embedder/engine/debug_arm64/BUILD.bazel b/src/embedder/engine/debug_arm64/BUILD.bazel
new file mode 100644
index 0000000..b7b998d
--- /dev/null
+++ b/src/embedder/engine/debug_arm64/BUILD.bazel
@@ -0,0 +1,24 @@
+# Copyright 2022 The Fuchsia Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+#
+# Artifacts from the Flutter Engine repository built in
+# debug mode for the x64 architecture: https://github.com/flutter/engine
+
+# Shared library implementing the embedder.h header.
+#
+# TODO(akbiggs): This should come from a CIPD bucket instead.
+cc_library(
+    name = "libflutter_engine",
+    srcs = ["libflutter_engine.so"],
+    visibility = ["//src/embedder/engine:__pkg__"],
+    deps = [
+        "@fuchsia_sdk//pkg/memfs",
+        "@fuchsia_sdk//pkg/vulkan",
+    ],
+)
+
+exports_files(
+    ["libflutter_engine.so"],
+    visibility = ["//src/embedder/engine:__pkg__"],
+)
diff --git a/src/embedder/engine/debug_arm64/libflutter_engine.so b/src/embedder/engine/debug_arm64/libflutter_engine.so
new file mode 100755
index 0000000..4bd7d34
--- /dev/null
+++ b/src/embedder/engine/debug_arm64/libflutter_engine.so
Binary files differ
diff --git a/src/embedder/engine/debug_x64/BUILD.bazel b/src/embedder/engine/debug_x64/BUILD.bazel
index 20d4861..14fbe3f 100644
--- a/src/embedder/engine/debug_x64/BUILD.bazel
+++ b/src/embedder/engine/debug_x64/BUILD.bazel
@@ -16,21 +16,14 @@
 cc_library(
     name = "libflutter_engine",
     srcs = ["libflutter_engine.so"],
-    visibility = ["//src/embedder:__pkg__"],
+    visibility = ["//src/embedder/engine:__pkg__"],
     deps = [
         "@fuchsia_sdk//pkg/memfs",
         "@fuchsia_sdk//pkg/vulkan",
     ],
 )
 
-# Package resource to include libflutter_engine.so into a Fuchsia package's
-# libraries.
-#
-# You must include this in your package's dependencies if your package's binary
-# has a dependency on `:libflutter_engine`.
-fuchsia_package_resource(
-    name = "libflutter_engine_pkg_resource",
-    src = ":libflutter_engine.so",
-    dest = "lib/libflutter_engine.so",
-    visibility = ["//visibility:public"],
+exports_files(
+    ["libflutter_engine.so"],
+    visibility = ["//src/embedder/engine:__pkg__"],
 )
diff --git a/src/examples/animation_example/BUILD.bazel b/src/examples/animation_example/BUILD.bazel
index 2b94786..bdca6d3 100644
--- a/src/examples/animation_example/BUILD.bazel
+++ b/src/examples/animation_example/BUILD.bazel
@@ -43,9 +43,6 @@
     visibility = ["//visibility:public"],
     deps = [
         ":component",
-        # TODO(akbiggs): Enable switching between debug/release
-        # builds of libflutter_engine.so without manually modifying
-        # this file.
-        "//src/embedder/engine/debug_x64:libflutter_engine_pkg_resource",
+        "//src/embedder/engine:libflutter_engine_pkg_resource",
     ],
 )
diff --git a/src/examples/hello_dart/BUILD.bazel b/src/examples/hello_dart/BUILD.bazel
index 772531e..7e38c9a 100644
--- a/src/examples/hello_dart/BUILD.bazel
+++ b/src/examples/hello_dart/BUILD.bazel
@@ -39,6 +39,6 @@
     visibility = ["//visibility:public"],
     deps = [
         ":component",
-        "//src/embedder/engine/debug_x64:libflutter_engine_pkg_resource",
+        "//src/embedder/engine:libflutter_engine_pkg_resource",
     ],
 )
diff --git a/src/examples/hello_flutter/BUILD.bazel b/src/examples/hello_flutter/BUILD.bazel
index 1a335e6..1998550 100644
--- a/src/examples/hello_flutter/BUILD.bazel
+++ b/src/examples/hello_flutter/BUILD.bazel
@@ -40,9 +40,6 @@
     visibility = ["//visibility:public"],
     deps = [
         ":component",
-        # TODO(akbiggs): Enable switching between debug/release
-        # builds of libflutter_engine.so without manually modifying
-        # this file.
-        "//src/embedder/engine/debug_x64:libflutter_engine_pkg_resource",
+        "//src/embedder/engine:libflutter_engine_pkg_resource",
     ],
 )