Move build -> gn/standalone

Make it explicit that those gn files are only for the standalone
build.

Bug: 68710794
Change-Id: I7e2a15219d63b62bf8f249becfdbf39fda2cc183
diff --git a/gn/BUILD.gn b/gn/BUILD.gn
index 92fba54..41b5217 100644
--- a/gn/BUILD.gn
+++ b/gn/BUILD.gn
@@ -83,8 +83,8 @@
   public_configs = [ ":default_config" ]
   if (!build_with_chromium) {
     public_deps = [
-      "//build/libc++:deps",
-      "//build/sanitizers:deps",
+      "//gn/standalone/libc++:deps",
+      "//gn/standalone/sanitizers:deps",
     ]
   }
 }
diff --git a/gn/proto_library.gni b/gn/proto_library.gni
index 97b95d2..3ccdeab 100644
--- a/gn/proto_library.gni
+++ b/gn/proto_library.gni
@@ -15,9 +15,7 @@
 import("//build_overrides/build.gni")
 
 if (!build_with_chromium) {
-  # TODO(primiano): Just move //build/proto_library.gni inside this branch,
-  # there is no need to have that in //build at this point.
-  import("//build/proto_library.gni")
+  import("//gn/standalone/proto_library.gni")
 } else {
   import("//third_party/protobuf/proto_library.gni")
 }
