Updates for Android NDK version 26 (#822)

This PR adjusts the buildroot for Android NDK version 26. This NDK
version only supports clang, so it contains some cleanups of old
non-clang pathways.

The companion flutter/engine PR is
https://github.com/flutter/engine/pull/48254.
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index 9e8a02c..dc1eb06 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -5,15 +5,6 @@
 # This file contains common system config stuff for the Android build.
 
 if (is_android) {
-  has_chrome_android_internal =
-      exec_script("//build/dir_exists.py",
-                  [ rebase_path("//clank", root_build_dir) ],
-                  "string") == "True"
-
-  if (has_chrome_android_internal) {
-    import("//clank/config.gni")
-  }
-
   if (!defined(default_android_sdk_root)) {
     default_android_sdk_root = "//third_party/android_tools/sdk"
     default_android_sdk_version = "34"
@@ -25,22 +16,6 @@
     android_sdk_version = default_android_sdk_version
     android_sdk_build_tools_version = default_android_sdk_build_tools_version
 
-    android_default_keystore_path =
-        "//build/android/ant/chromium-debug.keystore"
-    android_default_keystore_name = "chromiumdebugkey"
-    android_default_keystore_password = "chromium"
-
-    # This is a unique identifier for a given build. It's used for
-    # identifying various build artifacts corresponding to a particular build of
-    # chrome (e.g. where to find archived symbols).
-    android_chrome_build_id = "\"\""
-
-    # Set to true to run findbugs on JAR targets.
-    run_findbugs = false
-
-    # Set to true to enable the Errorprone compiler
-    use_errorprone_java_compiler = false
-
     # Unused. Required for GN files maintained in other buildroots.
     enable_java_templates = false
 
@@ -92,69 +67,17 @@
 
   zipalign_path = "$android_sdk_build_tools/zipalign"
 
-  # Subdirectories inside android_ndk_root that contain the sysroot for the
-  # associated platform.
   if (current_cpu != "x64" && current_cpu != "arm64") {
-    android_api_level = 19
+    android_api_level = 21
   }
 
   # Toolchain root directory for each build. The actual binaries are inside
   # a "bin" directory inside of these.
-  _android_toolchain_version = "4.9"
-
   llvm_android_toolchain_root = "$android_ndk_root/toolchains/llvm/prebuilt/${android_host_os}-${android_host_arch}"
-
-  x86_android_toolchain_root = "$android_ndk_root/toolchains/x86-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
-  arm_android_toolchain_root = "$android_ndk_root/toolchains/arm-linux-androideabi-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
-  x86_64_android_toolchain_root = "$android_ndk_root/toolchains/x86_64-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
-  arm64_android_toolchain_root = "$android_ndk_root/toolchains/aarch64-linux-android-${_android_toolchain_version}/prebuilt/${android_host_os}-${android_host_arch}"
-
-  x86_android_lib = "$llvm_android_toolchain_root/sysroot/usr/lib/i686-linux-android/${android_api_level}"
-  arm_android_lib = "$llvm_android_toolchain_root/sysroot/usr/lib/arm-linux-androideabi/${android_api_level}"
-  x86_64_android_lib = "$llvm_android_toolchain_root/sysroot/usr/lib/x86_64-linux-android/${android_api_level}"
-  arm64_android_lib = "$llvm_android_toolchain_root/sysroot/usr/lib/aarch64-linux-android/${android_api_level}"
-
-  # Location of libgcc. This is only needed for the current GN toolchain, so we
-  # only need to define the current one, rather than one for every platform
-  # like the toolchain roots.
-  if (current_cpu == "x86") {
-    android_prebuilt_arch = "android-x86"
-    android_target_triple = "i686-linux-android"
-    android_toolchain_root = "$x86_android_toolchain_root"
-    android_lib = "$x86_android_lib"
-  } else if (current_cpu == "arm") {
-    android_prebuilt_arch = "android-arm"
-    android_target_triple = "arm-linux-androideabi"
-    android_toolchain_root = "$arm_android_toolchain_root"
-    android_lib = "$arm_android_lib"
-  } else if (current_cpu == "x64") {
-    android_prebuilt_arch = "android-x86_64"
-    android_target_triple = "x86_64-linux-android"
-    android_toolchain_root = "$x86_64_android_toolchain_root"
-    android_lib = "$x86_64_android_lib"
-  } else if (current_cpu == "arm64") {
-    android_prebuilt_arch = "android-arm64"
-    android_target_triple = "aarch64-linux-android"
-    android_toolchain_root = "$arm64_android_toolchain_root"
-    android_lib = "$arm64_android_lib"
-  } else {
-    assert(false, "Need android libgcc support for your target arch.")
-  }
-
-  android_tool_prefix = "$android_toolchain_root/bin/$android_target_triple-"
-  android_readelf = "${android_tool_prefix}readelf"
-  android_objcopy = "${android_tool_prefix}objcopy"
-  android_gdbserver =
-      "$android_ndk_root/prebuilt/$android_prebuilt_arch/gdbserver/gdbserver"
+  android_toolchain_root = "$android_ndk_root/toolchains/llvm/prebuilt/${android_host_os}-${android_host_arch}"
 
   # Toolchain stuff ------------------------------------------------------------
-
-  android_libcpp_root = "$android_ndk_root/sources/cxx-stl/llvm-libc++"
-  if (component_mode == "shared_library") {
-    android_libcpp_library = "c++_shared"
-  } else {
-    android_libcpp_library = "c++_static"
-  }
+  _android_lib_prefix = "$android_toolchain_root/sysroot/usr/lib"
 
   if (component_mode == "shared_library") {
     # By appending .cr, we prevent name collisions with libraries already
@@ -168,20 +91,21 @@
 
   if (current_cpu == "x86") {
     android_app_abi = "x86"
+    _android_lib_dir = "i686-linux-android"
   } else if (current_cpu == "arm") {
-    import("//build/config/arm.gni")
-    if (arm_version < 7) {
-      android_app_abi = "armeabi"
-    } else {
-      android_app_abi = "armeabi-v7a"
-    }
+    android_app_abi = "armeabi-v7a"
+    _android_lib_dir = "arm-linux-androideabi"
   } else if (current_cpu == "x64") {
     android_app_abi = "x86_64"
+    _android_lib_dir = "x86_64-linux-android"
   } else if (current_cpu == "arm64") {
     android_app_abi = "arm64-v8a"
+    _android_lib_dir = "aarch64-linux-android"
   } else {
     assert(false, "Unknown Android ABI: " + current_cpu)
   }
 
+  android_lib = "$_android_lib_prefix/$_android_lib_dir/$android_api_level"
+
   android_log_tag = "\"flutter\""
 }
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 16f5ccb..2eb442f 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -231,9 +231,6 @@
       }
       if (arm_use_thumb) {
         cflags += [ "-mthumb" ]
-        if (is_android && !is_clang) {  # Clang doesn't support this option.
-          cflags += [ "-mthumb-interwork" ]
-        }
       }
       if (!is_clang) {
         # Clang doesn't support these flags.
@@ -392,14 +389,6 @@
       "-fno-short-enums",
       "-nostdinc++",
     ]
-    if (!is_clang) {
-      # Clang doesn't support these flags.
-      cflags += [ "-finline-limit=64" ]
-    }
-    if (current_cpu == "arm64") {
-      # TODO (https://github.com/flutter/flutter/issues/75348).
-      cflags += [ "-mno-outline-atomics" ]
-    }
 
     defines += [ "ANDROID" ]
 
@@ -407,16 +396,9 @@
     # to say that it does. Define them here instead.
     defines += [ "HAVE_SYS_UIO_H" ]
 
-    if (is_clang) {
-      # Let clang find libgcc.
-      ldflags += [ "--gcc-toolchain=" +
-                   rebase_path(android_toolchain_root, root_build_dir) ]
-    }
-
     ldflags += [
       "-Wl,--no-undefined",
       "-Wl,--exclude-libs,ALL",
-      "-fuse-ld=lld",
 
       # Enable identical code folding to reduce size.
       "-Wl,--icf=all",
@@ -426,20 +408,18 @@
       "-Wl,-z,max-page-size=65536",
     ]
 
-    if (is_clang) {
-      if (current_cpu == "arm") {
-        cflags += [ "--target=arm-linux-androideabi" ]
-        ldflags += [ "--target=arm-linux-androideabi" ]
-      } else if (current_cpu == "arm64") {
-        cflags += [ "--target=aarch64-linux-android" ]
-        ldflags += [ "--target=aarch64-linux-android" ]
-      } else if (current_cpu == "x86") {
-        cflags += [ "--target=i686-linux-androideabi" ]
-        ldflags += [ "--target=i686-linux-androideabi" ]
-      } else if (current_cpu == "x64") {
-        cflags += [ "--target=x86_64-linux-androideabi" ]
-        ldflags += [ "--target=x86_64-linux-androideabi" ]
-      }
+    if (current_cpu == "arm") {
+      cflags += [ "--target=arm-linux-androideabi${android_api_level}" ]
+      ldflags += [ "--target=arm-linux-androideabi${android_api_level}" ]
+    } else if (current_cpu == "arm64") {
+      cflags += [ "--target=aarch64-linux-android${android_api_level}" ]
+      ldflags += [ "--target=aarch64-linux-android${android_api_level}" ]
+    } else if (current_cpu == "x86") {
+      cflags += [ "--target=i686-linux-androideabi${android_api_level}" ]
+      ldflags += [ "--target=i686-linux-androideabi${android_api_level}" ]
+    } else if (current_cpu == "x64") {
+      cflags += [ "--target=x86_64-linux-androideabi${android_api_level}" ]
+      ldflags += [ "--target=x86_64-linux-androideabi${android_api_level}" ]
     }
   }
 
@@ -561,40 +541,34 @@
 
   # Android standard library setup.
   if (is_android) {
-    if (is_clang) {
-      # Work around incompatibilities between bionic and clang headers.
-      defines += [
-        "__compiler_offsetof=__builtin_offsetof",
-        "nan=__builtin_nan",
-      ]
-    }
+    # Work around incompatibilities between bionic and clang headers.
+    defines += [
+      "__compiler_offsetof=__builtin_offsetof",
+      "nan=__builtin_nan",
+    ]
 
     ldflags += [ "-nostdlib" ]
 
-    cflags += [ "-D__ANDROID_API__=$android_api_level" ]
-
-    # libunwind and libandroid_support also live in $android_libcpp_root.
-    lib_dirs += [ "$android_libcpp_root/libs/$android_app_abi" ]
-
-    if (android_api_level < 21) {
-      libs += [ "android_support" ]
-    }
-
-    if (current_cpu == "arm") {
-      libs += [ "unwind" ]
-    }
+    ldflags += [
+      "-Wl,--warn-shared-textrel",
+    ]
 
     libs += [
-      "gcc",
       "c",
       "dl",
       "m",
     ]
 
-    # Clang with libc++ does not require an explicit atomic library reference.
-    if (!is_clang) {
-      libs += [ "atomic" ]
+    lib_dirs += [ "${android_toolchain_root}/lib/clang/17/lib/linux/" ]
+    current_android_cpu = current_cpu
+    if (current_cpu == "arm64") {
+      current_android_cpu = "aarch64"
+    } else if (current_cpu == "x64") {
+      current_android_cpu = "x86_64"
+    } else if (current_cpu == "x86") {
+      current_android_cpu = "i686"
     }
+    libs += [ "clang_rt.builtins-${current_android_cpu}-android" ]
   }
 
   # Linux standard library setup.
@@ -682,10 +656,15 @@
 
     # Needed for compiling Skia with clang-12
     "-Wno-psabi",
-
-    # Needed for nlohmann/json.
-    "-Wno-deprecated-literal-operator",
   ]
+
+  if (!is_android) {
+    default_warning_flags += [
+      # Needed for nlohmann/json.
+      "-Wno-deprecated-literal-operator",
+    ]
+  }
+
   if (!is_wasm) {
     default_warning_flags += [
       # Unqualified std::move is pretty common.
diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni
index 97d662f..727a6b1 100644
--- a/build/config/sysroot.gni
+++ b/build/config/sysroot.gni
@@ -21,7 +21,7 @@
   sysroot = target_sysroot
 } else if (is_android) {
   import("//build/config/android/config.gni")
-  sysroot = rebase_path("$llvm_android_toolchain_root/sysroot", root_build_dir)
+  sysroot = rebase_path("$android_toolchain_root/sysroot", root_build_dir)
 } else if (is_linux && !is_chromeos) {
   if (use_default_linux_sysroot && !is_fuchsia) {
     if (current_cpu == "x64") {
diff --git a/build/toolchain/android/BUILD.gn b/build/toolchain/android/BUILD.gn
index 8be0aa8..610f58c 100644
--- a/build/toolchain/android/BUILD.gn
+++ b/build/toolchain/android/BUILD.gn
@@ -19,7 +19,7 @@
 #      Prefix to be added to the tool names.
 #  - toolchain_cpu
 #      Same as gcc_toolchain
-template("android_gcc_toolchain") {
+template("android_toolchain") {
   gcc_toolchain(target_name) {
     extra_toolchain_args = {
       if (defined(invoker.extra_toolchain_args)) {
@@ -28,7 +28,7 @@
     }
 
     # Make our manually injected libs relative to the build dir.
-    android_ndk_lib = rebase_path(invoker.android_ndk_lib_dir, root_build_dir)
+    android_ndk_lib = rebase_path(android_lib, root_build_dir)
 
     libs_section_prefix = "$android_ndk_lib/crtbegin_dynamic.o"
     libs_section_postfix = "$android_ndk_lib/crtend_android.o"
@@ -36,56 +36,49 @@
     solink_libs_section_prefix = "$android_ndk_lib/crtbegin_so.o"
     solink_libs_section_postfix = "$android_ndk_lib/crtend_so.o"
 
-    # The tools should be run relative to the build dir.
-    tool_prefix = rebase_path(invoker.tool_prefix, root_build_dir)
-
     if (use_goma) {
       assert(!use_rbe, "Goma and RBE can't be used together.")
       assert(!use_ccache, "Goma and ccache can't be used together.")
+      assembler_prefix = "$goma_dir/gomacc "
       compiler_prefix = "$goma_dir/gomacc "
       link_prefix = "$goma_dir/gomacc "
     } else if (use_rbe) {
       compiler_args =
           rewrapper_command + [ "--labels=type=compile,compiler=clang,lang=cpp " ]
       link_args = rewrapper_command + [ "--labels=type=link,tool=clang " ]
+      assembler_prefix = ""
       compiler_prefix = string_join(" ", compiler_args)
       link_prefix = string_join(" ", link_args)
     } else if (use_ccache) {
+      assembler_prefix = "ccache "
       compiler_prefix = "ccache "
       link_prefix = "ccache "
     } else {
       compiler_prefix = ""
       link_prefix = ""
+      assembler_prefix = ""
     }
 
-    is_clang = invoker.is_clang
-    if (is_clang) {
-      host_dir = ""
-      if (host_os == "linux") {
-        host_dir = "linux-x64"
-      } else if (host_os == "mac") {
-        host_dir = "mac-x64"
-      } else {
-        assert(false, "Unknown host")
-      }
-
-      prefix = rebase_path("//buildtools/$host_dir/clang/bin", root_build_dir)
-
-      asm = prefix + "/clang"
-      cc = compiler_prefix + prefix + "/clang"
-      cxx = compiler_prefix + prefix + "/clang++"
-      ar = prefix + "/llvm-ar"
-      ld = link_prefix + prefix + "/clang++"
+    assert(invoker.is_clang)
+    host_dir = ""
+    if (host_os == "linux") {
+      host_dir = "linux-x64"
+    } else if (host_os == "mac") {
+      host_dir = "mac-x64"
     } else {
-      asm = tool_prefix + "gcc"
-      cc = compiler_prefix + tool_prefix + "gcc"
-      cxx = compiler_prefix + tool_prefix + "g++"
-      ar = tool_prefix + "ar"
-      ld = link_prefix + tool_prefix + "g++"
+      assert(false, "Unknown host")
     }
 
-    readelf = tool_prefix + "readelf"
-    nm = tool_prefix + "nm"
+    prefix = rebase_path("//buildtools/$host_dir/clang/bin", root_build_dir)
+
+    cc = "${compiler_prefix}${prefix}/clang"
+    cxx = "${compiler_prefix}${prefix}/clang++"
+    asm = "${assembler_prefix}${prefix}/clang"
+    ar = prefix + "/llvm-ar"
+    ld = "${link_prefix}${prefix}/clang++"
+    readelf = prefix + "/llvm-readelf"
+    nm = prefix + "/llvm-nm"
+    android_strip = prefix + "/llvm-strip"
 
     toolchain_os = "android"
     toolchain_cpu = invoker.toolchain_cpu
@@ -97,8 +90,6 @@
     stripped_soname = "lib.stripped/${soname}"
     temp_stripped_soname = "${stripped_soname}.tmp"
 
-    android_strip = "${tool_prefix}strip"
-
     strip_command = "$android_strip --strip-unneeded -o $temp_stripped_soname {{root_out_dir}}/$soname"
     replace_command = "if ! cmp -s $temp_stripped_soname $stripped_soname; then mv $temp_stripped_soname $stripped_soname; fi"
     postsolink = "$strip_command && $replace_command"
@@ -114,55 +105,31 @@
   }
 }
 
-template("android_gcc_toolchains_helper") {
-  android_gcc_toolchain(target_name) {
+template("android_toolchains_helper") {
+  android_toolchain("clang_$target_name") {
     extra_toolchain_args = {
       if (defined(invoker.extra_toolchain_args)) {
         forward_variables_from(invoker.extra_toolchain_args, "*")
       }
     }
-    android_ndk_lib_dir = invoker.android_ndk_lib_dir
-    tool_prefix = invoker.tool_prefix
-    toolchain_cpu = invoker.toolchain_cpu
-  }
-  android_gcc_toolchain("clang_$target_name") {
-    extra_toolchain_args = {
-      if (defined(invoker.extra_toolchain_args)) {
-        forward_variables_from(invoker.extra_toolchain_args, "*")
-      }
-    }
-    android_ndk_lib_dir = invoker.android_ndk_lib_dir
-    tool_prefix = invoker.tool_prefix
     toolchain_cpu = invoker.toolchain_cpu
     is_clang = true
   }
 }
 
-android_gcc_toolchains_helper("x86") {
-  android_ndk_lib_dir = x86_android_lib
-
-  tool_prefix = "$llvm_android_toolchain_root/bin/i686-linux-android-"
+android_toolchains_helper("x86") {
   toolchain_cpu = "x86"
 }
 
-android_gcc_toolchains_helper("arm") {
-  android_ndk_lib_dir = arm_android_lib
-
-  tool_prefix = "$llvm_android_toolchain_root/bin/arm-linux-androideabi-"
+android_toolchains_helper("arm") {
   toolchain_cpu = "arm"
 }
 
-android_gcc_toolchains_helper("x64") {
-  android_ndk_lib_dir = x86_64_android_lib
-
-  tool_prefix = "$llvm_android_toolchain_root/bin/x86_64-linux-android-"
+android_toolchains_helper("x64") {
   toolchain_cpu = "x86_64"
 }
 
-android_gcc_toolchains_helper("arm64") {
-  android_ndk_lib_dir = arm64_android_lib
-
-  tool_prefix = "$llvm_android_toolchain_root/bin/aarch64-linux-android-"
+android_toolchains_helper("arm64") {
   toolchain_cpu = "aarch64"
 }
 
@@ -170,10 +137,7 @@
 # //third_party/vulkan_validation_layers. This is because vulkan validation
 # layers requires API level >= 26, but Flutter officially supports down to API
 # level 22, which is the default value of the android_api_level argument.
-android_gcc_toolchains_helper("arm64_apilevel26") {
-  android_ndk_lib_dir = arm64_android_lib
-
-  tool_prefix = "$llvm_android_toolchain_root/bin/aarch64-linux-android-"
+android_toolchains_helper("arm64_apilevel26") {
   toolchain_cpu = "arm64"
   extra_toolchain_args = {
     android_api_level = 26