GN: iOS basics

This doesn't create any apps or bundles or sign anything, but it all compiles and links.

Note the awkward transitional hack I used to make each tool's tool_main() serve as the real main() again when built with GN, while keeping the existing setup with GYP.  Fun...

BUG=skia:

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

Change-Id: I632753d5d8e5848380854f413bf5905d676bfcf4
Reviewed-on: https://skia-review.googlesource.com/4350
Reviewed-by: Jim Van Verth <jvanverth@google.com>
Commit-Queue: Mike Klein <mtklein@chromium.org>
diff --git a/BUILD.gn b/BUILD.gn
index 40f7729..f089dc5 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -16,7 +16,7 @@
   skia_use_fontconfig = is_linux
   skia_use_freetype = is_android || is_fuchsia || is_linux
   skia_use_gdi = false
-  skia_use_icu = !is_fuchsia && !is_win  # TODO: Windows
+  skia_use_icu = !is_fuchsia && !is_ios && !is_win  # TODO: Windows
   skia_use_libjpeg_turbo = true
   skia_use_libpng = true
   skia_use_libwebp = !is_fuchsia
@@ -662,6 +662,22 @@
     ]
   }
 
+  if (is_ios) {
+    sources += [
+      "src/ports/SkDebug_stdio.cpp",
+      "src/ports/SkFontHost_mac.cpp",
+      "src/ports/SkImageEncoder_CG.cpp",
+      "src/ports/SkImageGeneratorCG.cpp",
+    ]
+    libs += [
+      "CoreFoundation.framework",
+      "CoreGraphics.framework",
+      "CoreText.framework",
+      "ImageIO.framework",
+      "MobileCoreServices.framework",
+    ]
+  }
+
   if (is_fuchsia) {
     sources += [ "src/ports/SkDebug_stdio.cpp" ]
   }
@@ -750,6 +766,9 @@
 
       if (is_android) {
         sources += [ "tools/gpu/gl/egl/CreatePlatformGLTestContext_egl.cpp" ]
+      } else if (is_ios) {
+        sources += [ "tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm" ]
+        libs += [ "OpenGLES.framework" ]
       } else if (is_linux) {
         sources += [ "tools/gpu/gl/glx/CreatePlatformGLTestContext_glx.cpp" ]
       } else if (is_mac) {
@@ -1056,8 +1075,8 @@
     }
   }
 