diff --git a/gn/standalone/BUILD.gn b/gn/standalone/BUILD.gn
new file mode 100644
index 0000000..59f60fd
--- /dev/null
+++ b/gn/standalone/BUILD.gn
@@ -0,0 +1,200 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/android.gni")
+import("//gn/standalone/sanitizers/sanitizers.gni")
+
+config("extra_warnings") {
+  cflags = [
+    "-Wextra",
+    "-Wno-missing-field-initializers",
+    "-Wno-unused-parameter",
+  ]
+  if (is_clang) {
+    cflags += [
+      "-Weverything",
+      "-Wno-c++98-compat-pedantic",
+      "-Wno-c++98-compat",
+      "-Wno-gnu-include-next",
+      "-Wno-gnu-statement-expression",
+      "-Wno-gnu-zero-variadic-macro-arguments",
+      "-Wno-padded",
+      "-Wno-reserved-id-macro",
+      "-Wno-weak-vtables",
+    ]
+  }
+}
+
+config("no_exceptions") {
+  cflags = [ "-fno-exceptions" ]
+}
+
+config("no_rtti") {
+  cflags = [ "-fno-rtti" ]
+}
+
+config("default") {
+  asmflags = []
+  cflags = []
+  cflags_c = []
+  cflags_cc = []
+  defines = []
+  ldflags = []
+  libs = []
+
+  cflags_cc += [ "-std=c++11" ]
+
+  cflags += [
+    "-fstrict-aliasing",
+    "-fstack-protector",
+    "-fPIC",
+    "-Wa,--noexecstack",
+    "-Wformat",
+    "-Wall",
+    "-Werror",
+  ]
+
+  # Color compiler output, see https://github.com/ninja-build/ninja/wiki/FAQ
+  if (is_clang) {
+    cflags += [
+      "-fcolor-diagnostics",
+      "-Wno-unknown-warning-option",
+    ]
+  } else {
+    cflags += [ "-Wno-unknown-warning" ]
+  }
+
+  if (current_cpu == "arm") {
+    cflags += [
+      "-march=armv7-a",
+      "-mfpu=neon",
+      "-mthumb",
+    ]
+  } else if (current_cpu == "x86") {
+    asmflags += [ "-m32" ]
+    cflags += [
+      "-m32",
+      "-msse2",
+      "-mfpmath=sse",
+    ]
+    ldflags += [ "-m32" ]
+  }
+
+  if (is_linux) {
+    libs += [
+      "pthread",
+      "rt",
+    ]
+  }
+
+  if (is_android) {
+    libs += [ "log" ]
+  }
+
+  if (is_android) {
+    asmflags += [ "--target=$android_abi_target" ]
+    cflags += [
+      "--sysroot=$android_compile_sysroot",
+      "-isystem$android_compile_sysroot/$android_compile_sysroot_subdir",
+      "-isystem$android_compile_sysroot",
+      "-DANDROID",
+      "-D__ANDROID_API__=21",
+      "--target=$android_abi_target",
+    ]
+    cflags_cc += [
+      "-I$android_ndk_root/sources/cxx-stl/llvm-libc++/include",
+      "-I$android_ndk_root/sources/android/support/include",
+      "-I$android_ndk_root/sources/cxx-stl/llvm-libc++abi/include",
+    ]
+    ldflags += [
+      "-Wl,-z,nocopyreloc",
+      "-gcc-toolchain",
+      "$android_toolchain_root",
+      "--sysroot=$android_ndk_root/$android_link_sysroot_subdir",
+      "--target=$android_abi_target",
+      "-Wl,--exclude-libs,libunwind.a",
+      "-Wl,--exclude-libs,libgcc.a",
+      "-Wl,--exclude-libs,libc++_static.a",
+      "-Wl,--build-id",
+      "-Wl,--no-undefined",
+      "-Wl,-z,noexecstack",
+      "-Wl,-z,relro",
+      "-Wl,-z,now",
+      "-Wl,--warn-shared-textrel",
+      "-Wl,--fatal-warnings",
+    ]
+    lib_dirs = [ "$android_ndk_root/sources/cxx-stl/llvm-libc++/libs/$android_app_abi" ]
+    libs += [
+      "gcc",
+      "c++_static",
+      "c++abi",
+      "android_support",
+    ]
+  }
+}
+
+config("debug_symbols") {
+  if (is_android) {
+    cflags = [
+      "-gline-tables-only",
+      "-funwind-tables",
+    ]
+  } else {
+    cflags = [ "-g2" ]
+  }
+}
+
+config("release") {
+  cflags = [
+    "-O3",
+    "-fdata-sections",
+    "-ffunction-sections",
+  ]
+  if (is_mac) {
+    ldflags = [ "-dead_strip" ]
+  } else {
+    ldflags = [ "-Wl,--gc-sections" ]
+  }
+  defines = [ "NDEBUG" ]
+}
+
+config("shared_library") {
+  if (is_android || is_linux) {
+    ldflags = [ "-fPIC" ]
+  }
+}
+
+config("executable") {
+  ldflags = []
+
+  # Android will refuse to run executables if they aren't position independent.
+  # Instead on Linux there isn't any need and they break ASan (goo.gl/paFR6K).
+  if (is_android) {
+    asmflags = [ "-fPIE" ]
+    cflags = [ "-fPIE" ]
+    ldflags += [ "-pie" ]
+  }
+
+  # -rpath stores the path to the linked shared libraries into the binary, so
+  # that they can be launched without passing any LD_LIBRARY_PATH. It's
+  # supported only by Linux, not Android. But concretely we need this only when
+  # use_custom_libcxx=true && custom_libcxx_is_static=false, which happens only
+  # on Linux right now.
+  if (is_linux) {
+    ldflags += [
+      "-Wl,-rpath=\$ORIGIN/.",
+      "-Wl,-rpath-link=.",
+    ]
+  }
+}
diff --git a/gn/standalone/BUILDCONFIG.gn b/gn/standalone/BUILDCONFIG.gn
new file mode 100644
index 0000000..b1d103f
--- /dev/null
+++ b/gn/standalone/BUILDCONFIG.gn
@@ -0,0 +1,83 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare_args() {
+  is_debug = true
+  is_clang = true
+}
+
+declare_args() {
+  ar = "ar"
+}
+
+# Platform detection
+if (target_os == "") {
+  target_os = host_os
+}
+if (current_os == "") {
+  current_os = target_os
+}
+
+is_android = current_os == "android"
+is_linux = current_os == "linux"
+is_linux_host = host_os == "linux"
+is_mac = current_os == "mac"
+
+if (target_cpu == "") {
+  target_cpu = host_cpu
+  if (is_android) {
+    target_cpu = "arm"
+  }
+}
+if (current_cpu == "") {
+  current_cpu = target_cpu
+}
+
+default_configs = [
+  "//gn/standalone:debug_symbols",
+  "//gn/standalone:default",
+  "//gn/standalone:extra_warnings",
+  "//gn/standalone:no_exceptions",
+  "//gn/standalone:no_rtti",
+  "//gn/standalone/libc++:config",
+  "//gn/standalone/sanitizers:sanitizers_cflags",
+]
+
+if (!is_debug) {
+  default_configs += [ "//gn/standalone:release" ]
+}
+
+set_defaults("source_set") {
+  configs = default_configs
+}
+
+set_defaults("static_library") {
+  configs = default_configs
+}
+
+# Realistically the only shared_library that we build right now is libc++.so
+# when use_custom_libcxx=true (on Linux). Hence don't add a dependency on
+# libc++ itself on these targets.
+set_defaults("shared_library") {
+  configs = default_configs
+  configs += [ "//gn/standalone:shared_library" ]
+}
+
+set_defaults("executable") {
+  configs = default_configs
+  configs += [ "//gn/standalone:executable" ]
+}
+
+set_default_toolchain("//gn/standalone/toolchain:gcc_like")
+host_toolchain = "//gn/standalone/toolchain:gcc_like_host"
diff --git a/gn/standalone/android.gni b/gn/standalone/android.gni
new file mode 100644
index 0000000..e339eb2
--- /dev/null
+++ b/gn/standalone/android.gni
@@ -0,0 +1,81 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare_args() {
+  android_api_level = 21
+  android_ndk_root = rebase_path("//buildtools/ndk")
+  _android_toolchain_version = "4.9"
+
+  if (host_os == "linux") {
+    android_host = "linux-x86_64"
+  } else if (host_os == "mac") {
+    android_host = "darwin-x86_64"
+  } else {
+    assert(false, "Need Android toolchain support for your build OS.")
+  }
+}
+
+declare_args() {
+  android_llvm_dir = "$android_ndk_root/toolchains/llvm/prebuilt/$android_host"
+  android_clangrt_dir = "$android_llvm_dir/lib64/clang/5.0/lib/linux"
+  android_compile_sysroot = "$android_ndk_root/sysroot/usr/include"
+
+  if (current_cpu == "x86") {
+    android_abi_target = "i686-linux-androideabi"
+    android_compile_sysroot_subdir = "i686-linux-android"
+    android_link_sysroot_subdir =
+        "platforms/android-${android_api_level}/arch-x86"
+    android_prebuilt_arch = "android-x86"
+    android_toolchain_root = "$android_ndk_root/toolchains/x86-${_android_toolchain_version}/prebuilt/$android_host"
+    android_llvm_arch = "i686"
+  } else if (current_cpu == "arm") {
+    android_abi_target = "arm-linux-androideabi"
+    android_compile_sysroot_subdir = "arm-linux-androideabi"
+    android_link_sysroot_subdir =
+        "platforms/android-${android_api_level}/arch-arm"
+    android_prebuilt_arch = "android-arm"
+    android_toolchain_root = "$android_ndk_root/toolchains/arm-linux-androideabi-${_android_toolchain_version}/prebuilt/$android_host"
+    android_llvm_arch = "arm"
+  } else if (current_cpu == "x64") {
+    android_abi_target = "x86_64-linux-androideabi"
+    android_compile_sysroot_subdir = "x86_64-linux-android"
+    android_link_sysroot_subdir =
+        "platforms/android-${android_api_level}/arch-x86_64"
+    android_prebuilt_arch = "android-x86_64"
+    android_toolchain_root = "$android_ndk_root/toolchains/x86_64-${_android_toolchain_version}/prebuilt/$android_host"
+    android_llvm_arch = "x86_64"
+  } else if (current_cpu == "arm64") {
+    android_abi_target = "aarch64-linux-android"
+    android_compile_sysroot_subdir = "aarch64-linux-android"
+    android_link_sysroot_subdir =
+        "platforms/android-${android_api_level}/arch-arm64"
+    android_prebuilt_arch = "android-arm64"
+    android_toolchain_root = "$android_ndk_root/toolchains/aarch64-linux-android-${_android_toolchain_version}/prebuilt/$android_host"
+    android_llvm_arch = "aarch64"
+  } else {
+    assert(false, "Need android libgcc support for this arch.")
+  }
+
+  if (current_cpu == "x86") {
+    android_app_abi = "x86"
+  } else if (current_cpu == "arm") {
+    android_app_abi = "armeabi-v7a"
+  } else if (current_cpu == "x64") {
+    android_app_abi = "x86_64"
+  } else if (current_cpu == "arm64") {
+    android_app_abi = "arm64-v8a"
+  } else {
+    assert(false, "Unknown ABI: " + current_cpu)
+  }
+}
diff --git a/gn/standalone/build_tool_wrapper.py b/gn/standalone/build_tool_wrapper.py
new file mode 100644
index 0000000..5b2f740
--- /dev/null
+++ b/gn/standalone/build_tool_wrapper.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+""" Wrapper to invoke compiled build tools from the build system.
+
+This is just a workaround for GN assuming that all external scripts are
+python sources. It is used to invoke the built protoc compiler.
+"""
+
+import os
+import sys
+
+def main():
+  cmd = sys.argv[1:]
+  if not os.path.exists(cmd[0]):
+    print >> sys.stderr, 'Cannot find ' + cmd[0]
+    return 1
+  os.execv(cmd[0], cmd)
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/gn/standalone/libc++/BUILD.gn b/gn/standalone/libc++/BUILD.gn
new file mode 100644
index 0000000..a8ccba1
--- /dev/null
+++ b/gn/standalone/libc++/BUILD.gn
@@ -0,0 +1,49 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("libc++.gni")
+
+config("config") {
+  if (use_custom_libcxx) {
+    defines = [
+      "_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS",
+      "_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS",
+    ]
+    cflags_cc = [
+      "-nostdinc++",
+      "-isystem" + rebase_path("$libcxx_prefix/include", root_build_dir),
+      "-isystem" + rebase_path("$libcxxabi_prefix/include", root_build_dir),
+    ]
+
+    # In theory here we want just -nostdlib++ to avoid linking both libc++ and
+    # libstdc++. Unfortunately the -nostdlib++ switch is available only in
+    # bleeding edge versions of clang. So, in order to get rid of libstdc++
+    # we have to remove all libs and then re-add the core ones like libc.
+    ldflags = [ "-nodefaultlibs" ]
+    libs = [
+      "c",  # libc: the core C library.
+      "m",  # libm: math library.
+      "dl",  # libdl: dynamic linking.
+      "gcc_eh",  # gcc exception handling, required by libunwind.
+    ]
+  }
+}
+
+group("deps") {
+  if (use_custom_libcxx) {
+    public_deps = [
+      "//buildtools:libc++",
+    ]
+  }
+}
diff --git a/gn/standalone/libc++/libc++.gni b/gn/standalone/libc++/libc++.gni
new file mode 100644
index 0000000..3306590
--- /dev/null
+++ b/gn/standalone/libc++/libc++.gni
@@ -0,0 +1,47 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/sanitizers/sanitizers.gni")
+
+declare_args() {
+  # Background:
+  # there are mainly two C++ libraries around in the world: (i) GNU's
+  # libstdc++ and LLVM's libc++ (aka libcxx). By default Linux provides libstdc++
+  # (even building with clang on Linux uses that by default) while Mac and
+  # Android switched to libcxx.
+  # buildtools/libcxx(abi) contains a fixed version of the libcxx, the same one
+  # that Chrome uses on most production configurations (% lagging catching up
+  # with our DEPS).
+  # The variable use_custom_libcxx tells our build system to prefer the
+  # aforementioned copy to the system one.
+  #
+  # Now, there are two reasons for using the checked in copy of libcxx:
+  # 1) LLVM sanitizers require that the c++ library is built from sources,
+  #    because they need to be instrumented with -fsanitize as well (see
+  #    https://github.com/google/sanitizers/wiki/MemorySanitizerLibcxxHowTo).
+  #    On top of this, they also require that the c++ library is dynamically
+  #    linked to prevent duplicate symbol errors when linking (see Chrome's
+  #    build/config/c++/c++.gni)
+  # 2) The libstdc++ situation is too wild on Linux. Modern debian distros are
+  #    fine but Ubuntu Trusty still ships a libstdc++ that doesn't fully
+  #    support C++11. Hence we enable this flag on Linux by default.
+  #    We still retain libstdc++ coverage on the Travis bots by overriding
+  #    use_custom_libcxx=false when we target a modern library (see the
+  #    GCC7 target in .travis.yml).
+  use_custom_libcxx = is_linux && is_clang
+  custom_libcxx_is_static = !using_sanitizer
+}
+
+libcxx_prefix = "//buildtools/libcxx"
+libcxxabi_prefix = "//buildtools/libcxxabi"
diff --git a/gn/standalone/proto_library.gni b/gn/standalone/proto_library.gni
new file mode 100644
index 0000000..90c7819
--- /dev/null
+++ b/gn/standalone/proto_library.gni
@@ -0,0 +1,196 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+template("proto_library") {
+  assert(defined(invoker.sources))
+  proto_sources = invoker.sources
+
+  # All the proto imports should be relative to the project root.
+  proto_in_dir = "//"
+  if (defined(invoker.proto_in_dir)) {
+    proto_in_dir = invoker.proto_in_dir
+  }
+  assert(defined(invoker.proto_out_dir),
+         "proto_out_dir must be explicitly defined")
+  proto_out_dir = invoker.proto_out_dir
+  assert(proto_out_dir == "protos_zero" || proto_out_dir == "protos_lite" ||
+             proto_out_dir == "protos_full",
+         "proto_out must be either 'proto_zero', 'proto_lite' or 'proto_full'")
+
+  # If false will not generate the default .pb.{cc,h} files. Used for custom
+  # codegen plugins.
+  generate_cc = true
+  if (defined(invoker.generate_cc)) {
+    generate_cc = invoker.generate_cc
+  }
+
+  if (defined(invoker.generator_plugin_label)) {
+    plugin_host_label = invoker.generator_plugin_label + "($host_toolchain)"
+    plugin_path = get_label_info(plugin_host_label, "root_out_dir") + "/" +
+                  get_label_info(plugin_host_label, "name")
+    generate_with_plugin = true
+  } else if (defined(invoker.generator_plugin_script)) {
+    plugin_path = invoker.generator_plugin_script
+    generate_with_plugin = true
+  } else {
+    generate_with_plugin = false
+  }
+
+  if (generate_with_plugin) {
+    if (defined(invoker.generator_plugin_suffix)) {
+      generator_plugin_suffixes = [
+        "${invoker.generator_plugin_suffix}.h",
+        "${invoker.generator_plugin_suffix}.cc",
+      ]
+    } else {
+      generator_plugin_suffixes = invoker.generator_plugin_suffixes
+    }
+  }
+
+  cc_out_dir = "$root_gen_dir/" + proto_out_dir
+  rel_cc_out_dir = rebase_path(cc_out_dir, root_build_dir)
+
+  protos = rebase_path(proto_sources, proto_in_dir)
+  protogens = []
+
+  foreach(proto, protos) {
+    proto_dir = get_path_info(proto, "dir")
+    proto_name = get_path_info(proto, "name")
+    proto_path = proto_dir + "/" + proto_name
+
+    if (generate_cc) {
+      protogens += [
+        "$cc_out_dir/$proto_path.pb.h",
+        "$cc_out_dir/$proto_path.pb.cc",
+      ]
+    }
+    if (generate_with_plugin) {
+      foreach(suffix, generator_plugin_suffixes) {
+        protogens += [ "$cc_out_dir/${proto_path}${suffix}" ]
+      }
+    }
+  }
+
+  config_name = "${target_name}_config"
+  action_name = "${target_name}_gen"
+  source_set_name = target_name
+
+  config(config_name) {
+    include_dirs = [ cc_out_dir ]
+  }
+
+  # The XXX_gen action that generates the .pb.{cc,h} files.
+  action(action_name) {
+    visibility = [ ":$source_set_name" ]
+    script = "//gn/standalone/build_tool_wrapper.py"
+    sources = proto_sources
+    outputs = get_path_info(protogens, "abspath")
+
+    protoc_label = "//buildtools:protoc($host_toolchain)"
+    protoc_path = get_label_info(protoc_label, "root_out_dir") + "/protoc"
+    args = [
+      # Path should be rebased because |root_build_dir| for current toolchain
+      # may be different from |root_out_dir| of protoc built on host toolchain.
+      "./" + rebase_path(protoc_path, root_build_dir),
+      "--proto_path",
+      rebase_path(proto_in_dir, root_build_dir),
+    ]
+    if (generate_cc) {
+      args += [
+        "--cpp_out",
+        rel_cc_out_dir,
+      ]
+    }
+
+    if (generate_with_plugin) {
+      plugin_path_rebased = rebase_path(plugin_path, root_build_dir)
+      plugin_out_args = ""
+      if (defined(invoker.generator_plugin_options)) {
+        plugin_out_args += invoker.generator_plugin_options
+      }
+      plugin_out_args += ":$rel_cc_out_dir"
+
+      args += [
+        "--plugin=protoc-gen-plugin=$plugin_path_rebased",
+        "--plugin_out=$plugin_out_args",
+      ]
+    }
+
+    args += rebase_path(proto_sources, root_out_dir)
+
+    inputs = [
+      protoc_path,
+    ]
+
+    deps = [
+      protoc_label,
+    ]
+    if (generate_with_plugin) {
+      inputs += [ plugin_path ]
+      if (defined(plugin_host_label)) {
+        # Action depends on native generator plugin but for host toolchain only.
+        deps += [ plugin_host_label ]
+      }
+    }
+
+    if (defined(invoker.deps)) {
+      deps += invoker.deps
+    }
+  }  # action "${target_name}_gen"
+
+  # The source_set that builds the generated .pb.cc files.
+  source_set(target_name) {
+    forward_variables_from(invoker,
+                           [
+                             "defines",
+                             "include_dirs",
+                             "public_configs",
+                             "testonly",
+                             "visibility",
+                           ])
+
+    sources = get_target_outputs(":$action_name")
+
+    configs -= [ "//gn/standalone:extra_warnings" ]
+    if (defined(invoker.extra_configs)) {
+      configs += invoker.extra_configs
+    }
+
+    if (!defined(invoker.public_configs)) {
+      public_configs = []
+    }
+
+    public_configs += [
+      "//buildtools:protobuf_gen_config",
+      ":$config_name",
+    ]
+
+    # Use protobuf_full only for tests.
+    if (defined(invoker.use_protobuf_full) &&
+        invoker.use_protobuf_full == true) {
+      deps = [
+        "//buildtools:protobuf_full",
+      ]
+    } else {
+      deps = [
+        "//buildtools:protobuf_lite",
+      ]
+    }
+
+    deps += [ ":$action_name" ]
+    if (defined(invoker.deps)) {
+      deps += invoker.deps
+    }
+  }  # source_set(target_name)
+}  # template
diff --git a/gn/standalone/sanitizers/BUILD.gn b/gn/standalone/sanitizers/BUILD.gn
new file mode 100644
index 0000000..0fec24a
--- /dev/null
+++ b/gn/standalone/sanitizers/BUILD.gn
@@ -0,0 +1,119 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/sanitizers/sanitizers.gni")
+
+# Link dependencies for sanitizers for executables.
+group("deps") {
+  visibility = [ "*" ]
+  if (using_sanitizer) {
+    public_configs = [ ":sanitizers_ldflags" ]
+    if (is_android && sanitizer_lib != "" && !sanitizer_lib_dir_is_static) {
+      deps = [
+        ":copy_sanitizer_lib",
+      ]
+    }
+  }
+}
+
+if (is_android && sanitizer_lib != "" && !sanitizer_lib_dir_is_static) {
+  copy("copy_sanitizer_lib") {
+    sources = [
+      "${sanitizer_lib_dir}/lib${sanitizer_lib}.so",
+    ]
+    outputs = [
+      "${root_out_dir}/sanitizer_libs/lib${sanitizer_lib}.so",
+    ]
+  }
+}
+
+config("sanitizers_cflags") {
+  if (using_sanitizer) {
+    blacklist_path_ = rebase_path("blacklist.txt", root_build_dir)
+    cflags = [
+      "-fno-omit-frame-pointer",
+      "-fsanitize-blacklist=$blacklist_path_",
+    ]
+    defines = []
+  }
+
+  if (is_asan) {
+    cflags += [ "-fsanitize=address" ]
+    defines += [ "ADDRESS_SANITIZER" ]
+  }
+  if (is_lsan) {
+    cflags += [ "-fsanitize=leak" ]
+    defines += [ "LEAK_SANITIZER" ]
+  }
+  if (is_tsan) {
+    cflags += [ "-fsanitize=thread" ]
+    defines += [
+      "THREAD_SANITIZER",
+      "DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL=1",
+    ]
+  }
+  if (is_msan) {
+    cflags += [
+      "-fsanitize=memory",
+      "-fsanitize-memory-track-origins=2",
+    ]
+    defines += [ "MEMORY_SANITIZER" ]
+  }
+  if (is_ubsan) {
+    cflags += [
+      "-fsanitize=bounds",
+      "-fsanitize=float-divide-by-zero",
+      "-fsanitize=integer-divide-by-zero",
+      "-fsanitize=null",
+      "-fsanitize=object-size",
+      "-fsanitize=return",
+      "-fsanitize=returns-nonnull-attribute",
+      "-fsanitize=shift-exponent",
+      "-fsanitize=signed-integer-overflow",
+      "-fsanitize=unreachable",
+      "-fsanitize=vla-bound",
+    ]
+    defines += [ "UNDEFINED_SANITIZER" ]
+  }
+}
+
+config("sanitizer_options_link_helper") {
+  if (is_mac) {
+    ldflags = [ "-Wl,-U,_sanitizer_options_link_helper" ]
+  }
+}
+
+config("sanitizers_ldflags") {
+  visibility = [ ":deps" ]
+  ldflags = []
+  if (is_asan) {
+    ldflags += [ "-fsanitize=address" ]
+  }
+  if (is_lsan) {
+    # This is not a copy/paste mistake. The LSan runtime library has
+    # moved into asan. So in order to make LSan work one has to build
+    # .cc files with -fsanitize=leak but link with -fsanitize=address.
+    ldflags += [ "-fsanitize=address" ]
+  }
+  if (is_tsan) {
+    ldflags += [ "-fsanitize=thread" ]
+  }
+  if (is_msan) {
+    ldflags += [ "-fsanitize=memory" ]
+  }
+  if (is_ubsan) {
+    ldflags += [ "-fsanitize=undefined" ]
+  }
+  configs = [ ":sanitizer_options_link_helper" ]
+}
diff --git a/gn/standalone/sanitizers/blacklist.txt b/gn/standalone/sanitizers/blacklist.txt
new file mode 100644
index 0000000..e0e315b
--- /dev/null
+++ b/gn/standalone/sanitizers/blacklist.txt
@@ -0,0 +1 @@
+# The rules in this file are only applied at compile time.
diff --git a/gn/standalone/sanitizers/sanitizers.gni b/gn/standalone/sanitizers/sanitizers.gni
new file mode 100644
index 0000000..95f40d1
--- /dev/null
+++ b/gn/standalone/sanitizers/sanitizers.gni
@@ -0,0 +1,61 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/android.gni")
+import("//gn/standalone/sanitizers/vars.gni")
+import("//gn/standalone/toolchain/llvm.gni")
+
+declare_args() {
+  sanitizer_lib_base_name_ = ""
+  if (is_asan || is_tsan || is_ubsan) {
+    if (is_asan) {
+      sanitizer_lib_base_name_ = "clang_rt.asan"
+    }
+    if (is_tsan) {
+      sanitizer_lib_base_name_ = "clang_rt.tsan"
+    }
+    if (is_ubsan) {
+      sanitizer_lib_base_name_ = "clang_rt.ubsan"
+      if (is_android || is_linux) {
+        sanitizer_lib_base_name_ += "_standalone"
+      }
+    }
+  }
+}
+
+declare_args() {
+  sanitizer_lib_dir = ""
+  sanitizer_lib = ""
+  sanitizer_lib_dir_is_static = false
+  if (sanitizer_lib_base_name_ != "") {
+    if (is_mac) {
+      sanitizer_lib = "${sanitizer_lib_base_name_}_osx_dynamic"
+      sanitizer_lib_dir = mac_clangrt_dir
+    }
+    if (is_linux) {
+      sanitizer_lib = "lib${sanitizer_lib_base_name_}-x86_64.a"
+      sanitizer_lib_dir_is_static = true
+      sanitizer_lib_dir = linux_clangrt_dir
+    }
+    if (is_android) {
+      sanitizer_lib = "${sanitizer_lib_base_name_}-${android_llvm_arch}-android"
+      sanitizer_lib_dir = android_clangrt_dir
+    }
+  }
+}
+
+using_sanitizer = is_asan || is_lsan || is_tsan || is_msan || is_ubsan
+assert(!using_sanitizer || is_clang, "is_*san requires is_clang=true'")
+assert(!is_msan || is_linux, "msan only supported on linux")
+assert(!is_tsan || (is_linux || is_mac), "tsan only supported on linux and mac")
diff --git a/gn/standalone/sanitizers/vars.gni b/gn/standalone/sanitizers/vars.gni
new file mode 100644
index 0000000..7ad54ab
--- /dev/null
+++ b/gn/standalone/sanitizers/vars.gni
@@ -0,0 +1,38 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+declare_args() {
+  # Address Sanitizer: memory bugs (e.g., UAF).
+  is_asan = false
+
+  # Leak Sanitizer: memory leaks.
+  is_lsan = false
+
+  # Memory Sanitizer: uninitialized reads.
+  is_msan = false
+
+  # Thread Sanitizer: threading bugs.
+  is_tsan = false
+
+  # Undefined Behaviour Sanitizer.
+  is_ubsan = false
+}
+
+declare_args() {
+  using_sanitizer = is_asan || is_lsan || is_tsan || is_msan || is_ubsan
+}
+
+assert(!using_sanitizer || is_clang, "is_*san requires is_clang=true'")
+assert(!is_msan || is_linux, "msan only supported on linux")
+assert(!is_tsan || (is_linux || is_mac), "tsan only supported on linux and mac")
diff --git a/gn/standalone/toolchain/BUILD.gn b/gn/standalone/toolchain/BUILD.gn
new file mode 100644
index 0000000..251c7c2
--- /dev/null
+++ b/gn/standalone/toolchain/BUILD.gn
@@ -0,0 +1,164 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/android.gni")
+import("llvm.gni")
+
+declare_args() {
+  if (is_clang) {
+    if (is_linux) {
+      cc = linux_clang_bin
+      cxx = linux_clangxx_bin
+    } else {
+      cc = "clang"
+      cxx = "clang++"
+    }
+  } else {
+    cc = "gcc"
+    cxx = "g++"
+  }
+}
+
+declare_args() {
+  host_ar = ar
+  if (is_linux_host && is_clang) {
+    host_cc = linux_clang_bin
+    host_cxx = linux_clangxx_bin
+  } else {
+    host_cc = cc
+    host_cxx = cxx
+  }
+
+  if (is_android) {
+    target_ar = "$android_toolchain_root/bin/ar"
+    target_cc = "$android_llvm_dir/bin/clang"
+    target_cxx = "$android_llvm_dir/bin/clang++"
+  } else {
+    target_ar = ar
+    target_cc = cc
+    target_cxx = cxx
+  }
+  cc_wrapper = ""
+}
+
+python = "python"
+stamp = "touch"
+
+template("gcc_like_toolchain") {
+  toolchain(target_name) {
+    ar = invoker.ar
+    cc = invoker.cc
+    cxx = invoker.cxx
+    lib_switch = "-l"
+    lib_dir_switch = "-L"
+
+    tool("cc") {
+      depfile = "{{output}}.d"
+      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_c}} -c {{source}} -o {{output}}"
+      depsformat = "gcc"
+      outputs = [
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+      ]
+      description = "compile {{source}}"
+    }
+
+    tool("cxx") {
+      depfile = "{{output}}.d"
+      command = "$cc_wrapper $cxx -MMD -MF $depfile {{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}} -c {{source}} -o {{output}}"
+      depsformat = "gcc"
+      outputs = [
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+      ]
+      description = "compile {{source}}"
+    }
+
+    tool("asm") {
+      depfile = "{{output}}.d"
+      command = "$cc_wrapper $cc -MMD -MF $depfile {{defines}} {{include_dirs}} {{asmflags}} -c {{source}} -o {{output}}"
+      depsformat = "gcc"
+      outputs = [
+        "{{source_out_dir}}/{{target_output_name}}.{{source_name_part}}.o",
+      ]
+      description = "assemble {{source}}"
+    }
+
+    tool("alink") {
+      rspfile = "{{output}}.rsp"
+      rspfile_content = "{{inputs}}"
+      command = "$ar {{output}} $rspfile"
+      outputs = [
+        "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
+      ]
+      default_output_extension = ".a"
+      output_prefix = "lib"
+      description = "link {{output}}"
+    }
+
+    tool("solink") {
+      soname = "{{target_output_name}}{{output_extension}}"
+
+      rpath = "-Wl,-soname,$soname"
+      if (is_mac) {
+        rpath = "-Wl,-install_name,@rpath/$soname"
+      }
+
+      command = "$cc_wrapper $cxx -shared {{ldflags}} {{inputs}} {{solibs}} {{libs}} $rpath -o {{output}}"
+      outputs = [
+        "{{root_out_dir}}/$soname",
+      ]
+      output_prefix = "lib"
+      default_output_extension = ".so"
+      description = "link {{output}}"
+    }
+
+    tool("link") {
+      command = "$cc_wrapper $cxx {{ldflags}} {{inputs}} {{solibs}} {{libs}} -o {{output}}"
+      outputs = [
+        "{{root_out_dir}}/{{target_output_name}}{{output_extension}}",
+      ]
+      description = "link {{output}}"
+    }
+
+    tool("stamp") {
+      command = "touch {{output}}"
+      description = "stamp {{output}}"
+    }
+
+    tool("copy") {
+      command = "cp -af {{source}} {{output}}"
+      description = "COPY {{source}} {{output}}"
+    }
+
+    toolchain_args = {
+      current_cpu = invoker.cpu
+      current_os = invoker.os
+    }
+  }
+}
+
+gcc_like_toolchain("gcc_like") {
+  cpu = current_cpu
+  os = current_os
+  ar = target_ar
+  cc = target_cc
+  cxx = target_cxx
+}
+
+gcc_like_toolchain("gcc_like_host") {
+  cpu = host_cpu
+  os = host_os
+  ar = host_ar
+  cc = host_cc
+  cxx = host_cxx
+}
diff --git a/gn/standalone/toolchain/linux_find_llvm.py b/gn/standalone/toolchain/linux_find_llvm.py
new file mode 100644
index 0000000..bccd17e
--- /dev/null
+++ b/gn/standalone/toolchain/linux_find_llvm.py
@@ -0,0 +1,40 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import subprocess
+import sys
+
+def main():
+  devnull = open(os.devnull, 'w')
+  for clang in ('clang', 'clang-3.8', 'clang-3.5'):
+    if subprocess.call(['which', clang], stdout=devnull, stderr=devnull) != 0:
+      continue
+    res = subprocess.check_output([clang, '-print-search-dirs'])
+    for line in res.splitlines():
+      if not line.startswith('libraries:'):
+        continue
+      libs = line.split('=', 1)[1].split(':')
+      for lib in libs:
+        if '/clang/' not in lib or not os.path.isdir(lib + '/lib'):
+          continue
+        print os.path.abspath(lib)
+        print clang
+        print clang.replace('clang', 'clang++')
+        return 0
+  print 'Could not find the LLVM lib dir'
+  return 1
+
+if __name__ == '__main__':
+  sys.exit(main())
diff --git a/gn/standalone/toolchain/llvm.gni b/gn/standalone/toolchain/llvm.gni
new file mode 100644
index 0000000..ae490ad
--- /dev/null
+++ b/gn/standalone/toolchain/llvm.gni
@@ -0,0 +1,44 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("//gn/standalone/sanitizers/vars.gni")
+
+declare_args() {
+  is_hermetic_clang = is_clang && is_linux_host && using_sanitizer
+}
+
+assert(!is_hermetic_clang || is_clang, "is_hermetic_clang requires is_clang")
+
+declare_args() {
+  if (is_linux_host) {
+    if (is_hermetic_clang) {
+      _hermetic_llvm_dir = rebase_path("//buildtools/clang", root_build_dir)
+      linux_llvm_dir = "$_hermetic_llvm_dir/lib/clang/6.0.0/"
+      linux_clang_bin = "$_hermetic_llvm_dir/bin/clang"
+      linux_clangxx_bin = "$_hermetic_llvm_dir/bin/clang++"
+      linux_clangrt_dir = "$_hermetic_llvm_dir/lib/clang/6.0.0/lib/linux"
+    } else if (is_clang) {
+      # Guess the path for the system clang.
+      find_llvm_out = exec_script("linux_find_llvm.py", [], "list lines")
+      linux_llvm_dir = find_llvm_out[0]
+      linux_clang_bin = find_llvm_out[1]
+      linux_clangxx_bin = find_llvm_out[2]
+      linux_clangrt_dir = "$linux_llvm_dir/lib/linux"
+    }
+  } else if (is_mac) {
+    mac_toolchain_dirs_ = exec_script("mac_find_llvm.py", [], "list lines")
+    mac_toolchain_dir = mac_toolchain_dirs_[0]
+    mac_clangrt_dir = mac_toolchain_dirs_[1]
+  }
+}
diff --git a/gn/standalone/toolchain/mac_find_llvm.py b/gn/standalone/toolchain/mac_find_llvm.py
new file mode 100644
index 0000000..17d1ea1
--- /dev/null
+++ b/gn/standalone/toolchain/mac_find_llvm.py
@@ -0,0 +1,36 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import glob
+import os
+import subprocess
+import sys
+
+def main():
+  job = subprocess.Popen(['xcrun', '-f', 'clang++'],
+                         stdout=subprocess.PIPE,
+                         stderr=subprocess.STDOUT)
+  out, err = job.communicate()
+  if job.returncode != 0:
+    print >> sys.stderr, out
+    print >> sys.stderr, err
+    return job.returncode
+  sdk_dir = os.path.dirname(os.path.dirname(out.rstrip()))
+  print sdk_dir
+  clang_dir = glob.glob(os.path.join(sdk_dir, 'lib', 'clang', '*', 'lib', 'darwin'))
+  print clang_dir[0] if clang_dir else 'CLANG_DIR_NOT_FOUND'
+
+
+if __name__ == '__main__':
+  sys.exit(main())