GN: Android

Once you have downloaded an android NDK, you can set the ndk GN arg to use it.
E.g. my gn.args looks like:
  is_debug = false
  ndk = "/opt/android-ndk"

This should be enough to get you going for an arm64 build.  You ought to be able to tweak that to other architectures by changing target_cpu to "arm", "x86", "x86-64", etc.  That won't quite work until I follow this up a bit, but the skeleton is there.

This is enough to get me compiled, linked, and running to completion on my N5x.

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2275983004

Review-Url: https://codereview.chromium.org/2275983004
diff --git a/BUILD.gn b/BUILD.gn
index 90f531f..8c053cf 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -161,16 +161,16 @@
 
 is_x86 = current_cpu == "x64" || current_cpu == "x86"
 
-opts("armv7") {
-  enabled = current_cpu == "arm"
-  sources = opts_gypi.armv7_sources
+opts("none") {
+  enabled = !is_x86 && current_cpu != "arm" && current_cpu != "arm64"
+  sources = opts_gypi.none_sources
   cflags = []
 }
 
-opts("neon") {
+opts("armv7") {
   enabled = current_cpu == "arm"
-  sources = opts_gypi.neon_sources
-  cflags = [ "-mfpu=neon" ]
+  sources = opts_gypi.armv7_sources + opts_gypi.neon_sources
+  cflags = []
 }
 
 opts("arm64") {
@@ -185,12 +185,6 @@
   cflags = [ "-march=armv8-a+crc" ]
 }
 
-opts("none") {
-  enabled = !is_x86 && current_cpu != "arm" && current_cpu != "arm64"
-  sources = opts_gypi.none_sources
-  cflags = []
-}
-
 opts("sse2") {
   enabled = is_x86
   sources = opts_gypi.sse2_sources
@@ -342,7 +336,6 @@
     ":crc32",
     ":gif",
     ":jpeg",
-    ":neon",
     ":none",
     ":pdf",
     ":png",
@@ -354,10 +347,6 @@
     ":xml",
   ]
 
-  if (!is_win) {
-    libs = [ "pthread" ]
-  }
-
   sources = []
   sources += core_gypi.sources
   sources += effects_gypi.sources
@@ -401,6 +390,8 @@
     "src/gpu/gl/GrGLDefaultInterface_none.cpp",
   ]
 
+  libs = []
+
   if (is_win) {
     sources += [
       "src/ports/SkDebug_win.cpp",
@@ -418,17 +409,38 @@
     sources -= [ "src/utils/SkThreadUtils_pthread.cpp" ]
   } else {
     sources += [
-      "src/ports/SkDebug_stdio.cpp",
       "src/ports/SkOSFile_posix.cpp",
       "src/ports/SkTLS_pthread.cpp",
       "src/xps/SkDocument_XPS_None.cpp",
     ]
   }
 
+  if (is_android) {
+    deps += [
+      "//third_party/cpu-features",
+      "//third_party/expat",
+      "//third_party/freetype2",
+    ]
+    sources += [
+      "src/gpu/gl/android/GrGLCreateNativeInterface_android.cpp",
+      "src/ports/SkDebug_android.cpp",
+      "src/ports/SkFontHost_FreeType.cpp",
+      "src/ports/SkFontHost_FreeType_common.cpp",
+      "src/ports/SkFontMgr_android.cpp",
+      "src/ports/SkFontMgr_android_factory.cpp",
+      "src/ports/SkFontMgr_android_parser.cpp",
+    ]
+    libs += [
+      "EGL",
+      "GLESv2",
+      "log",
+    ]
+  }
+
   if (is_linux) {
     deps += [
       "third_party:fontconfig",
-      "third_party:freetype2",
+      "//third_party/freetype2",
     ]
     libs += [
       "GL",
@@ -437,6 +449,7 @@
     ]
     sources += [
       "src/gpu/gl/glx/GrGLCreateNativeInterface_glx.cpp",
+      "src/ports/SkDebug_stdio.cpp",
       "src/ports/SkFontConfigInterface_direct.cpp",
       "src/ports/SkFontConfigInterface_direct_factory.cpp",
       "src/ports/SkFontHost_FreeType.cpp",
@@ -450,6 +463,7 @@
   if (is_mac) {
     sources += [
       "src/gpu/gl/mac/GrGLCreateNativeInterface_mac.cpp",
+      "src/ports/SkDebug_stdio.cpp",
       "src/ports/SkFontHost_mac.cpp",
       "src/ports/SkImageEncoder_CG.cpp",
       "src/ports/SkImageGeneratorCG.cpp",
@@ -463,6 +477,7 @@
   if (is_fuchsia) {
     sources += [
       "src/gpu/gl/GrGLCreateNativeInterface_none.cpp",
+      "src/ports/SkDebug_stdio.cpp",
       "src/ports/SkFontMgr_empty_factory.cpp",
     ]
   }
@@ -547,7 +562,9 @@
     ]
     libs = []
 
-    if (is_linux) {
+    if (is_android) {
+      sources += [ "tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp" ]
+    } else if (is_linux) {
       sources += [ "tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp" ]
     } else if (is_mac) {
       sources += [ "tools/gpu/gl/mac/CreatePlatformGLTestContext_mac.cpp" ]
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index fecca8e..0a56fa2 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -7,6 +7,11 @@
   cc = "cc"
   cxx = "c++"
 
+  if (is_android) {
+    cc = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang"
+    cxx = "$ndk/toolchains/llvm/prebuilt/$ndk_host/bin/clang++"
+  }
+
   extra_cflags = ""
   extra_cflags_c = ""
   extra_cflags_cc = ""
@@ -42,6 +47,41 @@
 
     "-Wnon-virtual-dtor",
   ]
+  if (current_cpu == "arm") {
+    cflags += [ "-mfpu=neon" ]
+  }
+
+  if (is_android) {
+    asmflags = [ "--target=$ndk_target" ]
+    cflags += [
+      "--sysroot=$ndk/platforms/$ndk_platform",
+      "--target=$ndk_target",
+    ]
+    cflags_cc += [
+      "-isystem$ndk/sources/android/support/include",
+      "-isystem$ndk/sources/cxx-stl/llvm-libc++/libcxx/include",
+    ]
+    ldflags = [
+      "--sysroot=$ndk/platforms/$ndk_platform",
+      "--target=$ndk_target",
+      "-B$ndk/toolchains/$ndk_target-4.9/prebuilt/$ndk_host/$ndk_target/bin",
+      "-pie",
+    ]
+    lib_dirs = [
+      "$ndk/sources/cxx-stl/llvm-libc++/libs/$ndk_stdlib",
+      "$ndk/toolchains/$ndk_target-4.9/prebuilt/$ndk_host/lib/gcc/$ndk_target/4.9.x",
+    ]
+    libs = [
+      # Order matters here!  Keep these three in exactly this order.
+      "c++_static",
+      "c++abi",
+      "android_support",
+    ]
+  }
+
+  if (is_linux) {
+    libs = [ "pthread" ]
+  }
 }
 
 config("release") {
diff --git a/gn/BUILDCONFIG.gn b/gn/BUILDCONFIG.gn
index d683357..6aa4451 100644
--- a/gn/BUILDCONFIG.gn
+++ b/gn/BUILDCONFIG.gn
@@ -8,11 +8,15 @@
 declare_args() {
   is_debug = true
   is_component_build = false
+  ndk = ""
 }
 
 # Platform detection
 if (target_os == "") {
   target_os = host_os
+  if (ndk != "") {
+    target_os = "android"
+  }
 }
 if (current_os == "") {
   current_os = target_os
@@ -20,6 +24,9 @@
 
 if (target_cpu == "") {
   target_cpu = host_cpu
+  if (ndk != "") {
+    target_cpu = "arm64"
+  }
 }
 if (current_cpu == "") {
   current_cpu = target_cpu
@@ -34,6 +41,22 @@
 
 is_posix = !is_win
 
+if (is_android) {
+  ndk_host = ""
+  ndk_target = ""
+  ndk_platform = ""
+  ndk_stdlib = ""
+
+  if (host_os == "linux" && host_cpu == "x64") {
+    ndk_host = "linux-x86_64"
+  }
+  if (target_cpu == "arm64") {
+    ndk_target = "aarch64-linux-android"
+    ndk_platform = "android-21/arch-arm64"
+    ndk_stdlib = "arm64-v8a"
+  }
+}
+
 # A component is either a static or a shared library.
 template("component") {
   _component_mode = "static_library"
diff --git a/src/core/SkCpu.cpp b/src/core/SkCpu.cpp
index 0f1c751..24333b7 100644
--- a/src/core/SkCpu.cpp
+++ b/src/core/SkCpu.cpp
@@ -59,7 +59,7 @@
 #elif defined(SK_CPU_ARM32)         && \
       defined(SK_BUILD_FOR_ANDROID) && \
      !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
-    #include <cpu-features.h>
+    #include "cpu-features.h"
 
     static uint32_t read_cpu_features() {
         uint32_t features = 0;
@@ -74,7 +74,7 @@
 #elif defined(SK_CPU_ARM64)         && \
       defined(SK_BUILD_FOR_ANDROID) && \
      !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK)
-    #include <cpu-features.h>
+    #include "cpu-features.h"
 
     static uint32_t read_cpu_features() {
         uint32_t features = 0;
diff --git a/third_party/BUILD.gn b/third_party/BUILD.gn
index 49d9f56..63fa748 100644
--- a/third_party/BUILD.gn
+++ b/third_party/BUILD.gn
@@ -6,14 +6,6 @@
 declare_args() {
 }
 
-config("system_freetype2") {
-  include_dirs = [ "/usr/include/freetype2" ]
-  libs = [ "freetype" ]
-}
-group("freetype2") {
-  public_configs = [ ":system_freetype2" ]
-}
-
 config("system_fontconfig") {
   libs = [ "fontconfig" ]
 }
diff --git a/third_party/cpu-features/BUILD.gn b/third_party/cpu-features/BUILD.gn
new file mode 100644
index 0000000..d1f6fad
--- /dev/null
+++ b/third_party/cpu-features/BUILD.gn
@@ -0,0 +1,17 @@
+# Copyright 2016 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+declare_args() {
+}
+
+import("../third_party.gni")
+
+third_party("cpu-features") {
+  public_include_dirs = [ "$ndk/sources/android/cpufeatures" ]
+
+  sources = [
+    "$ndk/sources/android/cpufeatures/cpu-features.c",
+  ]
+}
diff --git a/third_party/freetype2/BUILD.gn b/third_party/freetype2/BUILD.gn
new file mode 100644
index 0000000..623c47e
--- /dev/null
+++ b/third_party/freetype2/BUILD.gn
@@ -0,0 +1,63 @@
+# Copyright 2016 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+declare_args() {
+}
+
+import("../third_party.gni")
+
+if (is_android) {
+  third_party("freetype2") {
+    public_include_dirs = [ "../externals/freetype/include" ]
+
+    deps = [
+      "//third_party/libpng",
+    ]
+
+    include_dirs = [ "../freetype" ]
+    defines = [
+      "FT2_BUILD_LIBRARY",
+      "FT_CONFIG_MODULES_H=<include/freetype-android/ftmodule.h>",
+      "FT_CONFIG_OPTIONS_H=<include/freetype-android/ftoption.h>",
+    ]
+
+    sources = [
+      "../externals/freetype/src/autofit/autofit.c",
+      "../externals/freetype/src/base/ftbase.c",
+      "../externals/freetype/src/base/ftbbox.c",
+      "../externals/freetype/src/base/ftbitmap.c",
+      "../externals/freetype/src/base/ftdebug.c",
+      "../externals/freetype/src/base/ftfntfmt.c",
+      "../externals/freetype/src/base/ftfstype.c",
+      "../externals/freetype/src/base/ftgasp.c",
+      "../externals/freetype/src/base/ftglyph.c",
+      "../externals/freetype/src/base/ftinit.c",
+      "../externals/freetype/src/base/ftlcdfil.c",
+      "../externals/freetype/src/base/ftmm.c",
+      "../externals/freetype/src/base/ftpatent.c",
+      "../externals/freetype/src/base/ftstroke.c",
+      "../externals/freetype/src/base/ftsynth.c",
+      "../externals/freetype/src/base/ftsystem.c",
+      "../externals/freetype/src/base/fttype1.c",
+      "../externals/freetype/src/base/ftwinfnt.c",
+      "../externals/freetype/src/cff/cff.c",
+      "../externals/freetype/src/gzip/ftgzip.c",
+      "../externals/freetype/src/pshinter/pshinter.c",
+      "../externals/freetype/src/psnames/psnames.c",
+      "../externals/freetype/src/raster/raster.c",
+      "../externals/freetype/src/sfnt/sfnt.c",
+      "../externals/freetype/src/smooth/smooth.c",
+      "../externals/freetype/src/truetype/truetype.c",
+    ]
+  }
+} else {
+  config("system_freetype2") {
+    include_dirs = [ "/usr/include/freetype2" ]
+    libs = [ "freetype" ]
+  }
+  group("freetype2") {
+    public_configs = [ ":system_freetype2" ]
+  }
+}
diff --git a/third_party/icu/BUILD.gn b/third_party/icu/BUILD.gn
index e213760..e7a55b5 100644
--- a/third_party/icu/BUILD.gn
+++ b/third_party/icu/BUILD.gn
@@ -199,9 +199,5 @@
     "../externals/icu/source/common/uvectr64.cpp",
     "../externals/icu/source/common/wintz.c",
   ]
-  if (is_linux) {
-    sources += [ "../externals/icu/linux/icudtl_dat.S" ]
-  } else if (is_mac) {
-    sources += [ "../externals/icu/mac/icudtl_dat.S" ]
-  }
+  sources += [ "../externals/icu/$current_os/icudtl_dat.S" ]
 }
diff --git a/third_party/libpng/BUILD.gn b/third_party/libpng/BUILD.gn
index 76c0027..5cd8655 100644
--- a/third_party/libpng/BUILD.gn
+++ b/third_party/libpng/BUILD.gn
@@ -31,4 +31,11 @@
     "pngwtran.c",
     "pngwutil.c",
   ]
+
+  if (current_cpu == "arm" || current_cpu == "arm64") {
+    sources += [
+      "arm/arm_init.c",
+      "arm/filter_neon_intrinsics.c",
+    ]
+  }
 }
diff --git a/third_party/libwebp/BUILD.gn b/third_party/libwebp/BUILD.gn
index efac7d2..7f7901e 100644
--- a/third_party/libwebp/BUILD.gn
+++ b/third_party/libwebp/BUILD.gn
@@ -41,22 +41,28 @@
     "../externals/libwebp/src/dsp/cpu.c",
     "../externals/libwebp/src/dsp/dec.c",
     "../externals/libwebp/src/dsp/dec_clip_tables.c",
+    "../externals/libwebp/src/dsp/dec_neon.c",
     "../externals/libwebp/src/dsp/dec_sse2.c",
     "../externals/libwebp/src/dsp/dec_sse41.c",
     "../externals/libwebp/src/dsp/enc.c",
     "../externals/libwebp/src/dsp/enc_avx2.c",
+    "../externals/libwebp/src/dsp/enc_neon.c",
     "../externals/libwebp/src/dsp/enc_sse2.c",
     "../externals/libwebp/src/dsp/enc_sse41.c",
     "../externals/libwebp/src/dsp/filters.c",
     "../externals/libwebp/src/dsp/filters_sse2.c",
     "../externals/libwebp/src/dsp/lossless.c",
     "../externals/libwebp/src/dsp/lossless_enc.c",
+    "../externals/libwebp/src/dsp/lossless_enc_neon.c",
     "../externals/libwebp/src/dsp/lossless_enc_sse2.c",
     "../externals/libwebp/src/dsp/lossless_enc_sse41.c",
+    "../externals/libwebp/src/dsp/lossless_neon.c",
     "../externals/libwebp/src/dsp/lossless_sse2.c",
     "../externals/libwebp/src/dsp/rescaler.c",
+    "../externals/libwebp/src/dsp/rescaler_neon.c",
     "../externals/libwebp/src/dsp/rescaler_sse2.c",
     "../externals/libwebp/src/dsp/upsampling.c",
+    "../externals/libwebp/src/dsp/upsampling_neon.c",
     "../externals/libwebp/src/dsp/upsampling_sse2.c",
     "../externals/libwebp/src/dsp/yuv.c",
     "../externals/libwebp/src/dsp/yuv_sse2.c",
diff --git a/third_party/sfntly/BUILD.gn b/third_party/sfntly/BUILD.gn
index a9bf925..845c6ed 100644
--- a/third_party/sfntly/BUILD.gn
+++ b/third_party/sfntly/BUILD.gn
@@ -14,7 +14,6 @@
   deps = [
     "//third_party/icu",
   ]
-  libs = [ "pthread" ]
   sources = [
     "../externals/sfntly/cpp/src/sample/chromium/font_subsetter.cc",
     "../externals/sfntly/cpp/src/sample/chromium/subsetter_impl.cc",