-  # We can't yet build ICU on Windows.
-  if (!is_win) {
+  # We can't yet build ICU on iOS or Windows.
+  if (!is_ios && !is_win) {
     executable("sktexttopdf-hb") {
       sources = [
         "tools/SkShaper_harfbuzz.cpp",
@@ -1093,37 +1112,39 @@
     testonly = true
   }
 
-  executable("skiaserve") {
-    sources = [
-      "tools/skiaserve/Request.cpp",
-      "tools/skiaserve/Response.cpp",
-      "tools/skiaserve/skiaserve.cpp",
-      "tools/skiaserve/urlhandlers/BatchBoundsHandler.cpp",
-      "tools/skiaserve/urlhandlers/BatchesHandler.cpp",
-      "tools/skiaserve/urlhandlers/BreakHandler.cpp",
-      "tools/skiaserve/urlhandlers/ClipAlphaHandler.cpp",
-      "tools/skiaserve/urlhandlers/CmdHandler.cpp",
-      "tools/skiaserve/urlhandlers/ColorModeHandler.cpp",
-      "tools/skiaserve/urlhandlers/DataHandler.cpp",
-      "tools/skiaserve/urlhandlers/DownloadHandler.cpp",
-      "tools/skiaserve/urlhandlers/EnableGPUHandler.cpp",
-      "tools/skiaserve/urlhandlers/ImgHandler.cpp",
-      "tools/skiaserve/urlhandlers/InfoHandler.cpp",
-      "tools/skiaserve/urlhandlers/OverdrawHandler.cpp",
-      "tools/skiaserve/urlhandlers/PostHandler.cpp",
-      "tools/skiaserve/urlhandlers/QuitHandler.cpp",
-      "tools/skiaserve/urlhandlers/RootHandler.cpp",
-    ]
-    deps = [
-      ":flags",
-      ":gpu_tool_utils",
-      ":skia",
-      ":tool_utils",
-      "//third_party/jsoncpp",
-      "//third_party/libmicrohttpd",
-      "//third_party/libpng",
-    ]
-    testonly = true
+  if (!is_ios) {
+    executable("skiaserve") {
+      sources = [
+        "tools/skiaserve/Request.cpp",
+        "tools/skiaserve/Response.cpp",
+        "tools/skiaserve/skiaserve.cpp",
+        "tools/skiaserve/urlhandlers/BatchBoundsHandler.cpp",
+        "tools/skiaserve/urlhandlers/BatchesHandler.cpp",
+        "tools/skiaserve/urlhandlers/BreakHandler.cpp",
+        "tools/skiaserve/urlhandlers/ClipAlphaHandler.cpp",
+        "tools/skiaserve/urlhandlers/CmdHandler.cpp",
+        "tools/skiaserve/urlhandlers/ColorModeHandler.cpp",
+        "tools/skiaserve/urlhandlers/DataHandler.cpp",
+        "tools/skiaserve/urlhandlers/DownloadHandler.cpp",
+        "tools/skiaserve/urlhandlers/EnableGPUHandler.cpp",
+        "tools/skiaserve/urlhandlers/ImgHandler.cpp",
+        "tools/skiaserve/urlhandlers/InfoHandler.cpp",
+        "tools/skiaserve/urlhandlers/OverdrawHandler.cpp",
+        "tools/skiaserve/urlhandlers/PostHandler.cpp",
+        "tools/skiaserve/urlhandlers/QuitHandler.cpp",
+        "tools/skiaserve/urlhandlers/RootHandler.cpp",
+      ]
+      deps = [
+        ":flags",
+        ":gpu_tool_utils",
+        ":skia",
+        ":tool_utils",
+        "//third_party/jsoncpp",
+        "//third_party/libmicrohttpd",
+        "//third_party/libpng",
+      ]
+      testonly = true
+    }
   }
 
   executable("fuzz") {
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index 81813a3..a39217e 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -46,6 +46,10 @@
                          "value")
 }
 
+if (is_ios) {
+  ios_sysroot = exec_script("find_ios_sysroot.py", [], "trim string")
+}
+
 config("default") {
   asmflags = []
   cflags = []
@@ -178,6 +182,31 @@
     }
   }
 
+  if (is_ios) {
+    cflags += [
+      "--sysroot=$ios_sysroot",
+      "--target=$target_cpu-apple-darwin11",
+    ]
+    cflags_cc += [ "-stdlib=libc++" ]
+    ldflags += [
+      "--sysroot=$ios_sysroot",
+      "--target=$target_cpu-apple-darwin11",
+      "-stdlib=libc++",
+    ]
+    libs = [ "objc" ]
+
+    # We used to link all our iOS tools together, so none actually defines main().
+    # Instead they each define their own entry point, which our iOS mega-app called.
+    # If we can we'd like to not do that anymore.  While we're building both ways, here's
+    # our clever hack to give each tool back its own main().
+    cflags += [
+      "-Ddm_main=main",
+      "-Dnanobench_main=main",
+      "-Dtool_main=main",
+      "-Dtest_main=main",
+    ]
+  }
+
   if (is_linux) {
     libs = [ "pthread" ]
   }
diff --git a/gn/BUILDCONFIG.gn b/gn/BUILDCONFIG.gn
index 9a995bb..4ed5668 100644
--- a/gn/BUILDCONFIG.gn
+++ b/gn/BUILDCONFIG.gn
@@ -40,7 +40,7 @@
 
 if (target_cpu == "") {
   target_cpu = host_cpu
-  if (is_android) {
+  if (is_android || is_ios) {
     target_cpu = "arm64"
   }
 }
diff --git a/gn/find_ios_sysroot.py b/gn/find_ios_sysroot.py
new file mode 100644
index 0000000..2d9f8d6
--- /dev/null
+++ b/gn/find_ios_sysroot.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python
+#
+# Copyright 2016 Google Inc.
+#
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import subprocess
+
+print subprocess.check_output('xcrun --sdk iphoneos --show-sdk-path'.split())
diff --git a/include/views/SkOSWindow_iOS.h b/include/views/SkOSWindow_iOS.h
index c0b2fc3..3b540cf 100644
--- a/include/views/SkOSWindow_iOS.h
+++ b/include/views/SkOSWindow_iOS.h
@@ -37,7 +37,7 @@
     virtual void onHandleInval(const SkIRect&);
     // overrides from SkView
     virtual void onAddMenu(const SkOSMenu*);
-    virtual void onUpdateMenu(SkOSMenu*);
+    virtual void onUpdateMenu(const SkOSMenu*);
     virtual void onSetTitle(const char[]);
 
 private:
diff --git a/src/views/ios/SkOSWindow_iOS.mm b/src/views/ios/SkOSWindow_iOS.mm
index aa7d375..3e29371 100755
--- a/src/views/ios/SkOSWindow_iOS.mm
+++ b/src/views/ios/SkOSWindow_iOS.mm
@@ -53,7 +53,7 @@
     [(SkUIView*)fHWND onAddMenu:menu];
 }
 
-void SkOSWindow::onUpdateMenu(SkOSMenu* menu) {
+void SkOSWindow::onUpdateMenu(const SkOSMenu* menu) {
     [(SkUIView*)fHWND onUpdateMenu:menu];
 }
 
diff --git a/tests/StreamTest.cpp b/tests/StreamTest.cpp
index ca750d1..b99b001 100644
--- a/tests/StreamTest.cpp
+++ b/tests/StreamTest.cpp
@@ -192,6 +192,7 @@
     TestNullData();
 }
 
+#ifndef SK_BUILD_FOR_IOS
 /**
  *  Tests peeking and then reading the same amount. The two should provide the
  *  same results.
@@ -285,7 +286,6 @@
 // This test uses file system operations that don't work out of the
 // box on iOS. It's likely that we don't need them on iOS. Ignoring for now.
 // TODO(stephana): Re-evaluate if we need this in the future.
-#ifndef SK_BUILD_FOR_IOS
 DEF_TEST(StreamPeek, reporter) {
     // Test a memory stream.
     const char gAbcs[] = "abcdefghijklmnopqrstuvwxyz";
diff --git a/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm b/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm
index d31cb86..f2bcd5d 100644
--- a/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm
+++ b/tools/gpu/gl/iOS/CreatePlatformGLTestContext_iOS.mm
@@ -6,7 +6,7 @@
  * found in the LICENSE file.
  */
 
-#include "GLTestContext.h"
+#include "gl/GLTestContext.h"
 #import <OpenGLES/EAGL.h>
 #include <dlfcn.h>