Check in NDK r17.

Test: None
Bug: None
diff --git a/build/NOTICE b/build/NOTICE
new file mode 100644
index 0000000..d6c0922
--- /dev/null
+++ b/build/NOTICE
@@ -0,0 +1,13 @@
+Copyright (C) 2016 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.
diff --git a/build/__init__.py b/build/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/build/__init__.py
diff --git a/build/cmake/android.toolchain.cmake b/build/cmake/android.toolchain.cmake
new file mode 100644
index 0000000..a759b3a
--- /dev/null
+++ b/build/cmake/android.toolchain.cmake
@@ -0,0 +1,833 @@
+# Copyright (C) 2016 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.
+
+# Configurable variables.
+# Modeled after the ndk-build system.
+# For any variables defined in:
+#         https://developer.android.com/ndk/guides/android_mk.html
+#         https://developer.android.com/ndk/guides/application_mk.html
+# if it makes sense for CMake, then replace LOCAL, APP, or NDK with ANDROID, and
+# we have that variable below.
+# The exception is ANDROID_TOOLCHAIN vs NDK_TOOLCHAIN_VERSION.
+# Since we only have one version of each gcc and clang, specifying a version
+# doesn't make much sense.
+#
+# ANDROID_TOOLCHAIN
+# ANDROID_ABI
+# ANDROID_PLATFORM
+# ANDROID_STL
+# ANDROID_PIE
+# ANDROID_CPP_FEATURES
+# ANDROID_ALLOW_UNDEFINED_SYMBOLS
+# ANDROID_ARM_MODE
+# ANDROID_ARM_NEON
+# ANDROID_DISABLE_NO_EXECUTE
+# ANDROID_DISABLE_RELRO
+# ANDROID_DISABLE_FORMAT_STRING_CHECKS
+# ANDROID_CCACHE
+
+cmake_minimum_required(VERSION 3.6.0)
+
+# Inhibit all of CMake's own NDK handling code.
+set(CMAKE_SYSTEM_VERSION 1)
+
+# CMake invokes the toolchain file twice during the first build, but only once
+# during subsequent rebuilds. This was causing the various flags to be added
+# twice on the first build, and on a rebuild ninja would see only one set of the
+# flags and rebuild the world.
+# https://github.com/android-ndk/ndk/issues/323
+if(ANDROID_NDK_TOOLCHAIN_INCLUDED)
+  return()
+endif(ANDROID_NDK_TOOLCHAIN_INCLUDED)
+set(ANDROID_NDK_TOOLCHAIN_INCLUDED true)
+
+# Android NDK
+get_filename_component(ANDROID_NDK_EXPECTED_PATH
+    "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
+if(NOT ANDROID_NDK)
+  set(ANDROID_NDK "${ANDROID_NDK_EXPECTED_PATH}")
+else()
+  # Allow the user to specify their own NDK path, but emit a warning. This is an
+  # uncommon use case, but helpful if users want to use a bleeding edge
+  # toolchain file with a stable NDK.
+  # https://github.com/android-ndk/ndk/issues/473
+  get_filename_component(ANDROID_NDK "${ANDROID_NDK}" ABSOLUTE)
+  if(NOT "${ANDROID_NDK}" STREQUAL "${ANDROID_NDK_EXPECTED_PATH}")
+    message(WARNING "Using custom NDK path (ANDROID_NDK is set): ${ANDROID_NDK}")
+  endif()
+endif()
+unset(ANDROID_NDK_EXPECTED_PATH)
+file(TO_CMAKE_PATH "${ANDROID_NDK}" ANDROID_NDK)
+
+# Android NDK revision
+# Possible formats:
+# * r16, build 1234: 16.0.1234
+# * r16b, build 1234: 16.1.1234
+# * r16 beta 1, build 1234: 16.0.1234-beta1
+#
+# Canary builds are not specially marked.
+file(READ "${ANDROID_NDK}/source.properties" ANDROID_NDK_SOURCE_PROPERTIES)
+
+set(ANDROID_NDK_REVISION_REGEX
+  "^Pkg\\.Desc = Android NDK\nPkg\\.Revision = ([0-9]+)\\.([0-9]+)\\.([0-9]+)(-beta([0-9]+))?")
+if(NOT ANDROID_NDK_SOURCE_PROPERTIES MATCHES "${ANDROID_NDK_REVISION_REGEX}")
+  message(SEND_ERROR "Failed to parse Android NDK revision: ${ANDROID_NDK}/source.properties.\n${ANDROID_NDK_SOURCE_PROPERTIES}")
+endif()
+
+set(ANDROID_NDK_MAJOR "${CMAKE_MATCH_1}")
+set(ANDROID_NDK_MINOR "${CMAKE_MATCH_2}")
+set(ANDROID_NDK_BUILD "${CMAKE_MATCH_3}")
+set(ANDROID_NDK_BETA "${CMAKE_MATCH_5}")
+if(ANDROID_NDK_BETA STREQUAL "")
+  set(ANDROID_NDK_BETA "0")
+endif()
+set(ANDROID_NDK_REVISION
+  "${ANDROID_NDK_MAJOR}.${ANDROID_NDK_MINOR}.${ANDROID_NDK_BUILD}${CMAKE_MATCH_4}")
+
+# Touch toolchain variable to suppress "unused variable" warning.
+# This happens if CMake is invoked with the same command line the second time.
+if(CMAKE_TOOLCHAIN_FILE)
+endif()
+
+# Compatibility for configurable variables.
+# Compatible with configurable variables from the other toolchain file:
+#         https://github.com/taka-no-me/android-cmake
+# TODO: We should consider dropping compatibility to simplify things once most
+# of our users have migrated to our standard set of configurable variables.
+if(ANDROID_TOOLCHAIN_NAME AND NOT ANDROID_TOOLCHAIN)
+  if(ANDROID_TOOLCHAIN_NAME MATCHES "-clang([0-9].[0-9])?$")
+    set(ANDROID_TOOLCHAIN clang)
+  elseif(ANDROID_TOOLCHAIN_NAME MATCHES "-[0-9].[0-9]$")
+    set(ANDROID_TOOLCHAIN gcc)
+  endif()
+endif()
+if(ANDROID_ABI STREQUAL "armeabi-v7a with NEON")
+  set(ANDROID_ABI armeabi-v7a)
+  set(ANDROID_ARM_NEON TRUE)
+elseif(ANDROID_TOOLCHAIN_NAME AND NOT ANDROID_ABI)
+  if(ANDROID_TOOLCHAIN_NAME MATCHES "^arm-linux-androideabi-")
+    set(ANDROID_ABI armeabi-v7a)
+  elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^aarch64-linux-android-")
+    set(ANDROID_ABI arm64-v8a)
+  elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^x86-")
+    set(ANDROID_ABI x86)
+  elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^x86_64-")
+    set(ANDROID_ABI x86_64)
+  elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^mipsel-linux-android-")
+    set(ANDROID_ABI mips)
+  elseif(ANDROID_TOOLCHAIN_NAME MATCHES "^mips64el-linux-android-")
+    set(ANDROID_ABI mips64)
+  endif()
+endif()
+if(ANDROID_NATIVE_API_LEVEL AND NOT ANDROID_PLATFORM)
+  if(ANDROID_NATIVE_API_LEVEL MATCHES "^android-[0-9]+$")
+    set(ANDROID_PLATFORM ${ANDROID_NATIVE_API_LEVEL})
+  elseif(ANDROID_NATIVE_API_LEVEL MATCHES "^[0-9]+$")
+    set(ANDROID_PLATFORM android-${ANDROID_NATIVE_API_LEVEL})
+  endif()
+endif()
+if(DEFINED ANDROID_APP_PIE AND NOT DEFINED ANDROID_PIE)
+  set(ANDROID_PIE "${ANDROID_APP_PIE}")
+endif()
+if(ANDROID_STL_FORCE_FEATURES AND NOT DEFINED ANDROID_CPP_FEATURES)
+  set(ANDROID_CPP_FEATURES "rtti exceptions")
+endif()
+if(DEFINED ANDROID_NO_UNDEFINED AND NOT DEFINED ANDROID_ALLOW_UNDEFINED_SYMBOLS)
+  if(ANDROID_NO_UNDEFINED)
+    set(ANDROID_ALLOW_UNDEFINED_SYMBOLS FALSE)
+  else()
+    set(ANDROID_ALLOW_UNDEFINED_SYMBOLS TRUE)
+  endif()
+endif()
+if(DEFINED ANDROID_SO_UNDEFINED AND NOT DEFINED ANDROID_ALLOW_UNDEFINED_SYMBOLS)
+  set(ANDROID_ALLOW_UNDEFINED_SYMBOLS "${ANDROID_SO_UNDEFINED}")
+endif()
+if(DEFINED ANDROID_FORCE_ARM_BUILD AND NOT ANDROID_ARM_MODE)
+  if(ANDROID_FORCE_ARM_BUILD)
+    set(ANDROID_ARM_MODE arm)
+  else()
+    set(ANDROID_ARM_MODE thumb)
+  endif()
+endif()
+if(DEFINED ANDROID_NOEXECSTACK AND NOT DEFINED ANDROID_DISABLE_NO_EXECUTE)
+  if(ANDROID_NOEXECSTACK)
+    set(ANDROID_DISABLE_NO_EXECUTE FALSE)
+  else()
+    set(ANDROID_DISABLE_NO_EXECUTE TRUE)
+  endif()
+endif()
+if(DEFINED ANDROID_RELRO AND NOT DEFINED ANDROID_DISABLE_RELRO)
+  if(ANDROID_RELRO)
+    set(ANDROID_DISABLE_RELRO FALSE)
+  else()
+    set(ANDROID_DISABLE_RELRO TRUE)
+  endif()
+endif()
+if(NDK_CCACHE AND NOT ANDROID_CCACHE)
+  set(ANDROID_CCACHE "${NDK_CCACHE}")
+endif()
+
+# Default values for configurable variables.
+if(NOT ANDROID_TOOLCHAIN)
+  set(ANDROID_TOOLCHAIN clang)
+elseif(ANDROID_TOOLCHAIN STREQUAL gcc)
+  message(WARNING
+    "GCC is deprecated and will be removed in the next release. See "
+    "https://android.googlesource.com/platform/ndk/+/master/docs/ClangMigration.md.")
+endif()
+if(NOT ANDROID_ABI)
+  set(ANDROID_ABI armeabi-v7a)
+endif()
+if(ANDROID_PLATFORM MATCHES "^android-([0-9]|1[0-3])$")
+  message(WARNING "${ANDROID_PLATFORM} is unsupported. Using minimum supported "
+                  "version android-14")
+  set(ANDROID_PLATFORM android-14)
+elseif(ANDROID_PLATFORM STREQUAL android-20)
+  set(ANDROID_PLATFORM android-19)
+elseif(ANDROID_PLATFORM STREQUAL android-25)
+  set(ANDROID_PLATFORM android-24)
+elseif(NOT ANDROID_PLATFORM)
+  set(ANDROID_PLATFORM android-14)
+endif()
+string(REPLACE "android-" "" ANDROID_PLATFORM_LEVEL ${ANDROID_PLATFORM})
+if(ANDROID_ABI MATCHES "64(-v8a)?$" AND ANDROID_PLATFORM_LEVEL LESS 21)
+  set(ANDROID_PLATFORM android-21)
+  set(ANDROID_PLATFORM_LEVEL 21)
+endif()
+
+if(NOT ANDROID_STL)
+  set(ANDROID_STL c++_static)
+endif()
+
+if("${ANDROID_STL}" STREQUAL "gnustl_shared" OR
+    "${ANDROID_STL}" STREQUAL "gnustl_static" OR
+    "${ANDROID_STL}" STREQUAL "stlport_shared" OR
+    "${ANDROID_STL}" STREQUAL "stlport_static")
+  message(WARNING
+    "${ANDROID_STL} is deprecated and will be removed in the next release. "
+    "Please switch to either c++_shared or c++_static. See "
+    "https://developer.android.com/ndk/guides/cpp-support.html for more "
+    "information.")
+endif()
+
+if(NOT DEFINED ANDROID_PIE)
+  if(ANDROID_PLATFORM_LEVEL LESS 16)
+    set(ANDROID_PIE FALSE)
+  else()
+    set(ANDROID_PIE TRUE)
+  endif()
+endif()
+if(NOT ANDROID_ARM_MODE)
+  set(ANDROID_ARM_MODE thumb)
+endif()
+
+# Export configurable variables for the try_compile() command.
+set(CMAKE_TRY_COMPILE_PLATFORM_VARIABLES
+  ANDROID_TOOLCHAIN
+  ANDROID_ABI
+  ANDROID_PLATFORM
+  ANDROID_STL
+  ANDROID_PIE
+  ANDROID_CPP_FEATURES
+  ANDROID_ALLOW_UNDEFINED_SYMBOLS
+  ANDROID_ARM_MODE
+  ANDROID_ARM_NEON
+  ANDROID_DISABLE_NO_EXECUTE
+  ANDROID_DISABLE_RELRO
+  ANDROID_DISABLE_FORMAT_STRING_CHECKS
+  ANDROID_CCACHE)
+
+# Standard cross-compiling stuff.
+set(ANDROID TRUE)
+set(CMAKE_SYSTEM_NAME Android)
+
+# Allow users to override these values in case they want more strict behaviors.
+# For example, they may want to prevent the NDK's libz from being picked up so
+# they can use their own.
+# https://github.com/android-ndk/ndk/issues/517
+if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
+  set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+endif()
+
+if(NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY)
+  set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+endif()
+
+if(NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)
+  set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+endif()
+
+if(NOT CMAKE_FIND_ROOT_PATH_MODE_PACKAGE)
+  set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+endif()
+
+# ABI.
+set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI})
+if(ANDROID_ABI STREQUAL armeabi-v7a)
+  set(ANDROID_SYSROOT_ABI arm)
+  set(ANDROID_TOOLCHAIN_NAME arm-linux-androideabi)
+  set(ANDROID_TOOLCHAIN_ROOT ${ANDROID_TOOLCHAIN_NAME})
+  set(ANDROID_HEADER_TRIPLE arm-linux-androideabi)
+  set(CMAKE_SYSTEM_PROCESSOR armv7-a)
+  set(ANDROID_LLVM_TRIPLE armv7-none-linux-androideabi)
+elseif(ANDROID_ABI STREQUAL arm64-v8a)
+  set(ANDROID_SYSROOT_ABI arm64)
+  set(CMAKE_SYSTEM_PROCESSOR aarch64)
+  set(ANDROID_TOOLCHAIN_NAME aarch64-linux-android)
+  set(ANDROID_TOOLCHAIN_ROOT ${ANDROID_TOOLCHAIN_NAME})
+  set(ANDROID_LLVM_TRIPLE aarch64-none-linux-android)
+  set(ANDROID_HEADER_TRIPLE aarch64-linux-android)
+elseif(ANDROID_ABI STREQUAL x86)
+  set(ANDROID_SYSROOT_ABI x86)
+  set(CMAKE_SYSTEM_PROCESSOR i686)
+  set(ANDROID_TOOLCHAIN_NAME i686-linux-android)
+  set(ANDROID_TOOLCHAIN_ROOT ${ANDROID_ABI})
+  set(ANDROID_LLVM_TRIPLE i686-none-linux-android)
+  set(ANDROID_HEADER_TRIPLE i686-linux-android)
+elseif(ANDROID_ABI STREQUAL x86_64)
+  set(ANDROID_SYSROOT_ABI x86_64)
+  set(CMAKE_SYSTEM_PROCESSOR x86_64)
+  set(ANDROID_TOOLCHAIN_NAME x86_64-linux-android)
+  set(ANDROID_TOOLCHAIN_ROOT ${ANDROID_ABI})
+  set(ANDROID_LLVM_TRIPLE x86_64-none-linux-android)
+  set(ANDROID_HEADER_TRIPLE x86_64-linux-android)
+else()
+  set(ANDROID_ABI_ERROR "")
+  if(ANDROID_ABI STREQUAL armeabi)
+    set(ANDROID_ABI_ERROR " (armeabi is no longer supported. Use armeabi-v7a.)")
+  elseif(ANDROID_ABI MATCHES "^(mips|mips64)$")
+    set(ANDROID_ABI_ERROR " (MIPS and MIPS64 are no longer supported.)")
+  endif()
+  message(FATAL_ERROR "Invalid Android ABI: ${ANDROID_ABI}.${ANDROID_ABI_ERROR}")
+endif()
+
+set(ANDROID_COMPILER_FLAGS)
+set(ANDROID_COMPILER_FLAGS_CXX)
+set(ANDROID_COMPILER_FLAGS_DEBUG)
+set(ANDROID_COMPILER_FLAGS_RELEASE)
+set(ANDROID_LINKER_FLAGS)
+set(ANDROID_LINKER_FLAGS_EXE)
+
+# Don't re-export libgcc symbols in every binary.
+list(APPEND ANDROID_LINKER_FLAGS -Wl,--exclude-libs,libgcc.a)
+list(APPEND ANDROID_LINKER_FLAGS -Wl,--exclude-libs,libatomic.a)
+
+# STL.
+set(USE_NOSTDLIBXX TRUE)
+set(ANDROID_STL_STATIC_LIBRARIES)
+set(ANDROID_STL_SHARED_LIBRARIES)
+set(ANDROID_STL_LDLIBS)
+if(ANDROID_STL STREQUAL system)
+  set(USE_NOSTDLIBXX FALSE)
+  if(NOT "x${ANDROID_CPP_FEATURES}" STREQUAL "x")
+    set(ANDROID_STL_STATIC_LIBRARIES supc++)
+  endif()
+elseif(ANDROID_STL STREQUAL stlport_static)
+  set(USE_NOSTDLIBXX FALSE)
+  set(ANDROID_STL_STATIC_LIBRARIES stlport_static)
+elseif(ANDROID_STL STREQUAL stlport_shared)
+  set(USE_NOSTDLIBXX FALSE)
+  set(ANDROID_STL_SHARED_LIBRARIES stlport_shared)
+elseif(ANDROID_STL STREQUAL gnustl_static)
+  set(ANDROID_STL_STATIC_LIBRARIES gnustl_static)
+elseif(ANDROID_STL STREQUAL gnustl_shared)
+  set(ANDROID_STL_STATIC_LIBRARIES supc++)
+  set(ANDROID_STL_SHARED_LIBRARIES gnustl_shared)
+elseif(ANDROID_STL STREQUAL c++_static)
+  list(APPEND ANDROID_STL_STATIC_LIBRARIES c++_static c++abi)
+  if(ANDROID_PLATFORM_LEVEL LESS 21)
+    list(APPEND ANDROID_STL_STATIC_LIBRARIES android_support)
+  endif()
+  if(ANDROID_ABI STREQUAL armeabi-v7a)
+    list(APPEND ANDROID_STL_STATIC_LIBRARIES unwind)
+    list(APPEND ANDROID_STL_LDLIBS dl)
+  endif()
+elseif(ANDROID_STL STREQUAL c++_shared)
+  if(ANDROID_PLATFORM_LEVEL LESS 21)
+    list(APPEND ANDROID_STL_STATIC_LIBRARIES android_support)
+  endif()
+  if(ANDROID_ABI STREQUAL armeabi-v7a)
+    list(APPEND ANDROID_STL_STATIC_LIBRARIES unwind)
+  endif()
+  list(APPEND ANDROID_STL_SHARED_LIBRARIES c++_shared)
+elseif(ANDROID_STL STREQUAL none)
+else()
+  message(FATAL_ERROR "Invalid Android STL: ${ANDROID_STL}.")
+endif()
+
+if(USE_NOSTDLIBXX AND ANDROID_TOOLCHAIN STREQUAL clang)
+  list(APPEND ANDROID_LINKER_FLAGS "-nostdlib++")
+endif()
+
+# Behavior of CMAKE_SYSTEM_LIBRARY_PATH and CMAKE_LIBRARY_PATH are really weird
+# when CMAKE_SYSROOT is set. The library path is appended to the sysroot even if
+# the library path is an abspath. Using a relative path from the sysroot doesn't
+# work either, because the relative path is abspath'd relative to the current
+# CMakeLists.txt file before being appended :(
+#
+# We can try to get out of this problem by providing another root path for cmake
+# to check. CMAKE_FIND_ROOT_PATH is intended for this purpose:
+# https://cmake.org/cmake/help/v3.8/variable/CMAKE_FIND_ROOT_PATH.html
+#
+# In theory this should just be our sysroot, but since we don't have a single
+# sysroot that is correct (there's only one set of headers, but multiple
+# locations for libraries that need to be handled differently).  Some day we'll
+# want to move all the libraries into ${ANDROID_NDK}/sysroot, but we'll need to
+# make some fixes to Clang, various build systems, and possibly CMake itself to
+# get that working.
+list(APPEND CMAKE_FIND_ROOT_PATH "${ANDROID_NDK}")
+
+# Sysroot.
+set(CMAKE_SYSROOT "${ANDROID_NDK}/sysroot")
+
+# CMake 3.9 tries to use CMAKE_SYSROOT_COMPILE before it gets set from
+# CMAKE_SYSROOT, which leads to using the system's /usr/include. Set this
+# manually.
+# https://github.com/android-ndk/ndk/issues/467
+set(CMAKE_SYSROOT_COMPILE "${CMAKE_SYSROOT}")
+
+# The compiler driver doesn't check any arch specific include locations (though
+# maybe we should add that). Architecture specific headers like asm/ and
+# machine/ are installed to an arch-$ARCH subdirectory of the sysroot.
+list(APPEND ANDROID_COMPILER_FLAGS
+  "-isystem ${CMAKE_SYSROOT}/usr/include/${ANDROID_HEADER_TRIPLE}")
+list(APPEND ANDROID_COMPILER_FLAGS
+  "-D__ANDROID_API__=${ANDROID_PLATFORM_LEVEL}")
+
+# We need different sysroots for linking and compiling, but cmake doesn't
+# support that. Pass the sysroot flag manually when linking.
+set(ANDROID_SYSTEM_LIBRARY_PATH
+  "${ANDROID_NDK}/platforms/${ANDROID_PLATFORM}/arch-${ANDROID_SYSROOT_ABI}")
+list(APPEND ANDROID_LINKER_FLAGS "--sysroot ${ANDROID_SYSTEM_LIBRARY_PATH}")
+
+# find_library searches a handful of paths as described by
+# https://cmake.org/cmake/help/v3.6/command/find_library.html.  Since libraries
+# are per-API level and headers aren't, We don't have libraries in the
+# CMAKE_SYSROOT. Set up CMAKE_SYSTEM_LIBRARY_PATH
+# (https://cmake.org/cmake/help/v3.6/variable/CMAKE_SYSTEM_LIBRARY_PATH.html)
+# instead.
+#
+# NB: The suffix is just lib here instead of dealing with lib64 because
+# apparently CMake does some automatic rewriting of that? I've been testing by
+# building my own CMake with a bunch of logging added, and that seems to be the
+# case.
+list(APPEND CMAKE_SYSTEM_LIBRARY_PATH
+  "${ANDROID_SYSTEM_LIBRARY_PATH}/usr/lib")
+
+# Toolchain.
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL Linux)
+  set(ANDROID_HOST_TAG linux-x86_64)
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Darwin)
+  set(ANDROID_HOST_TAG darwin-x86_64)
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
+  set(ANDROID_HOST_TAG windows-x86_64)
+endif()
+set(ANDROID_TOOLCHAIN_ROOT "${ANDROID_NDK}/toolchains/${ANDROID_TOOLCHAIN_ROOT}-4.9/prebuilt/${ANDROID_HOST_TAG}")
+set(ANDROID_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_ROOT}/bin/${ANDROID_TOOLCHAIN_NAME}-")
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL Windows)
+  set(ANDROID_TOOLCHAIN_SUFFIX .exe)
+endif()
+
+set(ANDROID_HOST_PREBUILTS "${ANDROID_NDK}/prebuilt/${ANDROID_HOST_TAG}")
+
+if(ANDROID_TOOLCHAIN STREQUAL clang)
+  set(ANDROID_LLVM_TOOLCHAIN_PREFIX "${ANDROID_NDK}/toolchains/llvm/prebuilt/${ANDROID_HOST_TAG}/bin/")
+  set(ANDROID_C_COMPILER   "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang${ANDROID_TOOLCHAIN_SUFFIX}")
+  set(ANDROID_CXX_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang++${ANDROID_TOOLCHAIN_SUFFIX}")
+  set(ANDROID_ASM_COMPILER "${ANDROID_LLVM_TOOLCHAIN_PREFIX}clang${ANDROID_TOOLCHAIN_SUFFIX}")
+  # Clang can fail to compile if CMake doesn't correctly supply the target and
+  # external toolchain, but to do so, CMake needs to already know that the
+  # compiler is clang. Tell CMake that the compiler is really clang, but don't
+  # use CMakeForceCompiler, since we still want compile checks. We only want
+  # to skip the compiler ID detection step.
+  set(CMAKE_C_COMPILER_ID_RUN TRUE)
+  set(CMAKE_CXX_COMPILER_ID_RUN TRUE)
+  set(CMAKE_C_COMPILER_ID Clang)
+  set(CMAKE_CXX_COMPILER_ID Clang)
+  set(CMAKE_C_COMPILER_VERSION 3.8)
+  set(CMAKE_CXX_COMPILER_VERSION 3.8)
+  set(CMAKE_C_STANDARD_COMPUTED_DEFAULT 11)
+  set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT 98)
+  set(CMAKE_C_COMPILER_TARGET   ${ANDROID_LLVM_TRIPLE})
+  set(CMAKE_CXX_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
+  set(CMAKE_ASM_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
+  set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN   "${ANDROID_TOOLCHAIN_ROOT}")
+  set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${ANDROID_TOOLCHAIN_ROOT}")
+  set(CMAKE_ASM_COMPILER_EXTERNAL_TOOLCHAIN "${ANDROID_TOOLCHAIN_ROOT}")
+  set(ANDROID_AR "${ANDROID_TOOLCHAIN_PREFIX}ar${ANDROID_TOOLCHAIN_SUFFIX}")
+  set(ANDROID_RANLIB "${ANDROID_TOOLCHAIN_PREFIX}ranlib${ANDROID_TOOLCHAIN_SUFFIX}")
+elseif(ANDROID_TOOLCHAIN STREQUAL gcc)
+  set(ANDROID_C_COMPILER   "${ANDROID_TOOLCHAIN_PREFIX}gcc${ANDROID_TOOLCHAIN_SUFFIX}")
+  set(ANDROID_CXX_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}g++${ANDROID_TOOLCHAIN_SUFFIX}")
+  set(ANDROID_ASM_COMPILER "${ANDROID_TOOLCHAIN_PREFIX}gcc${ANDROID_TOOLCHAIN_SUFFIX}")
+  set(ANDROID_AR "${ANDROID_TOOLCHAIN_PREFIX}gcc-ar${ANDROID_TOOLCHAIN_SUFFIX}")
+  set(ANDROID_RANLIB "${ANDROID_TOOLCHAIN_PREFIX}gcc-ranlib${ANDROID_TOOLCHAIN_SUFFIX}")
+else()
+  message(FATAL_ERROR "Invalid Android toolchain: ${ANDROID_TOOLCHAIN}.")
+endif()
+
+if(NOT IS_DIRECTORY "${ANDROID_NDK}/platforms/${ANDROID_PLATFORM}")
+  message(FATAL_ERROR "Invalid Android platform: ${ANDROID_PLATFORM}.")
+elseif(NOT IS_DIRECTORY "${CMAKE_SYSROOT}")
+  message(FATAL_ERROR "Invalid Android sysroot: ${CMAKE_SYSROOT}.")
+endif()
+
+# Generic flags.
+list(APPEND ANDROID_COMPILER_FLAGS
+  -g
+  -DANDROID
+  -ffunction-sections
+  -funwind-tables
+  -fstack-protector-strong
+  -no-canonical-prefixes)
+list(APPEND ANDROID_LINKER_FLAGS
+  -Wl,--build-id
+  -Wl,--warn-shared-textrel
+  -Wl,--fatal-warnings)
+list(APPEND ANDROID_LINKER_FLAGS_EXE
+  -Wl,--gc-sections
+  -Wl,-z,nocopyreloc)
+
+# Debug and release flags.
+list(APPEND ANDROID_COMPILER_FLAGS_DEBUG -O0)
+if(ANDROID_ABI MATCHES "^armeabi")
+  list(APPEND ANDROID_COMPILER_FLAGS_RELEASE -Os)
+else()
+  list(APPEND ANDROID_COMPILER_FLAGS_RELEASE -O2)
+endif()
+list(APPEND ANDROID_COMPILER_FLAGS_RELEASE -DNDEBUG)
+if(ANDROID_TOOLCHAIN STREQUAL clang)
+  list(APPEND ANDROID_COMPILER_FLAGS_DEBUG -fno-limit-debug-info)
+endif()
+
+# Toolchain and ABI specific flags.
+if(ANDROID_ABI STREQUAL armeabi)
+  list(APPEND ANDROID_COMPILER_FLAGS
+    -march=armv5te
+    -mtune=xscale
+    -msoft-float)
+endif()
+if(ANDROID_ABI STREQUAL armeabi-v7a)
+  list(APPEND ANDROID_COMPILER_FLAGS
+    -march=armv7-a
+    -mfloat-abi=softfp
+    -mfpu=vfpv3-d16)
+  list(APPEND ANDROID_LINKER_FLAGS
+    -Wl,--fix-cortex-a8)
+endif()
+if(ANDROID_ABI STREQUAL mips)
+  list(APPEND ANDROID_COMPILER_FLAGS
+    -mips32)
+endif()
+if(ANDROID_ABI STREQUAL mips AND ANDROID_TOOLCHAIN STREQUAL clang)
+  # Help clang use mips64el multilib GCC
+  list(APPEND ANDROID_LINKER_FLAGS
+    "\"-L${ANDROID_TOOLCHAIN_ROOT}/lib/gcc/${ANDROID_TOOLCHAIN_NAME}/4.9.x/32/mips-r1\"")
+endif()
+if(ANDROID_ABI STREQUAL x86)
+  # http://b.android.com/222239
+  # http://b.android.com/220159 (internal http://b/31809417)
+  # x86 devices have stack alignment issues.
+  list(APPEND ANDROID_COMPILER_FLAGS -mstackrealign)
+endif()
+
+# STL specific flags.
+if(ANDROID_STL STREQUAL system)
+  set(ANDROID_STL_PREFIX gnu-libstdc++/4.9)
+  set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
+    "${ANDROID_NDK}/sources/cxx-stl/system/include")
+elseif(ANDROID_STL MATCHES "^stlport_")
+  set(ANDROID_STL_PREFIX stlport)
+  set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
+    "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/stlport"
+    "${ANDROID_NDK}/sources/cxx-stl/gabi++/include")
+elseif(ANDROID_STL MATCHES "^gnustl_")
+  set(ANDROID_STL_PREFIX gnu-libstdc++/4.9)
+  set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
+    "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/include"
+    "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}/include"
+    "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/include/backward")
+elseif(ANDROID_STL MATCHES "^c\\+\\+_")
+  set(ANDROID_STL_PREFIX llvm-libc++)
+  if(ANDROID_ABI MATCHES "^armeabi")
+    list(APPEND ANDROID_LINKER_FLAGS -Wl,--exclude-libs,libunwind.a)
+  endif()
+  list(APPEND ANDROID_COMPILER_FLAGS_CXX
+    -std=c++11)
+  if(ANDROID_TOOLCHAIN STREQUAL gcc)
+    list(APPEND ANDROID_COMPILER_FLAGS_CXX
+      -fno-strict-aliasing)
+  endif()
+
+  # Add the libc++ lib directory to the path so the linker scripts can pick up
+  # the extra libraries.
+  list(APPEND ANDROID_LINKER_FLAGS
+    "-L${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}")
+
+  set(CMAKE_CXX_STANDARD_INCLUDE_DIRECTORIES
+    "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/include"
+    "${ANDROID_NDK}/sources/android/support/include"
+    "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}abi/include")
+endif()
+set(ANDROID_CXX_STANDARD_LIBRARIES)
+foreach(library ${ANDROID_STL_STATIC_LIBRARIES})
+  list(APPEND ANDROID_CXX_STANDARD_LIBRARIES
+    "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}/lib${library}.a")
+endforeach()
+foreach(library ${ANDROID_STL_SHARED_LIBRARIES})
+  list(APPEND ANDROID_CXX_STANDARD_LIBRARIES
+    "${ANDROID_NDK}/sources/cxx-stl/${ANDROID_STL_PREFIX}/libs/${ANDROID_ABI}/lib${library}.so")
+endforeach()
+foreach(library ${ANDROID_STL_LDLIBS})
+  list(APPEND ANDROID_CXX_STANDARD_LIBRARIES "-l${library}")
+endforeach()
+set(CMAKE_C_STANDARD_LIBRARIES_INIT "-latomic -lm")
+set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_C_STANDARD_LIBRARIES_INIT}")
+if(ANDROID_CXX_STANDARD_LIBRARIES)
+  string(REPLACE ";" "\" \"" ANDROID_CXX_STANDARD_LIBRARIES "\"${ANDROID_CXX_STANDARD_LIBRARIES}\"")
+  set(CMAKE_CXX_STANDARD_LIBRARIES_INIT "${CMAKE_CXX_STANDARD_LIBRARIES_INIT} ${ANDROID_CXX_STANDARD_LIBRARIES}")
+endif()
+
+# Configuration specific flags.
+
+# x86 and x86_64 use large model pic, whereas everything else uses small model.
+# In the past we've always used -fPIE, but the LLVMgold plugin (for LTO)
+# complains if the models are mismatched.
+list(APPEND ANDROID_PIE_FLAGS -pie)
+if(ANDROID_ABI MATCHES "x86")
+  list(APPEND ANDROID_PIE_FLAGS -fPIE)
+else()
+  list(APPEND ANDROID_PIE_FLAGS -fpie)
+endif()
+
+# PIE is supported on all currently supported Android releases, but it is not
+# supported with static executables, so we still provide ANDROID_PIE as an
+# escape hatch for those.
+if(ANDROID_PIE)
+  set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
+  list(APPEND ANDROID_LINKER_FLAGS_EXE ${ANDROID_PIE_FLAGS})
+endif()
+
+if(ANDROID_CPP_FEATURES)
+  separate_arguments(ANDROID_CPP_FEATURES)
+  foreach(feature ${ANDROID_CPP_FEATURES})
+    if(NOT ${feature} MATCHES "^(rtti|exceptions)$")
+      message(FATAL_ERROR "Invalid Android C++ feature: ${feature}.")
+    endif()
+    list(APPEND ANDROID_COMPILER_FLAGS_CXX
+      -f${feature})
+  endforeach()
+  string(REPLACE ";" " " ANDROID_CPP_FEATURES "${ANDROID_CPP_FEATURES}")
+endif()
+if(NOT ANDROID_ALLOW_UNDEFINED_SYMBOLS)
+  list(APPEND ANDROID_LINKER_FLAGS
+    -Wl,--no-undefined)
+endif()
+if(ANDROID_ABI MATCHES "armeabi")
+  if(ANDROID_ARM_MODE STREQUAL thumb)
+    list(APPEND ANDROID_COMPILER_FLAGS
+      -mthumb)
+  elseif(ANDROID_ARM_MODE STREQUAL arm)
+    list(APPEND ANDROID_COMPILER_FLAGS
+      -marm)
+  else()
+    message(FATAL_ERROR "Invalid Android ARM mode: ${ANDROID_ARM_MODE}.")
+  endif()
+  if(ANDROID_ABI STREQUAL armeabi-v7a AND ANDROID_ARM_NEON)
+    list(APPEND ANDROID_COMPILER_FLAGS
+      -mfpu=neon)
+  endif()
+endif()
+if(ANDROID_DISABLE_NO_EXECUTE)
+  list(APPEND ANDROID_COMPILER_FLAGS
+    -Wa,--execstack)
+  list(APPEND ANDROID_LINKER_FLAGS
+    -Wl,-z,execstack)
+else()
+  list(APPEND ANDROID_COMPILER_FLAGS
+    -Wa,--noexecstack)
+  list(APPEND ANDROID_LINKER_FLAGS
+    -Wl,-z,noexecstack)
+endif()
+if(ANDROID_TOOLCHAIN STREQUAL clang)
+  # CMake automatically forwards all compiler flags to the linker,
+  # and clang doesn't like having -Wa flags being used for linking.
+  # To prevent CMake from doing this would require meddling with
+  # the CMAKE_<LANG>_COMPILE_OBJECT rules, which would get quite messy.
+  list(APPEND ANDROID_LINKER_FLAGS
+    -Qunused-arguments)
+endif()
+if(ANDROID_DISABLE_RELRO)
+  list(APPEND ANDROID_LINKER_FLAGS
+    -Wl,-z,norelro -Wl,-z,lazy)
+else()
+  list(APPEND ANDROID_LINKER_FLAGS
+    -Wl,-z,relro -Wl,-z,now)
+endif()
+if(ANDROID_DISABLE_FORMAT_STRING_CHECKS)
+  list(APPEND ANDROID_COMPILER_FLAGS
+    -Wno-error=format-security)
+else()
+  list(APPEND ANDROID_COMPILER_FLAGS
+    -Wformat -Werror=format-security)
+endif()
+
+# Convert these lists into strings.
+string(REPLACE ";" " " ANDROID_COMPILER_FLAGS         "${ANDROID_COMPILER_FLAGS}")
+string(REPLACE ";" " " ANDROID_COMPILER_FLAGS_CXX     "${ANDROID_COMPILER_FLAGS_CXX}")
+string(REPLACE ";" " " ANDROID_COMPILER_FLAGS_DEBUG   "${ANDROID_COMPILER_FLAGS_DEBUG}")
+string(REPLACE ";" " " ANDROID_COMPILER_FLAGS_RELEASE "${ANDROID_COMPILER_FLAGS_RELEASE}")
+string(REPLACE ";" " " ANDROID_LINKER_FLAGS           "${ANDROID_LINKER_FLAGS}")
+string(REPLACE ";" " " ANDROID_LINKER_FLAGS_EXE       "${ANDROID_LINKER_FLAGS_EXE}")
+
+if(ANDROID_CCACHE)
+  set(CMAKE_C_COMPILER_LAUNCHER   "${ANDROID_CCACHE}")
+  set(CMAKE_CXX_COMPILER_LAUNCHER "${ANDROID_CCACHE}")
+endif()
+set(CMAKE_C_COMPILER        "${ANDROID_C_COMPILER}")
+set(CMAKE_CXX_COMPILER      "${ANDROID_CXX_COMPILER}")
+set(CMAKE_AR                "${ANDROID_AR}" CACHE FILEPATH "Archiver")
+set(CMAKE_RANLIB            "${ANDROID_RANLIB}" CACHE FILEPATH "Ranlib")
+set(_CMAKE_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_PREFIX}")
+
+if(ANDROID_ABI STREQUAL "x86" OR ANDROID_ABI STREQUAL "x86_64")
+  set(CMAKE_ASM_NASM_COMPILER
+    "${ANDROID_HOST_PREBUILTS}/bin/yasm${ANDROID_TOOLCHAIN_SUFFIX}")
+  set(CMAKE_ASM_NASM_COMPILER_ARG1 "-DELF")
+endif()
+
+# Set or retrieve the cached flags.
+# This is necessary in case the user sets/changes flags in subsequent
+# configures. If we included the Android flags in here, they would get
+# overwritten.
+set(CMAKE_C_FLAGS ""
+  CACHE STRING "Flags used by the compiler during all build types.")
+set(CMAKE_CXX_FLAGS ""
+  CACHE STRING "Flags used by the compiler during all build types.")
+set(CMAKE_ASM_FLAGS ""
+  CACHE STRING "Flags used by the compiler during all build types.")
+set(CMAKE_C_FLAGS_DEBUG ""
+  CACHE STRING "Flags used by the compiler during debug builds.")
+set(CMAKE_CXX_FLAGS_DEBUG ""
+  CACHE STRING "Flags used by the compiler during debug builds.")
+set(CMAKE_ASM_FLAGS_DEBUG ""
+  CACHE STRING "Flags used by the compiler during debug builds.")
+set(CMAKE_C_FLAGS_RELEASE ""
+  CACHE STRING "Flags used by the compiler during release builds.")
+set(CMAKE_CXX_FLAGS_RELEASE ""
+  CACHE STRING "Flags used by the compiler during release builds.")
+set(CMAKE_ASM_FLAGS_RELEASE ""
+  CACHE STRING "Flags used by the compiler during release builds.")
+set(CMAKE_MODULE_LINKER_FLAGS ""
+  CACHE STRING "Flags used by the linker during the creation of modules.")
+set(CMAKE_SHARED_LINKER_FLAGS ""
+  CACHE STRING "Flags used by the linker during the creation of dll's.")
+set(CMAKE_EXE_LINKER_FLAGS ""
+  CACHE STRING "Flags used by the linker.")
+
+set(CMAKE_C_FLAGS             "${ANDROID_COMPILER_FLAGS} ${CMAKE_C_FLAGS}")
+set(CMAKE_CXX_FLAGS           "${ANDROID_COMPILER_FLAGS} ${ANDROID_COMPILER_FLAGS_CXX} ${CMAKE_CXX_FLAGS}")
+set(CMAKE_ASM_FLAGS           "${ANDROID_COMPILER_FLAGS} ${CMAKE_ASM_FLAGS}")
+set(CMAKE_C_FLAGS_DEBUG       "${ANDROID_COMPILER_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}")
+set(CMAKE_CXX_FLAGS_DEBUG     "${ANDROID_COMPILER_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS_DEBUG}")
+set(CMAKE_ASM_FLAGS_DEBUG     "${ANDROID_COMPILER_FLAGS_DEBUG} ${CMAKE_ASM_FLAGS_DEBUG}")
+set(CMAKE_C_FLAGS_RELEASE     "${ANDROID_COMPILER_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}")
+set(CMAKE_CXX_FLAGS_RELEASE   "${ANDROID_COMPILER_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS_RELEASE}")
+set(CMAKE_ASM_FLAGS_RELEASE   "${ANDROID_COMPILER_FLAGS_RELEASE} ${CMAKE_ASM_FLAGS_RELEASE}")
+set(CMAKE_SHARED_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_SHARED_LINKER_FLAGS}")
+set(CMAKE_MODULE_LINKER_FLAGS "${ANDROID_LINKER_FLAGS} ${CMAKE_MODULE_LINKER_FLAGS}")
+set(CMAKE_EXE_LINKER_FLAGS    "${ANDROID_LINKER_FLAGS} ${ANDROID_LINKER_FLAGS_EXE} ${CMAKE_EXE_LINKER_FLAGS}")
+
+# Compatibility for read-only variables.
+# Read-only variables for compatibility with the other toolchain file.
+# We'll keep these around for the existing projects that still use them.
+# TODO: All of the variables here have equivalents in our standard set of
+# configurable variables, so we can remove these once most of our users migrate
+# to those variables.
+set(ANDROID_NATIVE_API_LEVEL ${ANDROID_PLATFORM_LEVEL})
+if(ANDROID_ALLOW_UNDEFINED_SYMBOLS)
+  set(ANDROID_SO_UNDEFINED TRUE)
+else()
+  set(ANDROID_NO_UNDEFINED TRUE)
+endif()
+set(ANDROID_FUNCTION_LEVEL_LINKING TRUE)
+set(ANDROID_GOLD_LINKER TRUE)
+if(NOT ANDROID_DISABLE_NO_EXECUTE)
+  set(ANDROID_NOEXECSTACK TRUE)
+endif()
+if(NOT ANDROID_DISABLE_RELRO)
+  set(ANDROID_RELRO TRUE)
+endif()
+if(ANDROID_ARM_MODE STREQUAL arm)
+  set(ANDROID_FORCE_ARM_BUILD TRUE)
+endif()
+if(ANDROID_CPP_FEATURES MATCHES "rtti"
+    AND ANDROID_CPP_FEATURES MATCHES "exceptions")
+  set(ANDROID_STL_FORCE_FEATURES TRUE)
+endif()
+if(ANDROID_CCACHE)
+  set(NDK_CCACHE "${ANDROID_CCACHE}")
+endif()
+if(ANDROID_TOOLCHAIN STREQUAL clang)
+  set(ANDROID_TOOLCHAIN_NAME ${ANDROID_TOOLCHAIN_NAME}-clang)
+else()
+  set(ANDROID_TOOLCHAIN_NAME ${ANDROID_TOOLCHAIN_NAME}-4.9)
+endif()
+set(ANDROID_NDK_HOST_X64 TRUE)
+set(ANDROID_NDK_LAYOUT RELEASE)
+if(ANDROID_ABI STREQUAL armeabi)
+  set(ARMEABI TRUE)
+elseif(ANDROID_ABI STREQUAL armeabi-v7a)
+  set(ARMEABI_V7A TRUE)
+  if(ANDROID_ARM_NEON)
+    set(NEON TRUE)
+  endif()
+elseif(ANDROID_ABI STREQUAL arm64-v8a)
+  set(ARM64_V8A TRUE)
+elseif(ANDROID_ABI STREQUAL x86)
+  set(X86 TRUE)
+elseif(ANDROID_ABI STREQUAL x86_64)
+  set(X86_64 TRUE)
+elseif(ANDROID_ABI STREQUAL mips)
+  set(MIPS TRUE)
+elseif(ANDROID_ABI STREQUAL mips64)
+  set(MIPS64 TRUE)
+endif()
+set(ANDROID_NDK_HOST_SYSTEM_NAME ${ANDROID_HOST_TAG})
+set(ANDROID_NDK_ABI_NAME ${ANDROID_ABI})
+set(ANDROID_NDK_RELEASE r${ANDROID_NDK_REVISION})
+set(ANDROID_ARCH_NAME ${ANDROID_SYSROOT_ABI})
+set(ANDROID_SYSROOT "${CMAKE_SYSROOT}")
+set(TOOL_OS_SUFFIX ${ANDROID_TOOLCHAIN_SUFFIX})
+if(ANDROID_TOOLCHAIN STREQUAL clang)
+  set(ANDROID_COMPILER_IS_CLANG TRUE)
+endif()
+
+# CMake 3.7+ compatibility.
+if (CMAKE_VERSION VERSION_GREATER 3.7.0)
+  set(CMAKE_ANDROID_NDK ${ANDROID_NDK})
+
+  if(ANDROID_TOOLCHAIN STREQUAL gcc)
+    set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION 4.9)
+  else()
+    set(CMAKE_ANDROID_NDK_TOOLCHAIN_VERSION clang)
+  endif()
+
+  set(CMAKE_ANDROID_STL_TYPE ${ANDROID_STL})
+
+  if(ANDROID_ABI MATCHES "^armeabi(-v7a)?$")
+    set(CMAKE_ANDROID_ARM_NEON ${ANDROID_ARM_NEON})
+    set(CMAKE_ANDROID_ARM_MODE ${ANDROID_ARM_MODE})
+  endif()
+endif()
diff --git a/build/core/add-application.mk b/build/core/add-application.mk
new file mode 100644
index 0000000..5341e5a
--- /dev/null
+++ b/build/core/add-application.mk
@@ -0,0 +1,249 @@
+# Copyright (C) 2009 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.
+#
+
+# this script is used to record an application definition in the
+# NDK build system, before performing any build whatsoever.
+#
+# It is included repeatedly from build/core/main.mk and expects a
+# variable named '_application_mk' which points to a given Application.mk
+# file that will be included here. The latter must define a few variables
+# to describe the application to the build system, and the rest of the
+# code here will perform book-keeping and basic checks
+#
+
+$(call assert-defined, _application_mk _app)
+$(call ndk_log,Parsing $(_application_mk))
+
+$(call clear-vars, $(NDK_APP_VARS))
+
+# Check that NDK_DEBUG is properly defined. If it is
+# the only valid states are: undefined, 0, 1, false and true
+#
+# We set APP_DEBUG to <undefined>, 'true' or 'false'.
+#
+APP_DEBUG := $(strip $(NDK_DEBUG))
+ifeq ($(APP_DEBUG),0)
+  APP_DEBUG:= false
+endif
+ifeq ($(APP_DEBUG),1)
+  APP_DEBUG := true
+endif
+ifdef APP_DEBUG
+  ifneq (,$(filter-out true false,$(APP_DEBUG)))
+    $(call __ndk_warning,NDK_DEBUG is defined to the unsupported value '$(NDK_DEBUG)', will be ignored!)
+  endif
+endif
+
+include $(_application_mk)
+
+$(call check-required-vars,$(NDK_APP_VARS_REQUIRED),$(_application_mk))
+
+_map := NDK_APP.$(_app)
+
+# strip the 'lib' prefix in front of APP_MODULES modules
+APP_MODULES := $(call strip-lib-prefix,$(APP_MODULES))
+
+APP_PROJECT_PATH := $(strip $(APP_PROJECT_PATH))
+ifndef APP_PROJECT_PATH
+    APP_PROJECT_PATH := $(NDK_PROJECT_PATH)
+endif
+
+include $(BUILD_SYSTEM)/setup-app-platform.mk
+
+# If APP_PIE isn't defined, set it to true for android-$(NDK_FIRST_PIE_PLATFORM_LEVEL) and above
+#
+APP_PIE := $(strip $(APP_PIE))
+$(call ndk_log,  APP_PIE is $(APP_PIE))
+ifndef APP_PIE
+    ifneq (,$(call gte,$(APP_PLATFORM_LEVEL),$(NDK_FIRST_PIE_PLATFORM_LEVEL)))
+        APP_PIE := true
+        $(call ndk_log,  Enabling -fPIE)
+    else
+        APP_PIE := false
+    endif
+endif
+
+# Check that the value of APP_ABI corresponds to known ABIs
+# 'all' is a special case that means 'all supported ABIs'
+#
+# It will be handled in setup-app.mk. We can't hope to change
+# the value of APP_ABI is the user enforces it on the command-line
+# with a call like:  ndk-build APP_ABI=all
+#
+# Because GNU Make makes the APP_ABI variable read-only (any assignments
+# to it will be ignored)
+#
+APP_ABI := $(subst $(comma),$(space),$(strip $(APP_ABI)))
+ifndef APP_ABI
+    APP_ABI := $(NDK_DEFAULT_ABIS)
+endif
+
+# If APP_BUILD_SCRIPT is defined, check that the file exists.
+# If undefined, look in $(APP_PROJECT_PATH)/jni/Android.mk
+#
+APP_BUILD_SCRIPT := $(strip $(APP_BUILD_SCRIPT))
+ifdef APP_BUILD_SCRIPT
+    _build_script := $(strip $(wildcard $(APP_BUILD_SCRIPT)))
+    ifndef _build_script
+        $(call __ndk_info,Your APP_BUILD_SCRIPT points to an unknown file: $(APP_BUILD_SCRIPT))
+        $(call __ndk_error,Aborting...)
+    endif
+    APP_BUILD_SCRIPT := $(_build_script)
+    $(call ndk_log,  Using build script $(APP_BUILD_SCRIPT))
+else
+    ifeq (null,$(APP_PROJECT_PATH))
+      $(call __ndk_info,NDK_PROJECT_PATH==null.  Please explicitly set APP_BUILD_SCRIPT.)
+      $(call __ndk_error,Aborting.)
+    endif
+
+    _build_script := $(strip $(wildcard $(APP_PROJECT_PATH)/jni/Android.mk))
+    ifndef _build_script
+        $(call __ndk_info,There is no Android.mk under $(APP_PROJECT_PATH)/jni)
+        $(call __ndk_info,If this is intentional, please define APP_BUILD_SCRIPT to point)
+        $(call __ndk_info,to a valid NDK build script.)
+        $(call __ndk_error,Aborting...)
+    endif
+    APP_BUILD_SCRIPT := $(_build_script)
+    $(call ndk_log,  Defaulted to APP_BUILD_SCRIPT=$(APP_BUILD_SCRIPT))
+endif
+
+# Determine whether the application should be debuggable.
+# - If APP_DEBUG is set to 'true', then it always should.
+# - If APP_DEBUG is set to 'false', then it never should
+# - Otherwise, extract the android:debuggable attribute from the manifest.
+#
+ifdef APP_DEBUG
+  APP_DEBUGGABLE := $(APP_DEBUG)
+  ifeq ($(NDK_LOG),1)
+    ifeq ($(APP_DEBUG),true)
+      $(call ndk_log,Application '$(_app)' forced debuggable through NDK_DEBUG)
+    else
+      $(call ndk_log,Application '$(_app)' forced *not* debuggable through NDK_DEBUG)
+    endif
+  endif
+else
+  # NOTE: To make unit-testing simpler, handle the case where there is no manifest.
+  APP_DEBUGGABLE := false
+  ifdef APP_MANIFEST
+    APP_DEBUGGABLE := $(shell $(HOST_PYTHON) $(BUILD_PY)/extract_manifest.py debuggable $(call host-path,$(APP_MANIFEST)))
+  endif
+  ifeq ($(NDK_LOG),1)
+    ifeq ($(APP_DEBUGGABLE),true)
+      $(call ndk_log,Application '$(_app)' *is* debuggable)
+    else
+      $(call ndk_log,Application '$(_app)' is not debuggable)
+    endif
+  endif
+endif
+
+# LOCAL_BUILD_MODE will be either release or debug
+#
+# If APP_OPTIM is defined in the Application.mk, just use this.
+#
+# Otherwise, set to 'debug' if android:debuggable is set to TRUE,
+# and to 'release' if not.
+#
+ifneq ($(APP_OPTIM),)
+    # check that APP_OPTIM, if defined, is either 'release' or 'debug'
+    $(if $(filter-out release debug,$(APP_OPTIM)),\
+        $(call __ndk_info, The APP_OPTIM defined in $(_application_mk) must only be 'release' or 'debug')\
+        $(call __ndk_error,Aborting)\
+    )
+    $(call ndk_log,Selecting optimization mode through Application.mk: $(APP_OPTIM))
+else
+    ifeq ($(APP_DEBUGGABLE),true)
+        $(call ndk_log,Selecting debug optimization mode (app is debuggable))
+        APP_OPTIM := debug
+    else
+        $(call ndk_log,Selecting release optimization mode (app is not debuggable))
+        APP_OPTIM := release
+    endif
+endif
+
+APP_CFLAGS := $(strip $(APP_CFLAGS))
+APP_CONLYFLAGS := $(strip $(APP_CONLYFLAGS))
+APP_CPPFLAGS := $(strip $(APP_CPPFLAGS))
+APP_CXXFLAGS := $(strip $(APP_CXXFLAGS))
+APP_RENDERSCRIPT_FLAGS := $(strip $(APP_RENDERSCRIPT_FLAGS))
+APP_ASFLAGS := $(strip $(APP_ASFLAGS))
+APP_ASMFLAGS := $(strip $(APP_ASMFLAGS))
+APP_LDFLAGS  := $(strip $(APP_LDFLAGS))
+
+# Check that APP_STL is defined. If not, use the default value (system)
+# otherwise, check that the name is correct.
+APP_STL := $(strip $(APP_STL))
+ifndef APP_STL
+    APP_STL := system
+else
+    $(call ndk-stl-check,$(APP_STL))
+endif
+
+ifneq ($(filter $(APP_STL),gnustl_static gnustl_shared stlport_static stlport_shared),)
+    $(call __ndk_info,WARNING: APP_STL $(APP_STL) is deprecated and will be \
+        removed in the next release. Please switch to either c++_static or \
+        c++_shared. See \
+        https://developer.android.com/ndk/guides/cpp-support.html for more \
+        information.)
+endif
+
+# wrap.sh files can be specified in the user's Application.mk in either an
+# ABI-generic (APP_WRAP_SH) or ABI-specific (APP_WRAP_SH_x86, etc) fashion.
+# These two approaches cannot be combined; if any ABI-specific wrap.sh files are
+# specified then it is an error to also specify an ABI-generic one.
+#
+# After this block, only the ABI-specific values should be checked; if there is
+# an ABI-generic script specified the ABI-specific variables will be populated
+# with the generic script.
+NDK_NO_USER_WRAP_SH := true
+ifneq ($(APP_WRAP_SH),)
+    NDK_NO_USER_WRAP_SH := false
+endif
+
+NDK_HAVE_ABI_SPECIFIC_WRAP_SH := false
+$(foreach _abi,$(NDK_ALL_ABIS),\
+    $(if $(APP_WRAP_SH_$(_abi)),\
+        $(eval NDK_HAVE_ABI_SPECIFIC_WRAP_SH := true)))
+
+ifeq ($(NDK_HAVE_ABI_SPECIFIC_WRAP_SH),true)
+    # It is an error to have both ABI-specific and ABI-generic wrap.sh files
+    # specified.
+    ifneq ($(APP_WRAP_SH),)
+        $(call __ndk_error,Found both ABI-specific and ABI-generic APP_WRAP_SH \
+            directives. Must use either all ABI-specific or only ABI-generic.)
+    endif
+    NDK_NO_USER_WRAP_SH := false
+else
+    # If we have no ABI-specific wrap.sh files but we *do* have an ABI-generic
+    # one, install the generic one for all ABIs.
+    $(foreach _abi,$(NDK_ALL_ABIS),\
+        $(eval APP_WRAP_SH_$(_abi) := $(APP_WRAP_SH)))
+endif
+
+$(if $(call get,$(_map),defined),\
+  $(call __ndk_info,Weird, the application $(_app) is already defined by $(call get,$(_map),defined))\
+  $(call __ndk_error,Aborting)\
+)
+
+$(call set,$(_map),defined,$(_application_mk))
+
+# Record all app-specific variable definitions
+$(foreach __name,$(NDK_APP_VARS),\
+  $(call set,$(_map),$(__name),$($(__name)))\
+)
+
+# Record the Application.mk for debugging
+$(call set,$(_map),Application.mk,$(_application_mk))
+
+NDK_ALL_APPS += $(_app)
diff --git a/build/core/add-platform.mk b/build/core/add-platform.mk
new file mode 100644
index 0000000..da83717
--- /dev/null
+++ b/build/core/add-platform.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2009 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.
+#
+
+$(call assert-defined,_platform NDK_PLATFORMS_ROOT)
+
+# For each platform, determine the corresponding supported ABIs
+# And record them in NDK_PLATFORM_$(platform)_ABIS
+#
+_abis := $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/$(_platform)/arch-*)))
+_abis := $(_abis:arch-%=%)
+
+$(call ndk_log,PLATFORM $(_platform) supports: $(_abis))
+
+NDK_PLATFORM_$(_platform)_ABIS    := $(_abis)
+
+# Record the sysroots for each supported ABI
+#
+$(foreach _abi,$(_abis),\
+  $(eval NDK_PLATFORM_$(_platform)_$(_abi)_SYSROOT := $(NDK_PLATFORMS_ROOT)/$(_platform)/arch-$(_abi))\
+  $(call ndk_log,  ABI $(_abi) sysroot is: $(NDK_PLATFORM_$(_platform)_$(_abi)_SYSROOT))\
+)
diff --git a/build/core/add-toolchain.mk b/build/core/add-toolchain.mk
new file mode 100644
index 0000000..d852754
--- /dev/null
+++ b/build/core/add-toolchain.mk
@@ -0,0 +1,85 @@
+# Copyright (C) 2009 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.
+#
+
+# this script is included repeatedly by main.mk to add a new toolchain
+# definition to the NDK build system.
+#
+# '_config_mk' must be defined as the path of a toolchain
+# configuration file (config.mk) that will be included here.
+#
+$(call assert-defined, _config_mk)
+
+# The list of variables that must or may be defined
+# by the toolchain configuration file
+#
+NDK_TOOLCHAIN_VARS_REQUIRED := TOOLCHAIN_ABIS TOOLCHAIN_ARCH
+NDK_TOOLCHAIN_VARS_OPTIONAL :=
+
+# Clear variables that are supposed to be defined by the config file
+$(call clear-vars,$(NDK_TOOLCHAIN_VARS_REQUIRED))
+$(call clear-vars,$(NDK_TOOLCHAIN_VARS_OPTIONAL))
+
+# Include the config file
+include $(_config_mk)
+
+ifeq ($(TOOLCHAIN_ABIS)$(TOOLCHAIN_ARCH),)
+# Ignore if both TOOLCHAIN_ABIS and TOOLCHAIN_ARCH are not defined
+else
+
+# Check that the proper variables were defined
+$(call check-required-vars,$(NDK_TOOLCHAIN_VARS_REQUIRED),$(_config_mk))
+
+# Check that the file didn't do something stupid
+$(call assert-defined, _config_mk)
+
+# Now record the toolchain-specific information
+_dir  := $(patsubst %/,%,$(dir $(_config_mk)))
+_name := $(notdir $(_dir))
+_arch := $(TOOLCHAIN_ARCH)
+_abis := $(TOOLCHAIN_ABIS)
+
+_toolchain := NDK_TOOLCHAIN.$(_name)
+
+# check that the toolchain name is unique
+$(if $(strip $($(_toolchain).defined)),\
+  $(call __ndk_error,Toolchain $(_name) defined in $(_parent) is\
+                     already defined in $(NDK_TOOLCHAIN.$(_name).defined)))
+
+$(_toolchain).defined := $(_toolchain_config)
+$(_toolchain).arch    := $(_arch)
+$(_toolchain).abis    := $(_abis)
+$(_toolchain).setup   := $(wildcard $(_dir)/setup.mk)
+
+$(if $(strip $($(_toolchain).setup)),,\
+  $(call __ndk_error, Toolchain $(_name) lacks a setup.mk in $(_dir)))
+
+NDK_ALL_TOOLCHAINS += $(_name)
+NDK_ALL_ARCHS      += $(_arch)
+NDK_ALL_ABIS       += $(_abis)
+
+# NDK_ABI.<abi>.toolchains records the list of toolchains that support
+# a given ABI
+#
+$(foreach _abi,$(_abis),\
+    $(eval NDK_ABI.$(_abi).toolchains += $(_name)) \
+    $(eval NDK_ABI.$(_abi).arch := $(sort $(NDK_ABI.$(_abi).arch) $(_arch)))\
+)
+
+NDK_ARCH.$(_arch).toolchains += $(_name)
+NDK_ARCH.$(_arch).abis := $(sort $(NDK_ARCH.$(_arch).abis) $(_abis))
+
+endif
+
+# done
diff --git a/build/core/build-all.mk b/build/core/build-all.mk
new file mode 100644
index 0000000..b94f5fb
--- /dev/null
+++ b/build/core/build-all.mk
@@ -0,0 +1,122 @@
+# Copyright (C) 2009-2010 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.
+#
+
+#
+# This script is used to build all wanted NDK binaries. It is included
+# by several scripts.
+#
+
+# ensure that the following variables are properly defined
+$(call assert-defined,NDK_APPS NDK_APP_OUT)
+
+# ====================================================================
+#
+# Prepare the build for parsing Android.mk files
+#
+# ====================================================================
+
+# These phony targets are used to control various stages of the build
+.PHONY: all \
+        host_libraries host_executables \
+        installed_modules \
+        executables libraries static_libraries shared_libraries \
+        clean clean-objs-dir \
+        clean-executables clean-libraries \
+        clean-installed-modules \
+        clean-installed-binaries
+
+# These macros are used in Android.mk to include the corresponding
+# build script that will parse the LOCAL_XXX variable definitions.
+#
+CLEAR_VARS                := $(BUILD_SYSTEM)/clear-vars.mk
+BUILD_HOST_EXECUTABLE     := $(BUILD_SYSTEM)/build-host-executable.mk
+BUILD_HOST_STATIC_LIBRARY := $(BUILD_SYSTEM)/build-host-static-library.mk
+BUILD_STATIC_LIBRARY      := $(BUILD_SYSTEM)/build-static-library.mk
+BUILD_SHARED_LIBRARY      := $(BUILD_SYSTEM)/build-shared-library.mk
+BUILD_EXECUTABLE          := $(BUILD_SYSTEM)/build-executable.mk
+PREBUILT_SHARED_LIBRARY   := $(BUILD_SYSTEM)/prebuilt-shared-library.mk
+PREBUILT_STATIC_LIBRARY   := $(BUILD_SYSTEM)/prebuilt-static-library.mk
+
+ANDROID_MK_INCLUDED := \
+  $(CLEAR_VARS) \
+  $(BUILD_HOST_EXECUTABLE) \
+  $(BUILD_HOST_STATIC_LIBRARY) \
+  $(BUILD_STATIC_LIBRARY) \
+  $(BUILD_SHARED_LIBRARY) \
+  $(BUILD_EXECUTABLE) \
+  $(PREBUILT_SHARED_LIBRARY) \
+
+
+# this is the list of directories containing dependency information
+# generated during the build. It will be updated by build scripts
+# when module definitions are parsed.
+#
+ALL_DEPENDENCY_DIRS :=
+
+# this is the list of all generated files that we would need to clean
+ALL_HOST_EXECUTABLES      :=
+ALL_HOST_STATIC_LIBRARIES :=
+ALL_STATIC_LIBRARIES      :=
+ALL_SHARED_LIBRARIES      :=
+ALL_EXECUTABLES           :=
+
+WANTED_INSTALLED_MODULES  :=
+
+# the first rule
+all: installed_modules host_libraries host_executables
+
+
+$(foreach _app,$(NDK_APPS),\
+  $(eval include $(BUILD_SYSTEM)/setup-app.mk)\
+)
+
+ifeq (,$(strip $(WANTED_INSTALLED_MODULES)))
+    ifneq (,$(strip $(NDK_APP_MODULES)))
+        $(call __ndk_warning,WARNING: No modules to build, your APP_MODULES definition is probably incorrect!)
+    else
+        $(call __ndk_warning,WARNING: There are no modules to build in this project!)
+    endif
+endif
+
+# ====================================================================
+#
+# Now finish the build preparation with a few rules that depend on
+# what has been effectively parsed and recorded previously
+#
+# ====================================================================
+
+clean: clean-intermediates clean-installed-binaries
+
+distclean: clean
+
+installed_modules: clean-installed-binaries libraries $(WANTED_INSTALLED_MODULES)
+host_libraries: $(HOST_STATIC_LIBRARIES)
+host_executables: $(HOST_EXECUTABLES)
+
+static_libraries: $(STATIC_LIBRARIES)
+shared_libraries: $(SHARED_LIBRARIES)
+executables: $(EXECUTABLES)
+
+libraries: static_libraries shared_libraries
+
+clean-host-intermediates:
+	$(hide) $(call host-rm,$(HOST_EXECUTABLES) $(HOST_STATIC_LIBRARIES))
+
+clean-intermediates: clean-host-intermediates
+	$(hide) $(call host-rm,$(EXECUTABLES) $(STATIC_LIBRARIES) $(SHARED_LIBRARIES))
+	
+# include dependency information
+ALL_DEPENDENCY_DIRS := $(patsubst %/,%,$(sort $(ALL_DEPENDENCY_DIRS)))
+-include $(wildcard $(ALL_DEPENDENCY_DIRS:%=%/*.d))
diff --git a/build/core/build-binary.mk b/build/core/build-binary.mk
new file mode 100644
index 0000000..f65e563
--- /dev/null
+++ b/build/core/build-binary.mk
@@ -0,0 +1,805 @@
+# Copyright (C) 2008 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.
+#
+
+# Check that LOCAL_MODULE is defined, then restore its LOCAL_XXXX values
+$(call assert-defined,LOCAL_MODULE)
+$(call module-restore-locals,$(LOCAL_MODULE))
+
+# As in build-module.mk, eval sucks. Manually unstash the cflags variations to
+# preserve -Werror=#warnings.
+LOCAL_CFLAGS := $(__ndk_modules.$(LOCAL_MODULE).CFLAGS)
+LOCAL_CONLYFLAGS := $(__ndk_modules.$(LOCAL_MODULE).CONLYFLAGS)
+LOCAL_CPPFLAGS := $(__ndk_modules.$(LOCAL_MODULE).CPPFLAGS)
+LOCAL_CXXFLAGS := $(__ndk_modules.$(LOCAL_MODULE).CXXFLAGS)
+
+# For now, only support target (device-specific modules).
+# We may want to introduce support for host modules in the future
+# but that is too experimental for now.
+#
+my := TARGET_
+
+# LOCAL_MAKEFILE must also exist and name the Android.mk that
+# included the module build script.
+#
+$(call assert-defined,LOCAL_MAKEFILE LOCAL_BUILD_SCRIPT LOCAL_BUILT_MODULE)
+
+# A list of LOCAL_XXX variables that are ignored for static libraries.
+# Print a warning if they are present inside a module definition to let
+# the user know this won't do what he/she expects.
+not_in_static_libs := \
+    LOCAL_LDFLAGS \
+    LOCAL_LDLIBS \
+    LOCAL_ALLOW_UNDEFINED_SYMBOLS
+
+ifeq ($(call module-get-class,$(LOCAL_MODULE)),STATIC_LIBRARY)
+$(foreach _notvar,$(not_in_static_libs),\
+    $(if $(strip $($(_notvar))),\
+        $(call __ndk_info,WARNING:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): $(_notvar) is always ignored for static libraries)\
+    )\
+)
+endif
+
+# Some developers like to add library names (e.g. -lfoo) to LOCAL_LDLIBS
+# and LOCAL_LDFLAGS directly. This is very fragile and can lead to broken
+# builds and other nasty surprises, because it doesn't tell ndk-build
+# that the corresponding module depends on these files. Emit a warning
+# when we detect this case.
+libs_in_ldflags := $(filter -l% %.so %.a,$(LOCAL_LDLIBS) $(LOCAL_LDFLAGS))
+
+# Since the above will glob anything ending in .so or .a, we need to filter out
+# any cases of -Wl,--exclude-libs since we use that to hide symbols in STLs.
+libs_in_ldflags := \
+    $(filter-out -Wl$(comma)--exclude-libs$(comma)%,$(libs_in_ldflags))
+
+# Remove the system libraries we know about from the warning, it's ok
+# (and actually expected) to link them with -l<name>.
+system_libs := \
+    EGL \
+    GLESv1_CM \
+    GLESv2 \
+    GLESv3 \
+    OpenMAXAL \
+    OpenSLES \
+    aaudio \
+    android \
+    atomic \
+    c \
+    camera2ndk \
+    dl \
+    jnigraphics \
+    log \
+    m \
+    mediandk \
+    stdc++ \
+    vulkan \
+    z \
+
+libs_in_ldflags := $(filter-out $(addprefix -l,$(system_libs)), $(libs_in_ldflags))
+
+ifneq (,$(strip $(libs_in_ldflags)))
+  $(call __ndk_info,WARNING:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): non-system libraries in linker flags: $(libs_in_ldflags))
+  $(call __ndk_info,    This is likely to result in incorrect builds. Try using LOCAL_STATIC_LIBRARIES)
+  $(call __ndk_info,    or LOCAL_SHARED_LIBRARIES instead to list the library dependencies of the)
+  $(call __ndk_info,    current module)
+endif
+
+include $(BUILD_SYSTEM)/import-locals.mk
+
+# Check for LOCAL_THIN_ARCHIVE / APP_THIN_ARCHIVE and print a warning if
+# it is defined for non-static library modules.
+thin_archive := $(strip $(LOCAL_THIN_ARCHIVE))
+ifdef thin_archive
+ifneq (STATIC_LIBRARY,$(call module-get-class,$(LOCAL_MODULE)))
+    $(call __ndk_info,WARNING:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_THIN_ARCHIVE is for building static libraries)
+endif
+endif
+
+ifndef thin_archive
+    thin_archive := $(strip $(NDK_APP_THIN_ARCHIVE))
+endif
+# Print a warning if the value is not 'true', 'false' or empty.
+ifneq (,$(filter-out true false,$(thin_archive)))
+    $(call __ndk_info,WARNING:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): Invalid LOCAL_THIN_ARCHIVE value '$(thin_archive)' ignored!)
+    thin_archive :=
+endif
+
+#
+# Ensure that 'make <module>' and 'make clean-<module>' work
+#
+.PHONY: $(LOCAL_MODULE)
+$(LOCAL_MODULE): $(LOCAL_BUILT_MODULE)
+
+cleantarget := clean-$(LOCAL_MODULE)-$(TARGET_ARCH_ABI)
+.PHONY: $(cleantarget)
+clean: $(cleantarget)
+
+$(cleantarget): PRIVATE_ABI         := $(TARGET_ARCH_ABI)
+$(cleantarget): PRIVATE_MODULE      := $(LOCAL_MODULE)
+ifneq ($(LOCAL_BUILT_MODULE_NOT_COPIED),true)
+$(cleantarget): PRIVATE_CLEAN_FILES := $(LOCAL_BUILT_MODULE) \
+                                       $($(my)OBJS)
+else
+$(cleantarget): PRIVATE_CLEAN_FILES := $($(my)OBJS)
+endif
+$(cleantarget)::
+	$(call host-echo-build-step,$(PRIVATE_ABI),Clean) "$(PRIVATE_MODULE) [$(PRIVATE_ABI)]"
+	$(hide) $(call host-rmdir,$(PRIVATE_CLEAN_FILES))
+
+ifeq ($(NDK_APP_DEBUGGABLE),true)
+$(NDK_APP_GDBSETUP): PRIVATE_SRC_DIRS += $(LOCAL_C_INCLUDES) $(LOCAL_PATH)
+endif
+
+# list of generated object files
+LOCAL_OBJECTS :=
+
+# list of generated object files from RS files, subset of LOCAL_OBJECTS
+LOCAL_RS_OBJECTS :=
+
+# always define ANDROID when building binaries
+#
+LOCAL_CFLAGS := -DANDROID $(LOCAL_CFLAGS)
+LOCAL_CFLAGS += -D__ANDROID_API__=$(TARGET_PLATFORM_LEVEL)
+
+#
+# Add the default system shared libraries to the build
+#
+ifeq ($(LOCAL_SYSTEM_SHARED_LIBRARIES),none)
+  LOCAL_SHARED_LIBRARIES += $(TARGET_DEFAULT_SYSTEM_SHARED_LIBRARIES)
+else
+  LOCAL_SHARED_LIBRARIES += $(LOCAL_SYSTEM_SHARED_LIBRARIES)
+endif
+
+#
+# Check LOCAL_CPP_EXTENSION
+#
+bad_cpp_extensions := $(strip $(filter-out .%,$(LOCAL_CPP_EXTENSION)))
+ifdef bad_cpp_extensions
+    $(call __ndk_info,WARNING: Invalid LOCAL_CPP_EXTENSION values: $(bad_cpp_extensions))
+    LOCAL_CPP_EXTENSION := $(filter $(bad_cpp_extensions),$(LOCAL_CPP_EXTENSIONS))
+endif
+LOCAL_CPP_EXTENSION := $(strip $(LOCAL_CPP_EXTENSION))
+ifeq ($(LOCAL_CPP_EXTENSION),)
+  # Match the default GCC C++ extensions.
+  LOCAL_CPP_EXTENSION := $(default-c++-extensions)
+endif
+LOCAL_RS_EXTENSION := $(default-rs-extensions)
+
+LOCAL_LDFLAGS += -Wl,--build-id
+
+ifeq ($(NDK_TOOLCHAIN_VERSION),clang)
+    ifeq ($(filter system stlport_shared stlport_static,$(NDK_APP_STL)),)
+        LOCAL_LDFLAGS += -nostdlib++
+    endif
+endif
+
+#
+# If LOCAL_ALLOW_UNDEFINED_SYMBOLS is not true, the linker will allow the generation
+# of a binary that uses undefined symbols.
+#
+ifneq ($(LOCAL_ALLOW_UNDEFINED_SYMBOLS),true)
+  LOCAL_LDFLAGS += $($(my)NO_UNDEFINED_LDFLAGS)
+endif
+
+# Toolchain by default disallows generated code running from the heap and stack.
+# If LOCAL_DISABLE_NO_EXECUTE is true, we allow that
+#
+ifeq ($(LOCAL_DISABLE_NO_EXECUTE),true)
+  LOCAL_CFLAGS += $($(my)DISABLE_NO_EXECUTE_CFLAGS)
+  LOCAL_LDFLAGS += $($(my)DISABLE_NO_EXECUTE_LDFLAGS)
+else
+  LOCAL_CFLAGS += $($(my)NO_EXECUTE_CFLAGS)
+  LOCAL_LDFLAGS += $($(my)NO_EXECUTE_LDFLAGS)
+endif
+
+# Toolchain by default provides relro and GOT protections.
+# If LOCAL_DISABLE_RELRO is true, we disable the protections.
+#
+ifeq ($(LOCAL_DISABLE_RELRO),true)
+  LOCAL_LDFLAGS += $($(my)DISABLE_RELRO_LDFLAGS)
+else
+  LOCAL_LDFLAGS += $($(my)RELRO_LDFLAGS)
+endif
+
+# We enable shared text relocation warnings by default. These are not allowed in
+# current versions of Android (android-21 for LP64 ABIs, android-23 for LP32
+# ABIs).
+LOCAL_LDFLAGS += -Wl,--warn-shared-textrel
+
+# We enable fatal linker warnings by default.
+# If LOCAL_DISABLE_FATAL_LINKER_WARNINGS is true, we don't enable this check.
+ifneq ($(LOCAL_DISABLE_FATAL_LINKER_WARNINGS),true)
+  LOCAL_LDFLAGS += -Wl,--fatal-warnings
+endif
+
+# By default, we protect against format string vulnerabilities
+# If LOCAL_DISABLE_FORMAT_STRING_CHECKS is true, we disable the protections.
+ifeq ($(LOCAL_DISABLE_FORMAT_STRING_CHECKS),true)
+  LOCAL_CFLAGS += $($(my)DISABLE_FORMAT_STRING_CFLAGS)
+else
+  LOCAL_CFLAGS += $($(my)FORMAT_STRING_CFLAGS)
+endif
+
+# enable PIE for executable beyond certain API level, unless "-static"
+ifneq (,$(filter true,$(NDK_APP_PIE) $(TARGET_PIE)))
+  ifeq ($(call module-get-class,$(LOCAL_MODULE)),EXECUTABLE)
+    ifeq (,$(filter -static,$(TARGET_LDFLAGS) $(LOCAL_LDFLAGS) $(NDK_APP_LDFLAGS)))
+      # x86 and x86_64 use large model pic, whereas everything else uses small
+      # model. In the past we've always used -fPIE, but the LLVMgold plugin (for
+      # LTO) complains if the models are mismatched.
+      ifneq (,$(filter x86 x86_64,$(TARGET_ARCH_ABI)))
+        LOCAL_CFLAGS += -fPIE
+        LOCAL_LDFLAGS += -fPIE -pie
+      else
+        LOCAL_CFLAGS += -fpie
+        LOCAL_LDFLAGS += -fpie -pie
+      endif
+    endif
+  endif
+endif
+
+# http://b.android.com/222239
+# http://b.android.com/220159 (internal http://b/31809417)
+# x86 devices have stack alignment issues.
+ifeq ($(TARGET_ARCH_ABI),x86)
+    LOCAL_CFLAGS += -mstackrealign
+endif
+
+# https://github.com/android-ndk/ndk/issues/297
+ifeq ($(TARGET_ARCH_ABI),x86)
+    ifneq (,$(call lt,$(APP_PLATFORM_LEVEL),17))
+        ifeq ($(NDK_TOOLCHAIN_VERSION),4.9)
+            LOCAL_CFLAGS += -mstack-protector-guard=global
+        endif
+    endif
+endif
+
+#
+# The original Android build system allows you to use the .arm prefix
+# to a source file name to indicate that it should be defined in either
+# 'thumb' or 'arm' mode, depending on the value of LOCAL_ARM_MODE
+#
+# First, check LOCAL_ARM_MODE, it should be empty, 'thumb' or 'arm'
+# We make the default 'thumb'
+#
+LOCAL_ARM_MODE := $(strip $(LOCAL_ARM_MODE))
+ifdef LOCAL_ARM_MODE
+  ifneq ($(words $(LOCAL_ARM_MODE)),1)
+      $(call __ndk_info,   LOCAL_ARM_MODE in $(LOCAL_MAKEFILE) must be one word, not '$(LOCAL_ARM_MODE)')
+      $(call __ndk_error, Aborting)
+  endif
+  # check that LOCAL_ARM_MODE is defined to either 'arm' or 'thumb'
+  $(if $(filter-out thumb arm, $(LOCAL_ARM_MODE)),\
+      $(call __ndk_info,   LOCAL_ARM_MODE must be defined to either 'arm' or 'thumb' in $(LOCAL_MAKEFILE) not '$(LOCAL_ARM_MODE)')\
+      $(call __ndk_error, Aborting)\
+  )
+  my_link_arm_mode := $(LOCAL_ARM_MODE)
+else
+  my_link_arm_mode := thumb
+endif
+
+# As a special case, the original Android build system
+# allows one to specify that certain source files can be
+# forced to build in ARM mode by using a '.arm' suffix
+# after the extension, e.g.
+#
+#  LOCAL_SRC_FILES := foo.c.arm
+#
+# to build source file $(LOCAL_PATH)/foo.c as ARM
+#
+
+$(call clear-all-src-tags)
+
+# As a special extension, the NDK also supports the .neon extension suffix
+# to indicate that a single file can be compiled with ARM NEON support
+# We must support both foo.c.neon and foo.c.arm.neon here
+#
+# Also, if LOCAL_ARM_NEON is set to 'true', force Neon mode for all source
+# files
+#
+
+neon_sources  := $(filter %.neon,$(LOCAL_SRC_FILES))
+neon_sources  := $(neon_sources:%.neon=%)
+
+LOCAL_ARM_NEON := $(strip $(LOCAL_ARM_NEON))
+ifdef LOCAL_ARM_NEON
+  $(if $(filter-out true false,$(LOCAL_ARM_NEON)),\
+    $(call __ndk_info,LOCAL_ARM_NEON must be defined either to 'true' or 'false' in $(LOCAL_MAKEFILE), not '$(LOCAL_ARM_NEON)')\
+    $(call __ndk_error,Aborting) \
+  )
+endif
+ifeq ($(LOCAL_ARM_NEON),true)
+  neon_sources += $(LOCAL_SRC_FILES:%.neon=%)
+  # tag the precompiled header with 'neon' tag if it exists
+  ifneq (,$(LOCAL_PCH))
+    $(call tag-src-files,$(LOCAL_PCH),neon)
+  endif
+endif
+
+neon_sources := $(strip $(neon_sources))
+ifdef neon_sources
+  ifeq ($(filter $(TARGET_ARCH_ABI), armeabi-v7a arm64-v8a x86 x86_64),)
+    $(call __ndk_info,NEON support is only available for armeabi-v7a, arm64-v8a, x86, and x86_64 ABIs)
+    $(call __ndk_info,Please add checks against TARGET_ARCH_ABI in $(LOCAL_MAKEFILE))
+    $(call __ndk_error,Aborting)
+  endif
+  $(call tag-src-files,$(neon_sources:%.arm=%),neon)
+endif
+
+LOCAL_SRC_FILES := $(LOCAL_SRC_FILES:%.neon=%)
+
+# strip the .arm suffix from LOCAL_SRC_FILES
+# and tag the relevant sources with the 'arm' tag
+#
+arm_sources     := $(filter %.arm,$(LOCAL_SRC_FILES))
+arm_sources     := $(arm_sources:%.arm=%)
+thumb_sources   := $(filter-out %.arm,$(LOCAL_SRC_FILES))
+LOCAL_SRC_FILES := $(LOCAL_SRC_FILES:%.arm=%)
+
+ifeq ($(LOCAL_ARM_MODE),arm)
+    arm_sources := $(LOCAL_SRC_FILES)
+    # tag the precompiled header with 'arm' tag if it exists
+    ifneq (,$(LOCAL_PCH))
+        $(call tag-src-files,$(LOCAL_PCH),arm)
+    endif
+endif
+ifeq ($(LOCAL_ARM_MODE),thumb)
+    arm_sources := $(empty)
+endif
+$(call tag-src-files,$(arm_sources),arm)
+
+# tag debug if APP_OPTIM is 'debug'
+#
+ifeq ($(APP_OPTIM),debug)
+    $(call tag-src-files,$(LOCAL_SRC_FILES),debug)
+    ifneq (,$(LOCAL_PCH))
+        $(call tag-src-files,$(LOCAL_PCH),debug)
+    endif
+endif
+
+# add PCH to LOCAL_SRC_FILES so that TARGET-process-src-files-tags could process it
+ifneq (,$(LOCAL_PCH))
+    LOCAL_SRC_FILES += $(LOCAL_PCH)
+endif
+
+# Process all source file tags to determine toolchain-specific
+# target compiler flags, and text.
+#
+$(call TARGET-process-src-files-tags)
+
+# now remove PCH from LOCAL_SRC_FILES to prevent getting NDK warning about
+# unsupported source file extensions
+ifneq (,$(LOCAL_PCH))
+    LOCAL_SRC_FILES := $(filter-out $(LOCAL_PCH),$(LOCAL_SRC_FILES))
+endif
+
+# only call dump-src-file-tags during debugging
+#$(dump-src-file-tags)
+
+LOCAL_DEPENDENCY_DIRS :=
+
+# all_source_patterns contains the list of filename patterns that correspond
+# to source files recognized by our build system
+ifneq ($(filter x86 x86_64, $(TARGET_ARCH_ABI)),)
+all_source_extensions := .c .s .S .asm $(LOCAL_CPP_EXTENSION) $(LOCAL_RS_EXTENSION)
+else
+all_source_extensions := .c .s .S $(LOCAL_CPP_EXTENSION) $(LOCAL_RS_EXTENSION)
+endif
+all_source_patterns   := $(foreach _ext,$(all_source_extensions),%$(_ext))
+all_cpp_patterns      := $(foreach _ext,$(LOCAL_CPP_EXTENSION),%$(_ext))
+all_rs_patterns       := $(foreach _ext,$(LOCAL_RS_EXTENSION),%$(_ext))
+
+unknown_sources := $(strip $(filter-out $(all_source_patterns),$(LOCAL_SRC_FILES)))
+ifdef unknown_sources
+    $(call __ndk_info,WARNING: Unsupported source file extensions in $(LOCAL_MAKEFILE) for module $(LOCAL_MODULE))
+    $(call __ndk_info,  $(unknown_sources))
+endif
+
+# LOCAL_OBJECTS will list all object files corresponding to the sources
+# listed in LOCAL_SRC_FILES, in the *same* order.
+#
+LOCAL_OBJECTS := $(LOCAL_SRC_FILES)
+$(foreach _ext,$(all_source_extensions),\
+    $(eval LOCAL_OBJECTS := $$(LOCAL_OBJECTS:%$(_ext)=%$$(TARGET_OBJ_EXTENSION)))\
+)
+LOCAL_OBJECTS := $(filter %$(TARGET_OBJ_EXTENSION),$(LOCAL_OBJECTS))
+LOCAL_OBJECTS := $(subst ../,__/,$(LOCAL_OBJECTS))
+LOCAL_OBJECTS := $(subst :,_,$(LOCAL_OBJECTS))
+LOCAL_OBJECTS := $(foreach _obj,$(LOCAL_OBJECTS),$(LOCAL_OBJS_DIR)/$(_obj))
+
+LOCAL_RS_OBJECTS := $(filter $(all_rs_patterns),$(LOCAL_SRC_FILES))
+$(foreach _ext,$(LOCAL_RS_EXTENSION),\
+    $(eval LOCAL_RS_OBJECTS := $$(LOCAL_RS_OBJECTS:%$(_ext)=%$$(TARGET_OBJ_EXTENSION)))\
+)
+LOCAL_RS_OBJECTS := $(filter %$(TARGET_OBJ_EXTENSION),$(LOCAL_RS_OBJECTS))
+LOCAL_RS_OBJECTS := $(subst ../,__/,$(LOCAL_RS_OBJECTS))
+LOCAL_RS_OBJECTS := $(subst :,_,$(LOCAL_RS_OBJECTS))
+LOCAL_RS_OBJECTS := $(foreach _obj,$(LOCAL_RS_OBJECTS),$(LOCAL_OBJS_DIR)/$(_obj))
+
+# If the module has any kind of C++ features, enable them in LOCAL_CPPFLAGS
+#
+ifneq (,$(call module-has-c++-features,$(LOCAL_MODULE),rtti))
+    LOCAL_CPPFLAGS += -frtti
+endif
+ifneq (,$(call module-has-c++-features,$(LOCAL_MODULE),exceptions))
+    LOCAL_CPPFLAGS += -fexceptions
+endif
+
+# Set include patch for renderscript
+ifneq ($(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE),)
+    LOCAL_RENDERSCRIPT_INCLUDES := $(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE)
+else
+    LOCAL_RENDERSCRIPT_INCLUDES := \
+        $(RENDERSCRIPT_PLATFORM_HEADER)/scriptc \
+        $(RENDERSCRIPT_TOOLCHAIN_HEADER) \
+        $(LOCAL_RENDERSCRIPT_INCLUDES)
+endif
+
+# Only enable the compatibility path when LOCAL_RENDERSCRIPT_COMPATIBILITY is defined.
+RS_COMPAT :=
+ifeq ($(LOCAL_RENDERSCRIPT_COMPATIBILITY),true)
+    RS_COMPAT := true
+endif
+
+
+# Build PCH
+
+get-pch-name = $(strip \
+    $(subst ../,__/,\
+        $(eval __pch := $1)\
+        $(eval __pch := $(__pch:%.h=%.precompiled.h))\
+        $(__pch)\
+    ))
+
+ifneq (,$(LOCAL_PCH))
+    # Build PCH into obj directory
+    LOCAL_BUILT_PCH := $(call get-pch-name,$(LOCAL_PCH))
+
+    # Clang whines about a "c-header" (.h rather than .hpp) being used in C++
+    # mode (note that we use compile-cpp-source to build the header).
+    LOCAL_SRC_FILES_TARGET_CFLAGS.$(LOCAL_PCH) += -x c++-header
+
+    # Build PCH
+    $(call compile-cpp-source,$(LOCAL_PCH),$(LOCAL_BUILT_PCH).gch)
+
+    # The PCH must be compiled the same way as the sources (thumb vs arm, neon
+    # vs non-neon must match). This means that we'd have to generate a PCH for
+    # each combination of foo.c.arm and foo.c.neon (do we allow
+    # foo.c.arm.neon?).
+    #
+    # Since files with those source tags should be the minority, precompiling
+    # that header might be a net loss compared to just using it normally. As
+    # such, we only use the PCH for the default compilation mode for the module.
+    #
+    # See https://github.com/android-ndk/ndk/issues/14
+    TAGS_TO_FILTER :=
+
+    # If neon is off, strip out .neon files.
+    ifneq (true,$(LOCAL_ARM_NEON))
+        TAGS_TO_FILTER += neon
+    endif
+
+    # If we're building thumb, strip out .arm files.
+    ifneq (arm,$(LOCAL_ARM_MODE))
+        TAGS_TO_FILTER += arm
+    endif
+
+    # There is no .thumb. No need to filter them out if we're building ARM.
+
+    allowed_src := $(foreach src,$(filter $(all_cpp_patterns),$(LOCAL_SRC_FILES)),\
+        $(if $(filter $(TAGS_TO_FILTER),$(LOCAL_SRC_FILES_TAGS.$(src))),,$(src))\
+    )
+    # All files without tags depend on PCH
+    $(foreach src,$(allowed_src),\
+        $(eval $(LOCAL_OBJS_DIR)/$(call get-object-name,$(src)) : $(LOCAL_OBJS_DIR)/$(LOCAL_BUILT_PCH).gch)\
+    )
+    # Make sure those files are built with PCH
+    $(call add-src-files-target-cflags,$(allowed_src),-Winvalid-pch -include $(LOCAL_OBJS_DIR)/$(LOCAL_BUILT_PCH))
+
+    # Insert PCH dir at beginning of include search path
+    LOCAL_C_INCLUDES := \
+        $(LOCAL_OBJS_DIR) \
+        $(LOCAL_C_INCLUDES)
+endif
+
+# Build the sources to object files
+#
+
+# Include RenderScript headers if rs files are found.
+ifneq ($(filter $(all_rs_patterns),$(LOCAL_SRC_FILES)),)
+    LOCAL_C_INCLUDES += \
+        $(RENDERSCRIPT_PLATFORM_HEADER) \
+        $(RENDERSCRIPT_PLATFORM_HEADER)/cpp \
+        $(TARGET_OBJS)/$(LOCAL_MODULE)
+endif
+
+$(foreach src,$(filter %.c,$(LOCAL_SRC_FILES)), $(call compile-c-source,$(src),$(call get-object-name,$(src))))
+$(foreach src,$(filter %.S %.s,$(LOCAL_SRC_FILES)), $(call compile-s-source,$(src),$(call get-object-name,$(src))))
+$(foreach src,$(filter $(all_cpp_patterns),$(LOCAL_SRC_FILES)),\
+    $(call compile-cpp-source,$(src),$(call get-object-name,$(src)))\
+)
+
+$(foreach src,$(filter $(all_rs_patterns),$(LOCAL_SRC_FILES)),\
+    $(call compile-rs-source,$(src),$(call get-rs-scriptc-name,$(src)),$(call get-rs-bc-name,$(src)),$(call get-rs-so-name,$(src)),$(call get-object-name,$(src)),$(RS_COMPAT))\
+)
+
+ifneq ($(filter x86 x86_64, $(TARGET_ARCH_ABI)),)
+$(foreach src,$(filter %.asm,$(LOCAL_SRC_FILES)), $(call compile-asm-source,$(src),$(call get-object-name,$(src))))
+endif
+
+#
+# The compile-xxx-source calls updated LOCAL_OBJECTS and LOCAL_DEPENDENCY_DIRS
+#
+ALL_DEPENDENCY_DIRS += $(sort $(LOCAL_DEPENDENCY_DIRS))
+CLEAN_OBJS_DIRS     += $(LOCAL_OBJS_DIR)
+
+#
+# Handle the static and shared libraries this module depends on
+#
+
+# If LOCAL_LDLIBS contains anything like -l<library> then
+# prepend a -L$(SYSROOT_LINK)/usr/lib to it to ensure that the linker
+# looks in the right location
+#
+ifneq ($(filter -l%,$(LOCAL_LDLIBS)),)
+    LOCAL_LDLIBS := -L$(call host-path,$(SYSROOT_LINK)/usr/lib) $(LOCAL_LDLIBS)
+    ifneq ($(filter x86_64 mips64,$(TARGET_ARCH_ABI)),)
+        LOCAL_LDLIBS := -L$(call host-path,$(SYSROOT_LINK)/usr/lib64) $(LOCAL_LDLIBS)
+    endif
+endif
+
+my_ldflags := $(TARGET_LDFLAGS) $(LOCAL_LDFLAGS) $(NDK_APP_LDFLAGS)
+ifneq ($(filter armeabi%,$(TARGET_ARCH_ABI)),)
+    my_ldflags += $(TARGET_$(my_link_arm_mode)_LDFLAGS)
+endif
+
+# When LOCAL_SHORT_COMMANDS is defined to 'true' we are going to write the
+# list of all object files and/or static/shared libraries that appear on the
+# command line to a file, then use the @<listfile> syntax to invoke it.
+#
+# This allows us to link or archive a huge number of stuff even on Windows
+# with its puny 8192 max character limit on its command-line.
+#
+LOCAL_SHORT_COMMANDS := $(strip $(LOCAL_SHORT_COMMANDS))
+ifndef LOCAL_SHORT_COMMANDS
+    LOCAL_SHORT_COMMANDS := $(strip $(NDK_APP_SHORT_COMMANDS))
+endif
+
+$(call generate-file-dir,$(LOCAL_BUILT_MODULE))
+
+$(LOCAL_BUILT_MODULE): PRIVATE_OBJECTS := $(LOCAL_OBJECTS)
+$(LOCAL_BUILT_MODULE): PRIVATE_LIBGCC := $(TARGET_LIBGCC)
+$(LOCAL_BUILT_MODULE): PRIVATE_LIBATOMIC := $(TARGET_LIBATOMIC)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_LD := $(TARGET_LD)
+$(LOCAL_BUILT_MODULE): PRIVATE_LDFLAGS := $(my_ldflags)
+$(LOCAL_BUILT_MODULE): PRIVATE_LDLIBS  := $(LOCAL_LDLIBS) $(TARGET_LDLIBS)
+
+$(LOCAL_BUILT_MODULE): PRIVATE_NAME := $(notdir $(LOCAL_BUILT_MODULE))
+$(LOCAL_BUILT_MODULE): PRIVATE_CXX := $(TARGET_CXX)
+$(LOCAL_BUILT_MODULE): PRIVATE_CC := $(TARGET_CC)
+$(LOCAL_BUILT_MODULE): PRIVATE_SYSROOT_LINK := $(SYSROOT_LINK)
+
+ifeq ($(call module-get-class,$(LOCAL_MODULE)),STATIC_LIBRARY)
+
+#
+# This is a static library module, things are very easy. We only need
+# to build the object files and archive them with 'ar'. Note that module
+# dependencies can be ignored here, i.e. if the module depends on other
+# static or shared libraries, there is no need to actually build them
+# before, so don't add Make dependencies to them.
+#
+# In other words, consider the following graph:
+#
+#     libfoo.so -> libA.a ->libB.a
+#
+# then libA.a and libB.a can be built in parallel, only linking libfoo.so
+# depends on their completion.
+#
+
+ar_objects := $(call host-path,$(LOCAL_OBJECTS))
+
+ifeq ($(LOCAL_SHORT_COMMANDS),true)
+    $(call ndk_log,Building static library module '$(LOCAL_MODULE)' with linker list file)
+    ar_list_file := $(LOCAL_OBJS_DIR)/archiver.list
+    $(call generate-list-file,\
+        $(call escape-backslashes,$(ar_objects)),$(ar_list_file))
+    ar_objects   := @$(call host-path,$(ar_list_file))
+    $(LOCAL_BUILT_MODULE): $(ar_list_file)
+endif
+
+# Compute 'ar' flags. Thin archives simply require 'T' here.
+ar_flags := $(TARGET_ARFLAGS)
+ifeq (true,$(thin_archive))
+    $(call ndk_log,$(TARGET_ARCH_ABI):Building static library '$(LOCAL_MODULE)' as thin archive)
+    ar_flags := $(ar_flags)T
+endif
+
+$(LOCAL_BUILT_MODULE): PRIVATE_ABI := $(TARGET_ARCH_ABI)
+$(LOCAL_BUILT_MODULE): PRIVATE_AR := $(TARGET_AR) $(ar_flags) $(TARGET_AR_FLAGS)
+$(LOCAL_BUILT_MODULE): PRIVATE_AR_OBJECTS := $(ar_objects)
+$(LOCAL_BUILT_MODULE): PRIVATE_BUILD_STATIC_LIB := $(cmd-build-static-library)
+
+$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
+	$(call host-echo-build-step,$(PRIVATE_ABI),StaticLibrary) "$(PRIVATE_NAME)"
+	$(hide) $(call host-rm,$@)
+	$(hide) $(PRIVATE_BUILD_STATIC_LIB)
+
+ALL_STATIC_LIBRARIES += $(LOCAL_BUILT_MODULE)
+
+endif
+
+ifneq (,$(filter SHARED_LIBRARY EXECUTABLE,$(call module-get-class,$(LOCAL_MODULE))))
+
+#
+# This is a shared library or an executable, so computing dependencies properly is
+# crucial. The general rule to apply is the following:
+#
+#   - collect the list of all static libraries that need to be part
+#     of the link, and in the right order. To do so, get the transitive
+#     closure of LOCAL_STATIC_LIBRARIES and LOCAL_WHOLE_STATIC_LIBRARIES
+#     and ensure they are ordered topologically.
+#
+#  - collect the list of all shared libraries that need to be part of
+#    the link. This is the transitive closure of the list of
+#    LOCAL_SHARED_LIBRARIES for the module and all its dependent static
+#    libraries identified in the step above. Of course, need to be
+#    ordered topologically too.
+#
+#  - add Make dependencies to ensure that all these libs are built
+#    before the module itself too.
+#
+# A few quick examples:
+#
+#    main.exe -> libA.a -> libB.a -> libfoo.so -> libC.a
+#
+#      static_libs(main.exe) = libA.a libB.a  (i.e. no libC.a)
+#      shared_libs(main.exe) = libfoo.so
+#      static_libs(libfoo.so) = libC.a
+#
+#    main.exe -> libA.a ---> libB.a
+#                  |           ^
+#                  v           |
+#                libC.a  ------
+#
+#      static_libs(main.exe) = libA.a libC.a libB.a
+#             (i.e. libB.a must appear after all libraries that depend on it).
+#
+all_libs := $(call module-get-link-libs,$(LOCAL_MODULE))
+shared_libs := $(call module-filter-shared-libraries,$(all_libs))
+static_libs := $(call module-filter-static-libraries,$(all_libs))
+whole_static_libs := $(call module-extract-whole-static-libs,$(LOCAL_MODULE),$(static_libs))
+static_libs := $(filter-out $(whole_static_libs),$(static_libs))
+all_defined_libs := $(shared_libs) $(static_libs) $(whole_static_libs)
+undefined_libs := $(filter-out $(all_defined_libs),$(all_libs))
+
+ifdef undefined_libs
+    $(call __ndk_warning,Module $(LOCAL_MODULE) depends on undefined modules: $(undefined_libs))
+
+    # https://github.com/android-ndk/ndk/issues/208
+    # ndk-build didn't used to fail the build for a missing dependency. This
+    # seems to have always been the behavior, so there's a good chance that
+    # there are builds out there that depend on this behavior (as of right now,
+    # anything using libc++ on ARM has this problem because of libunwind).
+    #
+    # By default we will abort in this situation because this is so completely
+    # broken. A user may define APP_ALLOW_MISSING_DEPS to "true" in their
+    # Application.mk or on the command line to revert to the old, broken
+    # behavior.
+    ifneq ($(APP_ALLOW_MISSING_DEPS),true)
+        $(call __ndk_error,Aborting (set APP_ALLOW_MISSING_DEPS=true to allow missing dependencies))
+    endif
+endif
+
+$(call -ndk-mod-debug,module $(LOCAL_MODULE) [$(LOCAL_BUILT_MODULE)])
+$(call -ndk-mod-debug,.  all_libs='$(all_libs)')
+$(call -ndk-mod-debug,.  shared_libs='$(shared_libs)')
+$(call -ndk-mod-debug,.  static_libs='$(static_libs)')
+$(call -ndk-mod-debug,.  whole_static_libs='$(whole_static_libs)')
+
+shared_libs       := $(call map,module-get-built,$(shared_libs))\
+                     $(TARGET_PREBUILT_SHARED_LIBRARIES)
+static_libs       := $(call map,module-get-built,$(static_libs))
+whole_static_libs := $(call map,module-get-built,$(whole_static_libs))
+
+$(call -ndk-mod-debug,.  built_shared_libs='$(shared_libs)')
+$(call -ndk-mod-debug,.  built_static_libs='$(static_libs)')
+$(call -ndk-mod-debug,.  built_whole_static_libs='$(whole_static_libs)')
+
+# The list of object/static/shared libraries passed to the linker when
+# building shared libraries and executables. order is important.
+#
+# Cannot use immediate evaluation because PRIVATE_LIBGCC may not be defined at this point.
+linker_objects_and_libraries = $(strip $(call TARGET-get-linker-objects-and-libraries,\
+    $(LOCAL_OBJECTS), \
+    $(static_libs), \
+    $(whole_static_libs), \
+    $(shared_libs)))
+
+ifeq ($(LOCAL_SHORT_COMMANDS),true)
+    $(call ndk_log,Building ELF binary module '$(LOCAL_MODULE)' with linker list file)
+    linker_options   := $(linker_objects_and_libraries)
+    linker_list_file := $(LOCAL_OBJS_DIR)/linker.list
+    linker_objects_and_libraries := @$(call host-path,$(linker_list_file))
+    $(call generate-list-file,$(linker_options),$(linker_list_file))
+    $(LOCAL_BUILT_MODULE): $(linker_list_file)
+endif
+
+$(LOCAL_BUILT_MODULE): $(shared_libs) $(static_libs) $(whole_static_libs)
+$(LOCAL_BUILT_MODULE): PRIVATE_ABI := $(TARGET_ARCH_ABI)
+$(LOCAL_BUILT_MODULE): PRIVATE_LINKER_OBJECTS_AND_LIBRARIES := $(linker_objects_and_libraries)
+$(LOCAL_BUILT_MODULE): PRIVATE_STATIC_LIBRARIES := $(static_libs)
+$(LOCAL_BUILT_MODULE): PRIVATE_WHOLE_STATIC_LIBRARIES := $(whole_static_libs)
+$(LOCAL_BUILT_MODULE): PRIVATE_SHARED_LIBRARIES := $(shared_libs)
+
+endif
+
+#
+# If this is a shared library module
+#
+ifeq ($(call module-get-class,$(LOCAL_MODULE)),SHARED_LIBRARY)
+$(LOCAL_BUILT_MODULE): PRIVATE_BUILD_SHARED_LIB := $(cmd-build-shared-library)
+$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
+	$(call host-echo-build-step,$(PRIVATE_ABI),SharedLibrary) "$(PRIVATE_NAME)"
+	$(hide) $(PRIVATE_BUILD_SHARED_LIB)
+
+ALL_SHARED_LIBRARIES += $(LOCAL_BUILT_MODULE)
+endif
+
+#
+# If this is an executable module
+#
+ifeq ($(call module-get-class,$(LOCAL_MODULE)),EXECUTABLE)
+$(LOCAL_BUILT_MODULE): PRIVATE_ABI := $(TARGET_ARCH_ABI)
+$(LOCAL_BUILT_MODULE): PRIVATE_BUILD_EXECUTABLE := $(cmd-build-executable)
+$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
+	$(call host-echo-build-step,$(PRIVATE_ABI),Executable) "$(PRIVATE_NAME)"
+	$(hide) $(PRIVATE_BUILD_EXECUTABLE)
+
+ALL_EXECUTABLES += $(LOCAL_BUILT_MODULE)
+endif
+
+#
+# If this is a copyable prebuilt module
+#
+ifeq ($(call module-is-copyable,$(LOCAL_MODULE)),$(true))
+$(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
+	$(call host-echo-build-step,$(PRIVATE_ABI),Prebuilt) "$(PRIVATE_NAME) <= $(call pretty-dir,$(dir $<))"
+	$(hide) $(call host-cp,$<,$@)
+endif
+
+#
+# If this is an installable module
+#
+ifeq ($(call module-is-installable,$(LOCAL_MODULE)),$(true))
+$(LOCAL_INSTALLED): PRIVATE_ABI         := $(TARGET_ARCH_ABI)
+$(LOCAL_INSTALLED): PRIVATE_NAME        := $(notdir $(LOCAL_BUILT_MODULE))
+$(LOCAL_INSTALLED): PRIVATE_SRC         := $(LOCAL_BUILT_MODULE)
+$(LOCAL_INSTALLED): PRIVATE_DST_DIR     := $(NDK_APP_DST_DIR)
+$(LOCAL_INSTALLED): PRIVATE_DST         := $(LOCAL_INSTALLED)
+$(LOCAL_INSTALLED): PRIVATE_STRIP       := $(TARGET_STRIP)
+$(LOCAL_INSTALLED): PRIVATE_STRIP_CMD   := $(call cmd-strip, $(PRIVATE_DST))
+$(LOCAL_INSTALLED): PRIVATE_OBJCOPY     := $(TARGET_OBJCOPY)
+$(LOCAL_INSTALLED): PRIVATE_OBJCOPY_CMD := $(call cmd-add-gnu-debuglink, $(PRIVATE_DST), $(PRIVATE_SRC))
+
+$(LOCAL_INSTALLED): $(LOCAL_BUILT_MODULE) clean-installed-binaries
+	$(call host-echo-build-step,$(PRIVATE_ABI),Install) "$(PRIVATE_NAME) => $(call pretty-dir,$(PRIVATE_DST))"
+	$(hide) $(call host-install,$(PRIVATE_SRC),$(PRIVATE_DST))
+	$(hide) $(PRIVATE_STRIP_CMD)
+
+#$(hide) $(PRIVATE_OBJCOPY_CMD)
+
+$(call generate-file-dir,$(LOCAL_INSTALLED))
+
+endif
diff --git a/build/core/build-executable.mk b/build/core/build-executable.mk
new file mode 100644
index 0000000..dda5592
--- /dev/null
+++ b/build/core/build-executable.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is included from Android.mk files to build a target-specific
+# executable program
+#
+
+LOCAL_BUILD_SCRIPT := BUILD_EXECUTABLE
+LOCAL_MAKEFILE     := $(local-makefile)
+
+$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
+$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+$(call check-LOCAL_MODULE_FILENAME)
+
+# we are building target objects
+my := TARGET_
+
+$(call handle-module-filename,,)
+$(call handle-module-built)
+
+LOCAL_MODULE_CLASS := EXECUTABLE
+include $(BUILD_SYSTEM)/build-module.mk
diff --git a/build/core/build-local.mk b/build/core/build-local.mk
new file mode 100644
index 0000000..32423f4
--- /dev/null
+++ b/build/core/build-local.mk
@@ -0,0 +1,225 @@
+# Copyright (C) 2010 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.
+#
+
+# This file is designed to be called from the 'ndk-build' script
+# or similar wrapper tool.
+#
+
+# Detect the NDK installation path by processing this Makefile's location.
+# This assumes we are located under $NDK_ROOT/build/core/main.mk
+#
+
+# Don't output to stdout if we're being invoked to dump a variable
+DUMP_VAR := $(patsubst DUMP_%,%,$(filter DUMP_%,$(MAKECMDGOALS)))
+ifneq (,$(DUMP_VAR))
+    NDK_NO_INFO := 1
+    NDK_NO_WARNINGS := 1
+endif
+
+NDK_ROOT := $(dir $(lastword $(MAKEFILE_LIST)))
+NDK_ROOT := $(subst \,/,$(NDK_ROOT))
+NDK_ROOT := $(strip $(NDK_ROOT:%build/core/=%))
+NDK_ROOT := $(NDK_ROOT:%/=%)
+ifeq ($(NDK_ROOT),)
+    # for the case when we're invoked from the NDK install path
+    NDK_ROOT := .
+endif
+ifeq ($(NDK_LOG),1)
+    $(info Android NDK: NDK installation path auto-detected: '$(NDK_ROOT)')
+endif
+ifneq ($(words $(NDK_ROOT)),1)
+    $(info Android NDK: Your NDK installation path contains spaces.)
+    $(info Android NDK: Please re-install to a different location to fix the issue !)
+    $(error Aborting.)
+endif
+
+include $(NDK_ROOT)/build/core/init.mk
+
+# ====================================================================
+#
+# If NDK_PROJECT_PATH is not defined, find the application's project
+# path by looking at the manifest file in the current directory or
+# any of its parents. If none is found, try again with 'jni/Android.mk'
+#
+# Note that we first look at the current directory to avoid using
+# absolute NDK_PROJECT_PATH values. This reduces the length of all
+# source, object and binary paths that are passed to build commands.
+#
+# It turns out that some people use ndk-build to generate static
+# libraries without a full Android project tree.
+#
+# If NDK_PROJECT_PATH=null, ndk-build make no attempt to look for it, but does
+# need the following variables depending on NDK_PROJECT_PATH to be explicitly
+# specified (from the default, if any):
+#
+#   NDK_OUT
+#   NDK_LIBS_OUT
+#   APP_BUILD_SCRIPT
+#   NDK_DEBUG (optional, default to 0)
+#   Other APP_* used to be in Application.mk
+#
+# This behavior may be useful in an integrated build system.
+#
+# ====================================================================
+
+find-project-dir = $(strip $(call find-project-dir-inner,$(abspath $1),$2))
+
+find-project-dir-inner = \
+    $(eval __found_project_path := )\
+    $(eval __find_project_path := $1)\
+    $(eval __find_project_file := $2)\
+    $(call find-project-dir-inner-2)\
+    $(__found_project_path)
+
+find-project-dir-inner-2 = \
+    $(call ndk_log,Looking for $(__find_project_file) in $(__find_project_path))\
+    $(eval __find_project_manifest := $(strip $(wildcard $(__find_project_path)/$(__find_project_file))))\
+    $(if $(__find_project_manifest),\
+        $(call ndk_log,    Found it !)\
+        $(eval __found_project_path := $(__find_project_path))\
+        ,\
+        $(eval __find_project_parent := $(call parent-dir,$(__find_project_path)))\
+        $(if $(__find_project_parent),\
+            $(eval __find_project_path := $(__find_project_parent))\
+            $(call find-project-dir-inner-2)\
+        )\
+    )
+
+NDK_PROJECT_PATH := $(strip $(NDK_PROJECT_PATH))
+APP_PROJECT_PATH := $(strip $(APP_PROJECT_PATH))
+
+ifneq (,$(APP_PROJECT_PATH))
+    ifeq (,$(NDK_PROJECT_PATH))
+        # If NDK_PROJECT_PATH isn't set and APP_PROJECT_PATH is present, use APP_PROJECT_PATH
+        $(call ndk_log,Use APP_PROJECT_PATH for NDK_PROJECT_PATH: $(APP_PROJECT_PATH))
+        NDK_PROJECT_PATH := $(APP_PROJECT_PATH)
+    else
+        # If both NDK_PROJECT_PATH and APP_PROJECT_PATH are present, check consistency
+        ifneq ($(NDK_PROJECT_PATH),$(APP_PROJECT_PATH))
+            $(call __ndk_info,WARNING: NDK_PROJECT_PATH and APP_PROJECT_PATH are both set but not equal literally)
+            $(call __ndk_info,  NDK_PROJECT_PATH = $(NDK_PROJECT_PATH))
+            $(call __ndk_info,  APP_PROJECT_PATH = $(APP_PROJECT_PATH))
+        endif
+    endif
+endif
+
+ifeq (null,$(NDK_PROJECT_PATH))
+
+$(call ndk_log,Make no attempt to look for NDK_PROJECT_PATH.)
+
+else
+
+# To keep paths as short as possible during the build, we first look if the
+# current directory is the top of our project path. If this is the case, we
+# will define NDK_PROJECT_PATH to simply '.'
+#
+# Otherwise, we will use find-project-dir which will first get the absolute
+# path of the current directory the climb back the hierarchy until we find
+# something. The result will always be a much longer definition for
+# NDK_PROJECT_PATH
+#
+ifndef NDK_PROJECT_PATH
+    ifneq (,$(strip $(wildcard AndroidManifest.xml)))
+        NDK_PROJECT_PATH := .
+    else
+        ifneq (,$(strip $(wildcard jni/Android.mk)))
+            NDK_PROJECT_PATH := .
+        endif
+    endif
+endif
+ifndef NDK_PROJECT_PATH
+    NDK_PROJECT_PATH := $(call find-project-dir,.,jni/Android.mk)
+endif
+ifndef NDK_PROJECT_PATH
+    NDK_PROJECT_PATH := $(call find-project-dir,.,AndroidManifest.xml)
+endif
+ifndef NDK_PROJECT_PATH
+    $(call __ndk_info,Could not find application project directory !)
+    $(call __ndk_info,Please define the NDK_PROJECT_PATH variable to point to it.)
+    $(call __ndk_error,Aborting)
+endif
+
+# Check that there are no spaces in the project path, or bad things will happen
+ifneq ($(words $(NDK_PROJECT_PATH)),1)
+    $(call __ndk_info,Your Android application project path contains spaces: '$(NDK_PROJECT_PATH)')
+    $(call __ndk_info,The Android NDK build cannot work here. Please move your project to a different location.)
+    $(call __ndk_error,Aborting.)
+endif
+
+$(call ndk_log,Found project path: $(NDK_PROJECT_PATH))
+
+NDK_APPLICATION_MK := $(strip $(wildcard $(NDK_PROJECT_PATH)/jni/Application.mk))
+
+endif # NDK_PROJECT_PATH == null
+
+ifndef NDK_APPLICATION_MK
+    NDK_APPLICATION_MK := $(NDK_ROOT)/build/core/default-application.mk
+endif
+
+
+# Place all generated intermediate files here
+NDK_APP_OUT := $(strip $(NDK_OUT))
+ifndef NDK_APP_OUT
+  ifeq (null,$(NDK_PROJECT_PATH))
+    $(call __ndk_info,NDK_PROJECT_PATH==null.  Please explicitly set NDK_OUT to directory for all generated intermediate files.)
+    $(call __ndk_error,Aborting.)
+  endif
+  NDK_APP_OUT := $(NDK_PROJECT_PATH)/obj
+endif
+$(call ndk_log,Ouput path for intermediate files: $(NDK_APP_OUT))
+
+# Place all generated library files here.  This is rarely changed since aapt expects the default libs/
+NDK_APP_LIBS_OUT := $(strip $(NDK_LIBS_OUT))
+ifndef NDK_APP_LIBS_OUT
+  ifeq (null,$(NDK_PROJECT_PATH))
+    $(call __ndk_info,NDK_PROJECT_PATH==null.  Please explicitly set NDK_LIBS_OUT to directory for generated library files.)
+    $(call __ndk_error,Aborting.)
+  endif
+  NDK_APP_LIBS_OUT := $(NDK_PROJECT_PATH)/libs
+endif
+$(call ndk_log,Ouput path for generated library files: $(NDK_APP_LIBS_OUT))
+
+# Fake an application named 'local'
+_app            := local
+_application_mk := $(NDK_APPLICATION_MK)
+NDK_APPS        := $(_app)
+
+include $(BUILD_SYSTEM)/add-application.mk
+
+# If a goal is DUMP_xxx then we dump a variable xxx instead
+# of building anything
+#
+MAKECMDGOALS := $(filter-out DUMP_$(DUMP_VAR),$(MAKECMDGOALS))
+
+include $(BUILD_SYSTEM)/setup-imports.mk
+
+ifneq (,$(DUMP_VAR))
+
+# We only support a single DUMP_XXX goal at a time for now.
+ifneq ($(words $(DUMP_VAR)),1)
+    $(call __ndk_error,!!TOO-MANY-DUMP-VARIABLES!!)
+endif
+
+$(foreach _app,$(NDK_APPS),\
+  $(eval include $(BUILD_SYSTEM)/setup-app.mk)\
+)
+
+.PHONY : DUMP_$(DUMP_VAR)
+DUMP_$(DUMP_VAR):
+	@echo $($(DUMP_VAR))
+else
+    # Build it
+    include $(BUILD_SYSTEM)/build-all.mk
+endif
diff --git a/build/core/build-module.mk b/build/core/build-module.mk
new file mode 100644
index 0000000..a7b27a3
--- /dev/null
+++ b/build/core/build-module.mk
@@ -0,0 +1,42 @@
+# Copyright (C) 2010 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.
+#
+
+$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
+$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+
+# This file is used to record the LOCAL_XXX definitions of a given
+# module. It is included by BUILD_STATIC_LIBRARY, BUILD_SHARED_LIBRARY
+# and others.
+#
+LOCAL_MODULE_CLASS := $(strip $(LOCAL_MODULE_CLASS))
+ifndef LOCAL_MODULE_CLASS
+$(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_CLASS definition is missing !)
+$(call __ndk_error,Aborting)
+endif
+
+$(if $(call module-class-check,$(LOCAL_MODULE_CLASS)),,\
+$(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): Unknown LOCAL_MODULE_CLASS value: $(LOCAL_MODULE_CLASS))\
+$(call __ndk_error,Aborting)\
+)
+
+$(call module-add,$(LOCAL_MODULE))
+
+# Eval sucks. It's not possible to preserve even properly escaped # characters
+# as far as I can tell, and we need that for -Werror=#warnings. Manually stash
+# all the cflags variations so we can preserve these.
+__ndk_modules.$(LOCAL_MODULE).CFLAGS := $(LOCAL_CFLAGS)
+__ndk_modules.$(LOCAL_MODULE).CONLYFLAGS := $(LOCAL_CONLYFLAGS)
+__ndk_modules.$(LOCAL_MODULE).CPPFLAGS := $(LOCAL_CPPFLAGS)
+__ndk_modules.$(LOCAL_MODULE).CXXFLAGS := $(LOCAL_CXXFLAGS)
diff --git a/build/core/build-shared-library.mk b/build/core/build-shared-library.mk
new file mode 100644
index 0000000..f2e98f8
--- /dev/null
+++ b/build/core/build-shared-library.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is included from Android.mk files to build a target-specific
+# shared library
+#
+
+LOCAL_BUILD_SCRIPT := BUILD_SHARED_LIBRARY
+LOCAL_MAKEFILE     := $(local-makefile)
+
+$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
+$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+$(call check-LOCAL_MODULE_FILENAME)
+
+# we are building target objects
+my := TARGET_
+
+$(call handle-module-filename,lib,$(TARGET_SONAME_EXTENSION))
+$(call handle-module-built)
+
+LOCAL_MODULE_CLASS := SHARED_LIBRARY
+include $(BUILD_SYSTEM)/build-module.mk
diff --git a/build/core/build-static-library.mk b/build/core/build-static-library.mk
new file mode 100644
index 0000000..be30e74
--- /dev/null
+++ b/build/core/build-static-library.mk
@@ -0,0 +1,34 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is included from Android.mk files to build a target-specific
+# static library
+#
+
+LOCAL_BUILD_SCRIPT := BUILD_STATIC_LIBRARY
+LOCAL_MAKEFILE     := $(local-makefile)
+
+$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
+$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+
+# we are building target objects
+my := TARGET_
+
+$(call handle-module-filename,lib,$(TARGET_LIB_EXTENSION))
+$(call handle-module-built)
+
+LOCAL_MODULE_CLASS := STATIC_LIBRARY
+include $(BUILD_SYSTEM)/build-module.mk
+
diff --git a/build/core/check-cygwin-make.mk b/build/core/check-cygwin-make.mk
new file mode 100644
index 0000000..27bc227
--- /dev/null
+++ b/build/core/check-cygwin-make.mk
@@ -0,0 +1,43 @@
+# Copyright (C) 2010 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.
+#
+
+# Check that we have a Cygwin-compatible make.
+#
+# For some reason, a lot of application developers on Windows
+# have another GNU Make installed in their path, that fails
+# miserably with our build scripts. If we can detect this use
+# case, early, we will be able to dump a human-readable error
+# message with some help to fix the issue.
+#
+
+.PHONY: all
+all:
+
+# Get the cygwin-specific path to the make executable
+# (e.g. /cygdrive/c/cygwin/usr/bin/make), then strip the
+# .exe suffix, if any.
+#
+CYGWIN_MAKE := $(shell cygpath --unix --absolute $(firstword $(MAKE)))
+CYGWIN_MAKE := $(CYGWIN_MAKE:%.exe=%)
+
+# Now try to find it on the file system, a non-cygwin compatible
+# GNU Make, even if launched from a Cygwin shell, will not
+#
+SELF_MAKE := $(strip $(wildcard $(CYGWIN_MAKE).exe))
+ifeq ($(SELF_MAKE),)
+    $(error Android NDK: $(firstword $(MAKE)) is not cygwin-compatible)
+endif
+
+# that's all
diff --git a/build/core/clear-vars.mk b/build/core/clear-vars.mk
new file mode 100644
index 0000000..83c6e0e
--- /dev/null
+++ b/build/core/clear-vars.mk
@@ -0,0 +1,23 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is included repeatedly from Android.mk files in order to clean
+# the module-specific variables from the environment,
+
+# Note: As a special exception, we don't want to clear LOCAL_PATH
+$(call clear-vars, $(filter-out LOCAL_PATH,$(modules-LOCALS:%=LOCAL_%)))
+
+# strip LOCAL_PATH
+LOCAL_PATH := $(strip $(LOCAL_PATH))
diff --git a/build/core/default-application.mk b/build/core/default-application.mk
new file mode 100644
index 0000000..81147b0
--- /dev/null
+++ b/build/core/default-application.mk
@@ -0,0 +1,28 @@
+# Copyright (C) 2010 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.
+#
+
+# This is the default Application.mk that is being used for applications
+# that don't provide $PROJECT_PATH/jni/Application.mk
+#
+APP_PROJECT_PATH := $(NDK_PROJECT_PATH)
+
+# We expect the build script to be located here
+ifndef APP_BUILD_SCRIPT
+  ifeq (null,$(NDK_PROJECT_PATH))
+    $(call __ndk_info,NDK_PROJECT_PATH==null.  Please explicitly set APP_BUILD_SCRIPT.)
+    $(call __ndk_error,Aborting.)
+  endif
+  APP_BUILD_SCRIPT := $(APP_PROJECT_PATH)/jni/Android.mk
+endif
\ No newline at end of file
diff --git a/build/core/default-build-commands.mk b/build/core/default-build-commands.mk
new file mode 100644
index 0000000..e501f62
--- /dev/null
+++ b/build/core/default-build-commands.mk
@@ -0,0 +1,179 @@
+# The following definitions are the defaults used by all toolchains.
+# This is included in setup-toolchain.mk just before the inclusion
+# of the toolchain's specific setup.mk file which can then override
+# these definitions.
+#
+
+# These flags are used to ensure that a binary doesn't reference undefined
+# flags.
+TARGET_NO_UNDEFINED_LDFLAGS := -Wl,--no-undefined
+
+
+# Return the list of object, static libraries and shared libraries as they
+# must appear on the final static linker command (order is important).
+#
+# This can be over-ridden by a specific toolchain. Note that by default
+# we always put libgcc _after_ all static libraries and _before_ shared
+# libraries. This ensures that any libgcc function used by the final
+# executable will be copied into it. Otherwise, it could contain
+# symbol references to the same symbols as exported by shared libraries
+# and this causes binary compatibility problems when they come from
+# system libraries (e.g. libc.so and others).
+#
+# IMPORTANT: The result must use the host path convention.
+#
+# $1: object files
+# $2: static libraries
+# $3: whole static libraries
+# $4: shared libraries
+#
+TARGET-get-linker-objects-and-libraries = \
+    $(call host-path, $1) \
+    $(call link-whole-archives,$3) \
+    $(call host-path, $2) \
+    $(PRIVATE_LIBGCC) \
+    $(PRIVATE_LIBATOMIC) \
+    $(call host-path, $4) \
+
+
+# These flags are used to enforce the NX (no execute) security feature in the
+# generated machine code. This adds a special section to the generated shared
+# libraries that instruct the Linux kernel to disable code execution from
+# the stack and the heap.
+TARGET_NO_EXECUTE_CFLAGS  := -Wa,--noexecstack
+TARGET_NO_EXECUTE_LDFLAGS := -Wl,-z,noexecstack
+
+# These flags disable the above security feature
+TARGET_DISABLE_NO_EXECUTE_CFLAGS  := -Wa,--execstack
+TARGET_DISABLE_NO_EXECUTE_LDFLAGS := -Wl,-z,execstack
+
+# These flags are used to mark certain regions of the resulting
+# executable or shared library as being read-only after the dynamic
+# linker has run. This makes GOT overwrite security attacks harder to
+# exploit.
+TARGET_RELRO_LDFLAGS := -Wl,-z,relro -Wl,-z,now
+
+# These flags disable the above security feature
+TARGET_DISABLE_RELRO_LDFLAGS := -Wl,-z,norelro -Wl,-z,lazy
+
+# This flag are used to provide compiler protection against format
+# string vulnerabilities.
+TARGET_FORMAT_STRING_CFLAGS := -Wformat -Werror=format-security
+
+# This flag disables the above security checks
+TARGET_DISABLE_FORMAT_STRING_CFLAGS := -Wno-error=format-security
+
+# NOTE: Ensure that TARGET_LIBGCC is placed after all private objects
+#       and static libraries, but before any other library in the link
+#       command line when generating shared libraries and executables.
+#
+#       This ensures that all libgcc.a functions required by the target
+#       will be included into it, instead of relying on what's available
+#       on other libraries like libc.so, which may change between system
+#       releases due to toolchain or library changes.
+#
+define cmd-build-shared-library
+$(PRIVATE_CXX) \
+    -Wl,-soname,$(notdir $(LOCAL_BUILT_MODULE)) \
+    -shared \
+    --sysroot=$(call host-path,$(PRIVATE_SYSROOT_LINK)) \
+    $(PRIVATE_LINKER_OBJECTS_AND_LIBRARIES) \
+    $(PRIVATE_LDFLAGS) \
+    $(PRIVATE_LDLIBS) \
+    -o $(call host-path,$(LOCAL_BUILT_MODULE))
+endef
+
+# The following -rpath-link= are needed for ld.bfd (default for MIPS) when
+# linking executables to supress warning about missing symbol from libraries not
+# directly needed. ld.gold (default for ARM and X86) doesn't emulate this buggy
+# behavior, and ignores -rpath-link completely.
+define cmd-build-executable
+$(PRIVATE_CXX) \
+    -Wl,--gc-sections \
+    -Wl,-z,nocopyreloc \
+    --sysroot=$(call host-path,$(PRIVATE_SYSROOT_LINK)) \
+    -Wl,-rpath-link=$(call host-path,$(PRIVATE_SYSROOT_LINK)/usr/lib) \
+    -Wl,-rpath-link=$(call host-path,$(TARGET_OUT)) \
+    $(PRIVATE_LINKER_OBJECTS_AND_LIBRARIES) \
+    $(PRIVATE_LDFLAGS) \
+    $(PRIVATE_LDLIBS) \
+    -o $(call host-path,$(LOCAL_BUILT_MODULE))
+endef
+
+define cmd-build-static-library
+$(PRIVATE_AR) $(call host-path,$(LOCAL_BUILT_MODULE)) $(PRIVATE_AR_OBJECTS)
+endef
+
+# The strip command is only used for shared libraries and executables.
+# It is thus safe to use --strip-unneeded, which is only dangerous
+# when applied to static libraries or object files.
+cmd-strip = $(PRIVATE_STRIP) --strip-unneeded $(call host-path,$1)
+
+# The command objcopy --add-gnu-debuglink= will be needed for Valgrind
+cmd-add-gnu-debuglink = $(PRIVATE_OBJCOPY) --add-gnu-debuglink=$(strip $(call host-path,$2)) $(call host-path,$1)
+
+TARGET_LIBGCC = -lgcc -Wl,--exclude-libs,libgcc.a
+TARGET_LIBATOMIC = -latomic -Wl,--exclude-libs,libatomic.a
+TARGET_LDLIBS := -lc -lm
+
+#
+# IMPORTANT: The following definitions must use lazy assignment because
+# the value of TOOLCHAIN_PREFIX or TARGET_CFLAGS can be changed later by
+# the toolchain's setup.mk script.
+#
+
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,llvm)
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+ifneq ($(findstring ccc-analyzer,$(CC)),)
+    TARGET_CC = $(CC)
+else ifeq ($(NDK_TOOLCHAIN_VERSION),4.9)
+    TARGET_CC = $(TOOLCHAIN_PREFIX)gcc
+else
+    TARGET_CC = $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+endif
+
+TARGET_CFLAGS   =
+TARGET_CONLYFLAGS =
+
+ifneq ($(findstring c++-analyzer,$(CXX)),)
+    TARGET_CXX = $(CXX)
+else ifeq ($(NDK_TOOLCHAIN_VERSION),4.9)
+    TARGET_CXX = $(TOOLCHAIN_PREFIX)g++
+else
+    TARGET_CXX = $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+endif
+
+TARGET_CXXFLAGS = $(TARGET_CFLAGS) -fno-exceptions -fno-rtti
+
+TARGET_RS_CC    = $(RENDERSCRIPT_TOOLCHAIN_PREFIX)llvm-rs-cc
+TARGET_RS_BCC   = $(RENDERSCRIPT_TOOLCHAIN_PREFIX)bcc_compat
+TARGET_RS_FLAGS = -Wall -Werror
+ifeq (,$(findstring 64,$(TARGET_ARCH_ABI)))
+TARGET_RS_FLAGS += -m32
+else
+TARGET_RS_FLAGS += -m64
+endif
+
+TARGET_ASM      = $(HOST_PREBUILT)/yasm
+TARGET_ASMFLAGS =
+
+TARGET_LD       = $(TOOLCHAIN_PREFIX)ld
+TARGET_LDFLAGS :=
+
+# Use *-gcc-ar instead of *-ar for better LTO support when using GCC.
+ifeq (4.9,$(NDK_TOOLCHAIN_VERSION))
+    TARGET_AR = $(TOOLCHAIN_PREFIX)gcc-ar
+else
+    TARGET_AR = $(TOOLCHAIN_PREFIX)ar
+endif
+
+TARGET_ARFLAGS := crsD
+
+TARGET_STRIP    = $(TOOLCHAIN_PREFIX)strip
+
+TARGET_OBJCOPY  = $(TOOLCHAIN_PREFIX)objcopy
+
+TARGET_OBJ_EXTENSION := .o
+TARGET_LIB_EXTENSION := .a
+TARGET_SONAME_EXTENSION := .so
diff --git a/build/core/definitions-graph.mk b/build/core/definitions-graph.mk
new file mode 100644
index 0000000..68e7fa9
--- /dev/null
+++ b/build/core/definitions-graph.mk
@@ -0,0 +1,538 @@
+# Copyright (C) 2012 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.
+#
+# Definitions of various graph-related generic functions, used by
+# ndk-build internally.
+#
+
+# Coding style note:
+#
+# All internal variables in this file begin with '_ndk_mod_'
+# All internal functions in this file begin with '-ndk-mod-'
+#
+
+# Set this to true if you want to debug the functions here.
+_ndk_mod_debug := $(if $(NDK_DEBUG_MODULES),true)
+_ndk_topo_debug := $(if $(NDK_DEBUG_TOPO),true)
+
+# Use $(call -ndk-mod-debug,<message>) to print a debug message only
+# if _ndk_mod_debug is set to 'true'. Useful for debugging the functions
+# available here.
+#
+ifeq (true,$(_ndk_mod_debug))
+-ndk-mod-debug = $(info $1)
+else
+-ndk-mod-debug := $(empty)
+endif
+
+ifeq (true,$(_ndk_topo_debug))
+-ndk-topo-debug = $(info $1)
+else
+-ndk-topo-debug = $(empty)
+endif
+
+#######################################################################
+# Filter a list of module with a predicate function
+# $1: list of module names.
+# $2: predicate function, will be called with $(call $2,<name>), if the
+#     result is not empty, <name> will be added to the result.
+# Out: subset of input list, where each item passes the predicate.
+#######################################################################
+-ndk-mod-filter = $(strip \
+    $(foreach _ndk_mod_filter_n,$1,\
+        $(if $(call $2,$(_ndk_mod_filter_n)),$(_ndk_mod_filter_n))\
+    ))
+
+-test-ndk-mod-filter = \
+    $(eval -local-func = $$(call seq,foo,$$1))\
+    $(call test-expect,,$(call -ndk-mod-filter,,-local-func))\
+    $(call test-expect,foo,$(call -ndk-mod-filter,foo,-local-func))\
+    $(call test-expect,foo,$(call -ndk-mod-filter,foo bar,-local-func))\
+    $(call test-expect,foo foo,$(call -ndk-mod-filter,aaa foo bar foo,-local-func))\
+    $(eval -local-func = $$(call sne,foo,$$1))\
+    $(call test-expect,,$(call -ndk-mod-filter,,-local-func))\
+    $(call test-expect,,$(call -ndk-mod-filter,foo,-local-func))\
+    $(call test-expect,bar,$(call -ndk-mod-filter,foo bar,-local-func))\
+    $(call test-expect,aaa bar,$(call -ndk-mod-filter,aaa foo bar,-local-func))
+
+
+#######################################################################
+# Filter out a list of modules with a predicate function
+# $1: list of module names.
+# $2: predicate function, will be called with $(call $2,<name>), if the
+#     result is not empty, <name> will be added to the result.
+# Out: subset of input list, where each item doesn't pass the predicate.
+#######################################################################
+-ndk-mod-filter-out = $(strip \
+    $(foreach _ndk_mod_filter_n,$1,\
+        $(if $(call $2,$(_ndk_mod_filter_n)),,$(_ndk_mod_filter_n))\
+    ))
+
+-test-ndk-mod-filter-out = \
+    $(eval -local-func = $$(call seq,foo,$$1))\
+    $(call test-expect,,$(call -ndk-mod-filter-out,,-local-func))\
+    $(call test-expect,,$(call -ndk-mod-filter-out,foo,-local-func))\
+    $(call test-expect,bar,$(call -ndk-mod-filter-out,foo bar,-local-func))\
+    $(call test-expect,aaa bar,$(call -ndk-mod-filter-out,aaa foo bar foo,-local-func))\
+    $(eval -local-func = $$(call sne,foo,$$1))\
+    $(call test-expect,,$(call -ndk-mod-filter-out,,-local-func))\
+    $(call test-expect,foo,$(call -ndk-mod-filter-out,foo,-local-func))\
+    $(call test-expect,foo,$(call -ndk-mod-filter-out,foo bar,-local-func))\
+    $(call test-expect,foo foo,$(call -ndk-mod-filter-out,aaa foo bar foo,-local-func))
+
+
+#######################################################################
+# Find the first item in a list that checks a valid predicate.
+# $1: list of names.
+# $2: predicate function, will be called with $(call $2,<name>), if the
+#     result is not empty, <name> will be added to the result.
+# Out: subset of input list.
+#######################################################################
+-ndk-mod-find-first = $(firstword $(call -ndk-mod-filter,$1,$2))
+
+-test-ndk-mod-find-first.empty = \
+    $(eval -local-pred = $$(call seq,foo,$$1))\
+    $(call test-expect,,$(call -ndk-mod-find-first,,-local-pred))\
+    $(call test-expect,,$(call -ndk-mod-find-first,bar,-local-pred))
+
+-test-ndk-mod-find-first.simple = \
+    $(eval -local-pred = $$(call seq,foo,$$1))\
+    $(call test-expect,foo,$(call -ndk-mod-find-first,foo,-local-pred))\
+    $(call test-expect,foo,$(call -ndk-mod-find-first,aaa foo bar,-local-pred))\
+    $(call test-expect,foo,$(call -ndk-mod-find-first,aaa foo foo bar,-local-pred))
+
+########################################################################
+# Many tree walking operations require setting a 'visited' flag on
+# specific graph nodes. The following helper functions help implement
+# this while hiding details to the callers.
+#
+# Technical note:
+#  _ndk_mod_tree_visited.<name> will be 'true' if the node was visited,
+#  or empty otherwise.
+#
+#  _ndk_mod_tree_visitors lists all visited nodes, used to clean all
+#  _ndk_mod_tree_visited.<name> variables in -ndk-mod-tree-setup-visit.
+#
+#######################################################################
+
+# Call this before tree traversal.
+-ndk-mod-tree-setup-visit = \
+    $(foreach _ndk_mod_tree_visitor,$(_ndk_mod_tree_visitors),\
+        $(eval _ndk_mod_tree_visited.$$(_ndk_mod_tree_visitor) :=))\
+    $(eval _ndk_mod_tree_visitors :=)
+
+# Returns non-empty if a node was visited.
+-ndk-mod-tree-is-visited = \
+    $(_ndk_mod_tree_visited.$1)
+
+# Set the visited state of a node to 'true'
+-ndk-mod-tree-set-visited = \
+    $(eval _ndk_mod_tree_visited.$1 := true)\
+    $(eval _ndk_mod_tree_visitors += $1)
+
+########################################################################
+# Many graph walking operations require a work queue and computing
+# dependencies / children nodes. Here are a few helper functions that
+# can be used to make their code clearer. This uses a few global
+# variables that should be defined as follows during the operation:
+#
+#  _ndk_mod_module     current graph node name.
+#  _ndk_mod_wq         current node work queue.
+#  _ndk_mod_list       current result (list of nodes).
+#  _ndk_mod_depends    current graph node's children.
+#                      you must call -ndk-mod-get-depends to set this.
+#
+#######################################################################
+
+# Pop first item from work-queue into _ndk_mod_module.
+-ndk-mod-pop-first = \
+    $(eval _ndk_mod_module := $$(call first,$$(_ndk_mod_wq)))\
+    $(eval _ndk_mod_wq     := $$(call rest,$$(_ndk_mod_wq)))
+
+-test-ndk-mod-pop-first = \
+    $(eval _ndk_mod_wq := A B C)\
+    $(call -ndk-mod-pop-first)\
+    $(call test-expect,A,$(_ndk_mod_module))\
+    $(call test-expect,B C,$(_ndk_mod_wq))\
+
+
+# Push list of items at the back of the work-queue.
+-ndk-mod-push-back = \
+    $(eval _ndk_mod_wq := $(strip $(_ndk_mod_wq) $1))
+
+-test-ndk-mod-push-back = \
+  $(eval _ndk_mod_wq := A B C)\
+  $(call -ndk-mod-push-back, D    E)\
+  $(call test-expect,A B C D E,$(_ndk_mod_wq))
+
+# Set _ndk_mod_depends to the direct dependencies of _ndk_mod_module
+-ndk-mod-get-depends = \
+    $(eval _ndk_mod_depends := $$(call $$(_ndk_mod_deps_func),$$(_ndk_mod_module)))
+
+# Set _ndk_mod_depends to the direct dependencies of _ndk_mod_module that
+# are not already in _ndk_mod_list.
+-ndk-mod-get-new-depends = \
+    $(call -ndk-mod-get-depends)\
+    $(eval _ndk_mod_depends := $$(filter-out $$(_ndk_mod_list),$$(_ndk_mod_depends)))
+
+##########################################################################
+# Compute the transitive closure
+# $1: list of modules.
+# $2: dependency function, $(call $2,<module>) should return all the
+#     module that <module> depends on.
+# Out: transitive closure of all modules from those in $1. Always includes
+#      the modules in $1. Order is random.
+#
+# Implementation note:
+#   we use the -ndk-mod-tree-xxx functions to flag 'visited' nodes
+#   in the graph. A node is visited once it has been put into the work
+#   queue. For each item in the work queue, get the dependencies and
+#   append all those that were not visited yet.
+#######################################################################
+-ndk-mod-get-closure = $(strip \
+    $(eval _ndk_mod_wq :=)\
+    $(eval _ndk_mod_list :=)\
+    $(eval _ndk_mod_deps_func := $2)\
+    $(call -ndk-mod-tree-setup-visit)\
+    $(foreach _ndk_mod_module,$1,\
+        $(call -ndk-mod-closure-visit,$(_ndk_mod_module))\
+    )\
+    $(call -ndk-mod-closure-recursive)\
+    $(eval _ndk_mod_deps :=)\
+    $(_ndk_mod_list)\
+    )
+
+# Used internally to visit a new node during -ndk-mod-get-closure.
+# This appends the node to the work queue, and set its 'visit' flag.
+-ndk-mod-closure-visit = \
+    $(call -ndk-mod-push-back,$1)\
+    $(call -ndk-mod-tree-set-visited,$1)
+
+-ndk-mod-closure-recursive = \
+    $(call -ndk-mod-pop-first)\
+    $(eval _ndk_mod_list += $$(_ndk_mod_module))\
+    $(call -ndk-mod-get-depends)\
+    $(foreach _ndk_mod_dep,$(_ndk_mod_depends),\
+        $(if $(call -ndk-mod-tree-is-visited,$(_ndk_mod_dep)),,\
+        $(call -ndk-mod-closure-visit,$(_ndk_mod_dep))\
+        )\
+    )\
+    $(if $(_ndk_mod_wq),$(call -ndk-mod-closure-recursive))
+
+-test-ndk-mod-get-closure.empty = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(call test-expect,,$(call -ndk-mod-get-closure,,-local-deps))
+
+-test-ndk-mod-get-closure.single = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends :=)\
+    $(call test-expect,A,$(call -ndk-mod-get-closure,A,-local-deps))
+
+-test-ndk-mod-get-closure.double = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends := B)\
+    $(eval B_depends :=)\
+    $(call test-expect,A B,$(call -ndk-mod-get-closure,A,-local-deps))
+
+-test-ndk-mod-get-closure.circular-deps = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends := B)\
+    $(eval B_depends := C)\
+    $(eval C_depends := A)\
+    $(call test-expect,A B C,$(call -ndk-mod-get-closure,A,-local-deps))
+
+-test-ndk-mod-get-closure.ABCDE = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends := B C)\
+    $(eval B_depends := D)\
+    $(eval C_depends := D E)\
+    $(eval D_depends :=)\
+    $(eval E_depends :=)\
+    $(call test-expect,A B C D E,$(call -ndk-mod-get-closure,A,-local-deps))
+
+
+#########################################################################
+# For topological sort, we need to count the number of incoming edges
+# in each graph node. The following helper functions implement this and
+# hide implementation details.
+#
+# Count the number of incoming edges for each node during topological
+# sort with a string of xxxxs. I.e.:
+#  0 edge  -> ''
+#  1 edge  -> 'x'
+#  2 edges -> 'xx'
+#  3 edges -> 'xxx'
+#  etc.
+#########################################################################
+
+# zero the incoming edge counter for module $1
+-ndk-mod-topo-zero-incoming = \
+    $(eval _ndk_mod_topo_incoming.$1 :=)
+
+# increment the incoming edge counter for module $1
+-ndk-mod-topo-increment-incoming = \
+    $(eval _ndk_mod_topo_incoming.$1 := $$(_ndk_mod_topo_incoming.$1)x)
+
+# decrement the incoming edge counter for module $1
+-ndk-mod-topo-decrement-incoming = \
+    $(eval _ndk_mod_topo_incoming.$1 := $$(_ndk_mod_topo_incoming.$1:%x=%))
+
+# return non-empty if the module $1's incoming edge counter is > 0
+-ndk-mod-topo-has-incoming = $(_ndk_mod_topo_incoming.$1)
+
+# Find first node in a list that has zero incoming edges.
+# $1: list of nodes
+# Out: first node that has zero incoming edges, or empty.
+-ndk-mod-topo-find-first-zero-incoming = $(firstword $(call -ndk-mod-filter-out,$1,-ndk-mod-topo-has-incoming))
+
+# Only use for debugging:
+-ndk-mod-topo-dump-count = \
+    $(foreach _ndk_mod_module,$1,\
+        $(info .. $(_ndk_mod_module) incoming='$(_ndk_mod_topo_incoming.$(_ndk_mod_module))'))
+
+
+
+#########################################################################
+# Return the topologically ordered closure of all nodes from a top-level
+# one. This means that a node A, in the result, will always appear after
+# node B if A depends on B. Assumes that the graph is a DAG (if there are
+# circular dependencies, this property cannot be guaranteed, but at least
+# the function should not loop infinitely).
+#
+# $1: top-level node name.
+# $2: dependency function, i.e. $(call $2,<name>) returns the children
+#     nodes for <name>.
+# Return: list of nodes, include $1, which will always be the first.
+#########################################################################
+-ndk-mod-get-topo-list = $(strip \
+    $(eval _ndk_mod_top_module := $1)\
+    $(eval _ndk_mod_deps_func := $2)\
+    $(eval _ndk_mod_nodes := $(call -ndk-mod-get-closure,$1,$2))\
+    $(call -ndk-mod-topo-count,$(_ndk_mod_nodes))\
+    $(eval _ndk_mod_list :=)\
+    $(eval _ndk_mod_wq := $(call -ndk-mod-topo-find-first-zero-incoming,$(_ndk_mod_nodes)))\
+    $(call -ndk-mod-topo-sort)\
+    $(_ndk_mod_list) $(_ndk_mod_nodes)\
+    )
+
+# Given a closure list of nodes, count their incoming edges.
+# $1: list of nodes, must be a graph closure.
+-ndk-mod-topo-count = \
+    $(foreach _ndk_mod_module,$1,\
+        $(call -ndk-mod-topo-zero-incoming,$(_ndk_mod_module)))\
+    $(foreach _ndk_mod_module,$1,\
+        $(call -ndk-mod-get-depends)\
+        $(foreach _ndk_mod_dep,$(_ndk_mod_depends),\
+        $(call -ndk-mod-topo-increment-incoming,$(_ndk_mod_dep))\
+        )\
+    )
+
+-ndk-mod-topo-sort = \
+    $(call -ndk-topo-debug,-ndk-mod-topo-sort: wq='$(_ndk_mod_wq)' list='$(_ndk_mod_list)')\
+    $(call -ndk-mod-pop-first)\
+    $(if $(_ndk_mod_module),\
+        $(eval _ndk_mod_list += $(_ndk_mod_module))\
+        $(eval _ndk_mod_nodes := $(filter-out $(_ndk_mod_module),$(_ndk_mod_nodes)))\
+        $(call -ndk-mod-topo-decrement-incoming,$(_ndk_mod_module))\
+        $(call -ndk-mod-get-depends)\
+        $(call -ndk-topo-debug,-ndk-mod-topo-sort:   deps='$(_ndk_mod_depends)')\
+        $(foreach _ndk_mod_dep,$(_ndk_mod_depends),\
+            $(call -ndk-mod-topo-decrement-incoming,$(_ndk_mod_dep))\
+            $(if $(call -ndk-mod-topo-has-incoming,$(_ndk_mod_dep)),,\
+                $(call -ndk-mod-push-back,$(_ndk_mod_dep))\
+            )\
+        )\
+        $(call -ndk-mod-topo-sort)\
+    )
+
+
+-test-ndk-mod-get-topo-list.empty = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(call test-expect,,$(call -ndk-mod-get-topo-list,,-local-deps))
+
+-test-ndk-mod-get-topo-list.single = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends :=)\
+    $(call test-expect,A,$(call -ndk-mod-get-topo-list,A,-local-deps))
+
+-test-ndk-mod-get-topo-list.no-infinite-loop = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends := B)\
+    $(eval B_depends := C)\
+    $(eval C_depends := A)\
+    $(call test-expect,A B C,$(call -ndk-mod-get-topo-list,A,-local-deps))
+
+-test-ndk-mod-get-topo-list.ABC = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends := B C)\
+    $(eval B_depends :=)\
+    $(eval C_depends := B)\
+    $(call test-expect,A C B,$(call -ndk-mod-get-topo-list,A,-local-deps))
+
+-test-ndk-mod-get-topo-list.ABCD = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends := B C)\
+    $(eval B_depends := D)\
+    $(eval C_depends := B)\
+    $(eval D_depends :=)\
+    $(call test-expect,A C B D,$(call -ndk-mod-get-topo-list,A,-local-deps))
+
+-test-ndk-mod-get-topo-list.ABC.circular = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends := B)\
+    $(eval B_depends := C)\
+    $(eval C_depends := B)\
+    $(call test-expect,A B C,$(call -ndk-mod-get-topo-list,A,-local-deps))
+
+#########################################################################
+# Return the topologically ordered closure of all dependencies from a
+# top-level node.
+#
+# $1: top-level node name.
+# $2: dependency function, i.e. $(call $2,<name>) returns the children
+#     nodes for <name>.
+# Return: list of nodes, include $1, which will never be included.
+#########################################################################
+-ndk-mod-get-topological-depends = $(call rest,$(call -ndk-mod-get-topo-list,$1,$2))
+
+-test-ndk-mod-get-topological-depends.simple = \
+    $(eval -local-get-deps = $$($$1_depends))\
+    $(eval A_depends := B)\
+    $(eval B_depends :=)\
+    $(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\
+    $(call test-expect,B,$(topo_deps),topo dependencies)
+
+-test-ndk-mod-get-topological-depends.ABC = \
+    $(eval -local-get-deps = $$($$1_depends))\
+    $(eval A_depends := B C)\
+    $(eval B_depends :=)\
+    $(eval C_depends := B)\
+    $(eval bfs_deps := $$(call -ndk-mod-get-bfs-depends,A,-local-get-deps))\
+    $(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\
+    $(call test-expect,B C,$(bfs_deps),dfs dependencies)\
+    $(call test-expect,C B,$(topo_deps),topo dependencies)
+
+-test-ndk-mod-get-topological-depends.circular = \
+    $(eval -local-get-deps = $$($$1_depends))\
+    $(eval A_depends := B)\
+    $(eval B_depends := C)\
+    $(eval C_depends := B)\
+    $(eval bfs_deps := $$(call -ndk-mod-get-bfs-depends,A,-local-get-deps))\
+    $(eval topo_deps := $$(call -ndk-mod-get-topological-depends,A,-local-get-deps))\
+    $(call test-expect,B C,$(bfs_deps),dfs dependencies)\
+    $(call test-expect,B C,$(topo_deps),topo dependencies)
+
+#########################################################################
+# Return breadth-first walk of a graph, starting from an arbitrary
+# node.
+#
+# This performs a breadth-first walk of the graph and will return a
+# list of nodes. Note that $1 will always be the first in the list.
+#
+# $1: root node name.
+# $2: dependency function, i.e. $(call $2,<name>) returns the nodes
+#     that <name> depends on.
+# Result: list of dependent modules, $1 will be part of it.
+#########################################################################
+-ndk-mod-get-bfs-list = $(strip \
+    $(eval _ndk_mod_wq := $(call strip-lib-prefix,$1)) \
+    $(eval _ndk_mod_deps_func := $2)\
+    $(eval _ndk_mod_list :=)\
+    $(call -ndk-mod-tree-setup-visit)\
+    $(call -ndk-mod-tree-set-visited,$(_ndk_mod_wq))\
+    $(call -ndk-mod-bfs-recursive) \
+    $(_ndk_mod_list))
+
+# Recursive function used to perform a depth-first scan.
+# Must initialize _ndk_mod_list, _ndk_mod_field, _ndk_mod_wq
+# before calling this.
+-ndk-mod-bfs-recursive = \
+    $(call -ndk-mod-debug,-ndk-mod-bfs-recursive wq='$(_ndk_mod_wq)' list='$(_ndk_mod_list)' visited='$(_ndk_mod_tree_visitors)')\
+    $(call -ndk-mod-pop-first)\
+    $(eval _ndk_mod_list += $$(_ndk_mod_module))\
+    $(call -ndk-mod-get-depends)\
+    $(call -ndk-mod-debug,.  node='$(_ndk_mod_module)' deps='$(_ndk_mod_depends)')\
+    $(foreach _ndk_mod_child,$(_ndk_mod_depends),\
+        $(if $(call -ndk-mod-tree-is-visited,$(_ndk_mod_child)),,\
+            $(call -ndk-mod-tree-set-visited,$(_ndk_mod_child))\
+            $(call -ndk-mod-push-back,$(_ndk_mod_child))\
+        )\
+    )\
+    $(if $(_ndk_mod_wq),$(call -ndk-mod-bfs-recursive))
+
+-test-ndk-mod-get-bfs-list.empty = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(call test-expect,,$(call -ndk-mod-get-bfs-list,,-local-deps))
+
+-test-ndk-mod-get-bfs-list.A = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends :=)\
+    $(call test-expect,A,$(call -ndk-mod-get-bfs-list,A,-local-deps))
+
+-test-ndk-mod-get-bfs-list.ABCDEF = \
+    $(eval -local-deps = $$($$1_depends))\
+    $(eval A_depends := B C)\
+    $(eval B_depends := D E)\
+    $(eval C_depends := F E)\
+    $(eval D_depends :=)\
+    $(eval E_depends :=)\
+    $(eval F_depends :=)\
+    $(call test-expect,A B C D E F,$(call -ndk-mod-get-bfs-list,A,-local-deps))
+
+#########################################################################
+# Return breadth-first walk of a graph, starting from an arbitrary
+# node.
+#
+# This performs a breadth-first walk of the graph and will return a
+# list of nodes. Note that $1 will _not_ be part of the list.
+#
+# $1: root node name.
+# $2: dependency function, i.e. $(call $2,<name>) returns the nodes
+#     that <name> depends on.
+# Result: list of dependent modules, $1 will not be part of it.
+#########################################################################
+-ndk-mod-get-bfs-depends = $(call rest,$(call -ndk-mod-get-bfs-list,$1,$2))
+
+-test-ndk-mod-get-bfs-depends.simple = \
+    $(eval -local-deps-func = $$($$1_depends))\
+    $(eval A_depends := B)\
+    $(eval B_depends :=)\
+    $(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\
+    $(call test-expect,B,$(deps))
+
+-test-ndk-mod-get-bfs-depends.ABC = \
+    $(eval -local-deps-func = $$($$1_depends))\
+    $(eval A_depends := B C)\
+    $(eval B_depends :=)\
+    $(eval C_depends := B)\
+    $(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\
+    $(call test-expect,B C,$(deps))\
+
+-test-ndk-mod-get-bfs-depends.ABCDE = \
+    $(eval -local-deps-func = $$($$1_depends))\
+    $(eval A_depends := B C)\
+    $(eval B_depends := D)\
+    $(eval C_depends := D E F)\
+    $(eval D_depends :=)\
+    $(eval E_depends :=)\
+    $(eval F_depends :=)\
+    $(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\
+    $(call test-expect,B C D E F,$(deps))\
+
+-test-ndk-mod-get-bfs-depends.loop = \
+    $(eval -local-deps-func = $$($$1_depends))\
+    $(eval A_depends := B)\
+    $(eval B_depends := A)\
+    $(eval deps := $$(call -ndk-mod-get-bfs-depends,A,-local-deps-func))\
+    $(call test-expect,B,$(deps))
diff --git a/build/core/definitions-host.mk b/build/core/definitions-host.mk
new file mode 100644
index 0000000..3501e50
--- /dev/null
+++ b/build/core/definitions-host.mk
@@ -0,0 +1,218 @@
+# Copyright (C) 2009 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.
+#
+
+# These definitions contain a few host-specific functions. I.e. they are
+# typically used to generate shell commands during the build and their
+# implementation will depend on the value of the HOST_OS variable.
+#
+
+# -----------------------------------------------------------------------------
+# Function : host-path
+# Arguments: 1: file path
+# Returns  : file path, as understood by the host file system
+# Usage    : $(call host-path,<path>)
+# Rationale: This function is used to translate Cygwin paths into
+#            Cygwin-specific ones. On other platforms, it will just
+#            return its argument.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),cygwin)
+host-path = $(if $(strip $1),$(call cygwin-to-host-path,$1))
+else
+host-path = $1
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-rm
+# Arguments: 1: list of files
+# Usage    : $(call host-rm,<files>)
+# Rationale: This function expands to the host-specific shell command used
+#            to remove some files.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),windows)
+host-rm = \
+    $(eval __host_rm_files := $(foreach __host_rm_file,$1,$(subst /,\,$(wildcard $(__host_rm_file)))))\
+    $(if $(__host_rm_files),del /f/q $(__host_rm_files) >NUL 2>NUL)
+else
+host-rm = rm -f $1
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-rmdir
+# Arguments: 1: list of files or directories
+# Usage    : $(call host-rm,<files>)
+# Rationale: This function expands to the host-specific shell command used
+#            to remove some files _and_ directories.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),windows)
+host-rmdir = \
+    $(eval __host_rmdir_files := $(foreach __host_rmdir_file,$1,$(subst /,\,$(wildcard $(__host_rmdir_file)))))\
+    $(if $(__host_rmdir_files),del /f/s/q $(__host_rmdir_files) >NUL 2>NUL)
+else
+host-rmdir = rm -rf $1
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-mkdir
+# Arguments: 1: directory path
+# Usage    : $(call host-mkdir,<path>
+# Rationale: This function expands to the host-specific shell command used
+#            to create a path if it doesn't exist.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),windows)
+host-mkdir = md $(subst /,\,"$1") >NUL 2>NUL || rem
+else
+host-mkdir = mkdir -p $1
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-cp
+# Arguments: 1: source file
+#            2: target file
+# Usage    : $(call host-cp,<src-file>,<dst-file>)
+# Rationale: This function expands to the host-specific shell command used
+#            to copy a single file
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),windows)
+host-cp = copy /b/y $(subst /,\,"$1" "$2") > NUL
+else
+host-cp = cp -f $1 $2
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-mv
+# Arguments: 1: source file
+#            2: target file
+# Usage    : $(call host-mv,<src-file>,<dst-file>)
+# Rationale: This function expands to the host-specific shell command used
+#            to move a single file
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),windows)
+host-mv = move /y $(subst /,\,"$1" "$2") > NUL
+else
+host-mv = mv -f $1 $2
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-install
+# Arguments: 1: source file
+#            2: target file
+# Usage    : $(call host-install,<src-file>,<dst-file>)
+# Rationale: This function expands to the host-specific shell command used
+#            to install a file or directory, while preserving its timestamps
+#            (if possible).
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),windows)
+host-install = copy /b/y $(subst /,\,"$1" "$2") > NUL
+else
+host-install = install -p $1 $2
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-echo-build-step
+# Arguments: 1: ABI
+#            2: Step description (e.g. 'Compile C++', or 'StaticLibrary')
+# Usage    : ---->|$(call host-echo-build-step,Compile) ....other text...
+# Rationale: This function expands to the host-specific shell command used
+#            to print the prefix of a given build step / command.
+# -----------------------------------------------------------------------------
+host-echo-build-step = @ $(HOST_ECHO) [$1] $(call left-justify-quoted-15,$2):
+
+# -----------------------------------------------------------------------------
+# Function : host-c-includes
+# Arguments: 1: list of file paths (e.g. "foo bar")
+# Returns  : list of include compiler options (e.g. "-Ifoo -Ibar")
+# Usage    : $(call host-c-includes,<paths>)
+# Rationale: This function is used to translate Cygwin paths into
+#            Cygwin-specific ones. On other platforms, it will just
+#            return its argument.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),cygwin)
+host-c-includes = $(patsubst %,-I%,$(call host-path,$1))
+else
+host-c-includes = $(1:%=-I%)
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-copy-if-differ
+# Arguments: 1: source file
+#            2: destination file
+# Usage    : $(call host-copy-if-differ,<src-file>,<dst-file>)
+# Rationale: This function copy source file to destination file if contents are
+#            different.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),windows)
+host-copy-if-differ = $(HOST_CMP) -s $1 $2 > NUL || copy /b/y $(subst /,\,"$1" "$2") > NUL
+else
+host-copy-if-differ = $(HOST_CMP) -s $1 $2 > /dev/null 2>&1 || cp -f $1 $2
+endif
+
+
+# -----------------------------------------------------------------------------
+# Function : host-path-is-absolute
+# Arguments: 1: file path
+# Usage    : $(call host-path-is-absolute,<path>)
+# Rationale: This function returns a non-empty result if the input path is
+#            absolute on the host filesystem.
+# -----------------------------------------------------------------------------
+
+# On Windows, we need to take care drive prefix in file paths, e.g.:
+#    /foo       -> top-level 'foo' directory on current drive.
+#    //bar/foo  -> top-level 'foo' on network share 'bar'
+#    c:/foo     -> top-level 'foo' directory on C drive.
+#    c:foo      -> 'foo' subdirectory on C drive's current directory.
+#
+# Treat all of them as absolute. Filtering the first two cases is easy
+# by simply looking at the first character. The other ones are more
+# complicated and the simplest way is still to try all alphabet letters
+# directly. Anything else involves very complicated GNU Make parsing
+# voodoo.
+ndk-windows-drive-letters := a b c d e f g h i j k l m n o p q r s t u v w x y z \
+                             A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+
+ndk-windows-drive-patterns := $(foreach _drive,$(ndk-windows-drive-letters),$(_drive):%)
+
+windows-path-is-absolute = $(if $(filter /% $(ndk-windows-drive-patterns),$(subst \,/,$1)),true)
+
+ifeq ($(HOST_OS),windows)
+host-path-is-absolute = $(call windows-path-is-absolute,$1)
+else
+host-path-is-absolute = $(if $(filter /%,$1),true)
+endif
+
+-test-host-path-is-absolute.relative-paths = \
+  $(call test-expect,,$(call host-path-is-absolute,foo))\
+  $(call test-expect,,$(call host-path-is-absolute,foo/bar))\
+  $(call test-expect,,$(call host-path-is-absolute,.))\
+  $(call test-expect,,$(call host-path-is-absolute,..))
+
+-test-host-path-is-absolute.absolute-paths = \
+  $(call test-expect,true,$(call host-path-is-absolute,/))\
+  $(call test-expect,true,$(call host-path-is-absolute,/foo))\
+  $(call test-expect,true,$(call host-path-is-absolute,/foo/bar))\
+  $(call test-expect,true,$(call host-path-is-absolute,//foo))\
+  $(call test-expect,true,$(call host-path-is-absolute,/.))
+
+-test-host-path-is-asbolute.windows-relative-paths = \
+  $(call test-expect,$(call windows-path-is-absolute,foo))\
+  $(call test-expect,$(call windows-path-is-absolute,foo/bar))\
+  $(call test-expect,$(call windows-path-is-absolute,.))\
+  $(call test-expect,$(call windows-path-is-absolute,..))
+
+-test-host-path-is-asbolute.windows-absolute-paths = \
+  $(call test-expect,true,$(call windows-path-is-absolute,c:/))\
+  $(call test-expect,true,$(call windows-path-is-absolute,x:))\
+  $(call test-expect,true,$(call windows-path-is-absolute,K:foo))\
+  $(call test-expect,true,$(call windows-path-is-absolute,C:\Foo\Bar))\
+  $(call test-expect,true,$(call windows-path-is-absolute,\Foo))
diff --git a/build/core/definitions-tests.mk b/build/core/definitions-tests.mk
new file mode 100644
index 0000000..074036b
--- /dev/null
+++ b/build/core/definitions-tests.mk
@@ -0,0 +1,106 @@
+# Copyright (C) 2012 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.
+#
+# Definitions for the Android NDK build system's internal unit tests.
+#
+
+#
+# A function which names begin with -test- (e.g. -test-foo) is assumed
+# to be an internal unit test. It will be run automatically by ndk-build
+# if NDK_UNIT_TESTS is defined in your environment.
+#
+# Each test should call one of the following functions that will
+# register a failure:
+#
+#   $(call test-expect,<expected-value>,<actual-value>)
+#
+#      This will check that <actual-value> is equal to <expected-value>.
+#      If not, this will print an error message and increment the failure
+#      counter.
+#
+#   $(call test-assert,<expected-value>,<actual-value>)
+#
+#      This is similar to test-expect, though it will abort the program
+#      immediately after displaying an error message.
+#
+# Here's an example that checks that the 'filter' function works correctly:
+#
+#   -test-filter = \
+#     $(call test-expect,foo,$(filter bar,foo bar))
+#
+#
+
+-ndk-test-start = \
+  $(eval _test_name := $1)\
+  $(eval _test_list += $1)\
+  $(eval _test_failed :=)\
+  $(info [$1  RUN])
+
+# End current unit test.
+#
+-ndk-test-end = \
+  $(if $(_test_failed),\
+    $(info [$(_test_name) FAIL])$(error Aborting)\
+    $(eval _test_failures += $$(_test_name))\
+  ,\
+    $(info [$(_test_name)   OK])\
+  )
+
+# Define NDK_UNIT_TESTS to 2 to dump each test-expect/assert check.
+#
+ifeq (2,$(NDK_UNIT_TESTS))
+-ndk-test-log = $(info .  $(_test_name): $1)
+else
+-ndk-test-log = $(empty)
+endif
+
+test-expect = \
+  $(call -ndk-test-log,expect '$2' == '$1')\
+  $(if $(call sne,$1,$2),\
+    $(info ERROR <$(_test_name)>:$3)\
+    $(info .  expected value:'$1')\
+    $(info .  actual value:  '$2')\
+    $(eval _test_failed := true)\
+  )
+
+test-assert = \
+  $(call -ndk-test-log,assert '$2' == '$1')\
+  $(if $(call sne,$1,$2),\
+    $(info ASSERT <$(_test_name)>:$3)\
+    $(info .  expected value:'$1')\
+    $(info .  actual value:  '$2')\
+    $(eval _test_failed := true)\
+    $(error Aborting.)\
+  )
+
+# Run all the tests, i.e. all functions that are defined with a -test-
+# prefix will be called now in succession.
+ndk-run-all-tests = \
+  $(info ================= STARTING NDK-BUILD UNIT TESTS =================)\
+  $(eval _test_list :=)\
+  $(eval _test_failures :=)\
+  $(foreach _test,$(filter -test-%,$(.VARIABLES)),\
+    $(call -ndk-test-start,$(_test))\
+    $(call $(_test))\
+    $(call -ndk-test-end)\
+  )\
+  $(eval _test_count := $$(words $$(_test_list)))\
+  $(eval _test_fail_count := $$(words $$(_test_failures)))\
+  $(if $(_test_failures),\
+    $(info @@@@@@@@@@@ FAILED $(_test_fail_count) of $(_test_count) NDK-BUILD UNIT TESTS @@@@@@@)\
+    $(foreach _test_name,$(_test_failures),\
+      $(info .  $(_test_name)))\
+  ,\
+    $(info =================== PASSED $(_test_count) NDK-BUILD UNIT TESTS =================)\
+  )
diff --git a/build/core/definitions-utils.mk b/build/core/definitions-utils.mk
new file mode 100644
index 0000000..555d601
--- /dev/null
+++ b/build/core/definitions-utils.mk
@@ -0,0 +1,272 @@
+# Copyright (C) 2009 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.
+#
+
+# Common utility functions.
+#
+# NOTE: All the functions here should be purely functional, i.e. avoid
+#       using global variables or depend on the file system / environment
+#       variables. This makes testing easier.
+
+# -----------------------------------------------------------------------------
+# Macro    : empty
+# Returns  : an empty macro
+# Usage    : $(empty)
+# -----------------------------------------------------------------------------
+empty :=
+
+# -----------------------------------------------------------------------------
+# Macro    : space
+# Returns  : a single space
+# Usage    : $(space)
+# -----------------------------------------------------------------------------
+space  := $(empty) $(empty)
+
+space4 := $(space)$(space)$(space)$(space)
+
+# -----------------------------------------------------------------------------
+# Macro    : comma
+# Returns  : a single comma
+# Usage    : $(comma)
+# -----------------------------------------------------------------------------
+comma := ,
+
+# -----------------------------------------------------------------------------
+# Macro    : colon
+# Returns  : a single colon
+# Usage    : $(colon)
+# -----------------------------------------------------------------------------
+colon := :
+
+define newline
+
+
+endef
+
+# -----------------------------------------------------------------------------
+# Function : remove-duplicates
+# Arguments: a list
+# Returns  : the list with duplicate items removed, order is preserved.
+# Usage    : $(call remove-duplicates, <LIST>)
+# Note     : This is equivalent to the 'uniq' function provided by GMSL,
+#            however this implementation is non-recursive and *much*
+#            faster. It will also not explode the stack with a lot of
+#            items like 'uniq' does.
+# -----------------------------------------------------------------------------
+remove-duplicates = $(strip \
+  $(eval __uniq_ret :=) \
+  $(foreach __uniq_item,$1,\
+    $(if $(findstring $(__uniq_item),$(__uniq_ret)),,\
+      $(eval __uniq_ret += $(__uniq_item))\
+    )\
+  )\
+  $(__uniq_ret))
+
+-test-remove-duplicates = \
+  $(call test-expect,,$(call remove-duplicates))\
+  $(call test-expect,foo bar,$(call remove-duplicates,foo bar))\
+  $(call test-expect,foo bar,$(call remove-duplicates,foo bar foo bar))\
+  $(call test-expect,foo bar,$(call remove-duplicates,foo foo bar bar bar))
+
+# -----------------------------------------------------------------------------
+# Function : clear-vars
+# Arguments: 1: list of variable names
+#            2: file where the variable should be defined
+# Returns  : None
+# Usage    : $(call clear-vars, VAR1 VAR2 VAR3...)
+# Rationale: Clears/undefines all variables in argument list
+# -----------------------------------------------------------------------------
+clear-vars = $(foreach __varname,$1,$(eval $(__varname) := $(empty)))
+
+# -----------------------------------------------------------------------------
+# Function : filter-by
+# Arguments: 1: list
+#            2: predicate function, will be called as $(call $2,<name>)
+#               and it this returns a non-empty value, then <name>
+#               will be appended to the result.
+# Returns  : elements of $1 that satisfy the predicate function $2
+# -----------------------------------------------------------------------------
+filter-by = $(strip \
+  $(foreach __filter_by_n,$1,\
+    $(if $(call $2,$(__filter_by_n)),$(__filter_by_n))))
+
+-test-filter-by = \
+    $(eval -local-func = $$(call seq,foo,$$1))\
+    $(call test-expect,,$(call filter-by,,-local-func))\
+    $(call test-expect,foo,$(call filter-by,foo,-local-func))\
+    $(call test-expect,foo,$(call filter-by,foo bar,-local-func))\
+    $(call test-expect,foo foo,$(call filter-by,aaa foo bar foo,-local-func))\
+    $(eval -local-func = $$(call sne,foo,$$1))\
+    $(call test-expect,,$(call filter-by,,-local-func))\
+    $(call test-expect,,$(call filter-by,foo,-local-func))\
+    $(call test-expect,bar,$(call filter-by,foo bar,-local-func))\
+    $(call test-expect,aaa bar,$(call filter-by,aaa foo bar,-local-func))
+
+# -----------------------------------------------------------------------------
+# Function : filter-out-by
+# Arguments: 1: list
+#            2: predicate function, will be called as $(call $2,<name>)
+#               and it this returns an empty value, then <name>
+#               will be appended to the result.
+# Returns  : elements of $1 that do not satisfy the predicate function $2
+# -----------------------------------------------------------------------------
+filter-out-by = $(strip \
+  $(foreach __filter_out_by_n,$1,\
+    $(if $(call $2,$(__filter_out_by_n)),,$(__filter_out_by_n))))
+
+-test-filter-out-by = \
+    $(eval -local-func = $$(call seq,foo,$$1))\
+    $(call test-expect,,$(call filter-out-by,,-local-func))\
+    $(call test-expect,,$(call filter-out-by,foo,-local-func))\
+    $(call test-expect,bar,$(call filter-out-by,foo bar,-local-func))\
+    $(call test-expect,aaa bar,$(call filter-out-by,aaa foo bar foo,-local-func))\
+    $(eval -local-func = $$(call sne,foo,$$1))\
+    $(call test-expect,,$(call filter-out-by,,-local-func))\
+    $(call test-expect,foo,$(call filter-out-by,foo,-local-func))\
+    $(call test-expect,foo,$(call filter-out-by,foo bar,-local-func))\
+    $(call test-expect,foo foo,$(call filter-out-by,aaa foo bar foo,-local-func))
+
+# -----------------------------------------------------------------------------
+# Function : find-first
+# Arguments: 1: list
+#            2: predicate function, will be called as $(call $2,<name>).
+# Returns  : the first item of $1 that satisfies the predicate.
+# -----------------------------------------------------------------------------
+find-first = $(firstword $(call filter-by,$1,$2))
+
+-test-find-first.empty = \
+    $(eval -local-pred = $$(call seq,foo,$$1))\
+    $(call test-expect,,$(call find-first,,-local-pred))\
+    $(call test-expect,,$(call find-first,bar,-local-pred))
+
+-test-find-first.simple = \
+    $(eval -local-pred = $$(call seq,foo,$$1))\
+    $(call test-expect,foo,$(call find-first,foo,-local-pred))\
+    $(call test-expect,foo,$(call find-first,aaa foo bar,-local-pred))\
+    $(call test-expect,foo,$(call find-first,aaa foo foo bar,-local-pred))
+
+# -----------------------------------------------------------------------------
+# Function : parent-dir
+# Arguments: 1: path
+# Returns  : Parent dir or path of $1, with final separator removed.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),windows)
+# On Windows, defining parent-dir is a bit more tricky because the
+# GNU Make $(dir ...) function doesn't return an empty string when it
+# reaches the top of the directory tree, and we want to enforce this to
+# avoid infinite loops.
+#
+#   $(dir C:)     -> C:       (empty expected)
+#   $(dir C:/)    -> C:/      (empty expected)
+#   $(dir C:\)    -> C:\      (empty expected)
+#   $(dir C:/foo) -> C:/      (correct)
+#   $(dir C:\foo) -> C:\      (correct)
+#
+parent-dir = $(patsubst %/,%,$(strip \
+    $(eval __dir_node := $(patsubst %/,%,$(subst \,/,$1)))\
+    $(eval __dir_parent := $(dir $(__dir_node)))\
+    $(filter-out $1,$(__dir_parent))\
+    ))
+else
+parent-dir = $(patsubst %/,%,$(dir $(1:%/=%)))
+endif
+
+-test-parent-dir = \
+  $(call test-expect,,$(call parent-dir))\
+  $(call test-expect,.,$(call parent-dir,foo))\
+  $(call test-expect,foo,$(call parent-dir,foo/bar))\
+  $(call test-expect,foo,$(call parent-dir,foo/bar/))
+
+# -----------------------------------------------------------------------------
+# Strip any 'lib' prefix in front of a given string.
+#
+# Function : strip-lib-prefix
+# Arguments: 1: module name
+# Returns  : module name, without any 'lib' prefix if any
+# Usage    : $(call strip-lib-prefix,$(LOCAL_MODULE))
+# -----------------------------------------------------------------------------
+strip-lib-prefix = $(1:lib%=%)
+
+-test-strip-lib-prefix = \
+  $(call test-expect,,$(call strip-lib-prefix,))\
+  $(call test-expect,foo,$(call strip-lib-prefix,foo))\
+  $(call test-expect,foo,$(call strip-lib-prefix,libfoo))\
+  $(call test-expect,nolibfoo,$(call strip-lib-prefix,nolibfoo))\
+  $(call test-expect,foolib,$(call strip-lib-prefix,foolib))\
+  $(call test-expect,foo bar,$(call strip-lib-prefix,libfoo libbar))
+
+# -----------------------------------------------------------------------------
+# Left-justify input string with spaces to fill a width of 15.
+# Function: left-justify-quoted-15
+# Arguments: 1: Input text
+# Returns: A quoted string that can be used in command scripts to print
+#          the left-justified input with host-echo.
+#
+# Usage:  ---->@$(call host-echo, $(call left-justify-quoted-15,$(_TEXT)): Do stuff)
+#         Where ----> is a TAB character.
+# -----------------------------------------------------------------------------
+left-justify-quoted-15 = $(call -left-justify,$1,xxxxxxxxxxxxxxx)
+
+-test-left-justify-quoted-15 = \
+  $(call test-expect,"               ",$(call left-justify-quoted-15,))\
+  $(call test-expect,"Foo Bar        ",$(call left-justify-quoted-15,Foo Bar))\
+  $(call test-expect,"Very long string over 15 characters wide",$(strip \
+    $(call left-justify-quoted-15,Very long string over 15 characters wide)))
+
+# Used internally to compute a quoted left-justified text string.
+# $1: Input string.
+# $2: A series of contiguous x's, its length determines the full width to justify to.
+# Return: A quoted string with the input text left-justified appropriately.
+-left-justify = $(strip \
+    $(eval __lj_temp := $(subst $(space),x,$1))\
+    $(foreach __lj_a,$(__gmsl_characters),$(eval __lj_temp := $$(subst $$(__lj_a),x,$(__lj_temp))))\
+    $(eval __lj_margin := $$(call -justification-margin,$(__lj_temp),$2)))"$1$(subst x,$(space),$(__lj_margin))"
+
+-test-left-justify = \
+  $(call test-expect,"",$(call -left-justify,,))\
+  $(call test-expect,"foo",$(call -left-justify,foo,xxx))\
+  $(call test-expect,"foo ",$(call -left-justify,foo,xxxx))\
+  $(call test-expect,"foo   ",$(call -left-justify,foo,xxxxxx))\
+  $(call test-expect,"foo         ",$(call -left-justify,foo,xxxxxxxxxxxx))\
+  $(call test-expect,"very long string",$(call -left-justify,very long string,xxx))\
+
+# Used internally to compute a justification margin.
+# Expects $1 to be defined to a string of consecutive x's (e.g. 'xxxx')
+# Expects $2 to be defined to a maximum string of x's (e.g. 'xxxxxxxxx')
+# Returns a string of x's such as $1 + $(result) is equal to $2
+# If $1 is larger than $2, return empty string..
+-justification-margin = $(strip \
+    $(if $2,\
+      $(if $1,\
+        $(call -justification-margin-inner,$1,$2),\
+        $2\
+      ),\
+    $1))
+
+-justification-margin-inner = $(if $(findstring $2,$1),,x$(call -justification-margin-inner,x$1,$2))
+
+-test-justification-margin = \
+  $(call test-expect,,$(call -justification-margin,,))\
+  $(call test-expect,,$(call -justification-margin,xxx,xxx))\
+  $(call test-expect,xxxxxx,$(call -justification-margin,,xxxxxx))\
+  $(call test-expect,xxxxx,$(call -justification-margin,x,xxxxxx))\
+  $(call test-expect,xxxx,$(call -justification-margin,xx,xxxxxx))\
+  $(call test-expect,xxx,$(call -justification-margin,xxx,xxxxxx))\
+  $(call test-expect,xx,$(call -justification-margin,xxxx,xxxxxx))\
+  $(call test-expect,x,$(call -justification-margin,xxxxx,xxxxxx))\
+  $(call test-expect,,$(call -justification-margin,xxxxxx,xxxxxx))\
+  $(call test-expect,,$(call -justification-margin,xxxxxxxxxxx,xxxxxx))\
+
+# Escapes \ to \\. Useful for escaping Windows paths.
+escape-backslashes = $(subst \,\\,$1)
diff --git a/build/core/definitions.mk b/build/core/definitions.mk
new file mode 100644
index 0000000..cc33be9
--- /dev/null
+++ b/build/core/definitions.mk
@@ -0,0 +1,2170 @@
+# Copyright (C) 2009 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.
+#
+# Common definitions for the Android NDK build system
+#
+
+# We use the GNU Make Standard Library
+include $(NDK_ROOT)/build/gmsl/gmsl
+
+include $(BUILD_SYSTEM)/definitions-tests.mk
+include $(BUILD_SYSTEM)/definitions-utils.mk
+include $(BUILD_SYSTEM)/definitions-host.mk
+include $(BUILD_SYSTEM)/definitions-graph.mk
+
+# -----------------------------------------------------------------------------
+# Macro    : this-makefile
+# Returns  : the name of the current Makefile in the inclusion stack
+# Usage    : $(this-makefile)
+# -----------------------------------------------------------------------------
+this-makefile = $(lastword $(MAKEFILE_LIST))
+
+# -----------------------------------------------------------------------------
+# Macro    : local-makefile
+# Returns  : the name of the last parsed Android.mk file
+# Usage    : $(local-makefile)
+# -----------------------------------------------------------------------------
+local-makefile = $(lastword $(filter %Android.mk,$(MAKEFILE_LIST)))
+
+# -----------------------------------------------------------------------------
+# Function : assert-defined
+# Arguments: 1: list of variable names
+# Returns  : None
+# Usage    : $(call assert-defined, VAR1 VAR2 VAR3...)
+# Rationale: Checks that all variables listed in $1 are defined, or abort the
+#            build
+# -----------------------------------------------------------------------------
+assert-defined = $(foreach __varname,$(strip $1),\
+  $(if $(strip $($(__varname))),,\
+    $(call __ndk_error, Assertion failure: $(__varname) is not defined)\
+  )\
+)
+
+# -----------------------------------------------------------------------------
+# Function : check-required-vars
+# Arguments: 1: list of variable names
+#            2: file where the variable(s) should be defined
+# Returns  : None
+# Usage    : $(call check-required-vars, VAR1 VAR2 VAR3..., <file>)
+# Rationale: Checks that all required vars listed in $1 were defined by $2
+#            or abort the build with an error
+# -----------------------------------------------------------------------------
+check-required-vars = $(foreach __varname,$1,\
+  $(if $(strip $($(__varname))),,\
+    $(call __ndk_info, Required variable $(__varname) is not defined by $2)\
+    $(call __ndk_error,Aborting)\
+  )\
+)
+
+# The list of default C++ extensions supported by GCC.
+default-c++-extensions := .cc .cp .cxx .cpp .CPP .c++ .C
+
+# The list of default RS extensions supported by llvm-rs-cc
+default-rs-extensions := .rs .fs
+
+# -----------------------------------------------------------------------------
+# Function : generate-dir
+# Arguments: 1: directory path
+# Returns  : Generate a rule, but not dependency, to create a directory with
+#            host-mkdir.
+# Usage    : $(call generate-dir,<path>)
+# -----------------------------------------------------------------------------
+define ev-generate-dir
+__ndk_dir := $1
+ifeq (,$$(__ndk_dir_flag__$$(__ndk_dir)))
+# Note that the following doesn't work because path in windows may contain
+# ':' if ndk-build is called inside jni/ directory when path is expanded
+# to full-path, eg. C:/path/to/project/jni/
+#
+#    __ndk_dir_flag__$1 := true
+#
+__ndk_dir_flag__$$(__ndk_dir) := true
+$1:
+	@$$(call host-mkdir,$$@)
+endif
+endef
+
+generate-dir = $(eval $(call ev-generate-dir,$1))
+
+# -----------------------------------------------------------------------------
+# Function : generate-file-dir
+# Arguments: 1: file path
+# Returns  : Generate a dependency and a rule to ensure that the parent
+#            directory of the input file path will be created before it.
+#            This is used to enforce a call to host-mkdir.
+# Usage    : $(call generate-file-dir,<file>)
+# Rationale: Many object files will be stored in the same output directory.
+#            Introducing a dependency on the latter avoids calling mkdir -p
+#            for every one of them.
+#
+# -----------------------------------------------------------------------------
+
+define ev-generate-file-dir
+__ndk_file_dir := $(call parent-dir,$1)
+$$(call generate-dir,$$(__ndk_file_dir))
+$1:| $$(__ndk_file_dir)
+endef
+
+generate-file-dir = $(eval $(call ev-generate-file-dir,$1))
+
+# -----------------------------------------------------------------------------
+# Function : generate-list-file
+# Arguments: 1: list of strings (possibly very long)
+#            2: file name
+# Returns  : write the content of a possibly very long string list to a file.
+#            this shall be used in commands and will work around limitations
+#            of host command-line lengths.
+# Usage    : $(call host-echo-to-file,<string-list>,<file>)
+# Rationale: When there is a very large number of objects and/or libraries at
+#            link time, the size of the command becomes too large for the
+#            host system's maximum. Various tools however support the
+#            @<listfile> syntax, where <listfile> is the path of a file
+#            which content will be parsed as if they were options.
+#
+#            This function is used to generate such a list file from a long
+#            list of strings in input.
+#
+# -----------------------------------------------------------------------------
+
+# Helper functions because the GNU Make $(word ...) function does
+# not accept a 0 index, so we need to bump any of these to 1 when
+# we find them.
+#
+index-is-zero = $(filter 0 00 000 0000 00000 000000 0000000,$1)
+bump-0-to-1 = $(if $(call index-is-zero,$1),1,$1)
+
+-test-bump-0-to-1 = \
+  $(call test-expect,$(call bump-0-to-1))\
+  $(call test-expect,1,$(call bump-0-to-1,0))\
+  $(call test-expect,1,$(call bump-0-to-1,1))\
+  $(call test-expect,2,$(call bump-0-to-1,2))\
+  $(call test-expect,1,$(call bump-0-to-1,00))\
+  $(call test-expect,1,$(call bump-0-to-1,000))\
+  $(call test-expect,1,$(call bump-0-to-1,0000))\
+  $(call test-expect,1,$(call bump-0-to-1,00000))\
+  $(call test-expect,1,$(call bump-0-to-1,000000))\
+  $(call test-expect,10,$(call bump-0-to-1,10))\
+  $(call test-expect,100,$(call bump-0-to-1,100))
+
+# Same as $(wordlist ...) except the start index, if 0, is bumped to 1
+index-word-list = $(wordlist $(call bump-0-to-1,$1),$2,$3)
+
+-test-index-word-list = \
+  $(call test-expect,,$(call index-word-list,1,1))\
+  $(call test-expect,a b,$(call index-word-list,0,2,a b c d))\
+  $(call test-expect,b c,$(call index-word-list,2,3,a b c d))\
+
+# NOTE: With GNU Make $1 and $(1) are equivalent, which means
+#       that $10 is equivalent to $(1)0, and *not* $(10).
+
+# Used to generate a slice of up to 10 items starting from index $1,
+# If $1 is 0, it will be bumped to 1 (and only 9 items will be printed)
+# $1: start (tenth) index. Can be 0
+# $2: word list
+#
+define list-file-start-gen-10
+	$$(hide) $$(HOST_ECHO_N) "$(call index-word-list,$10,$19,$2) " >> $$@
+endef
+
+# Used to generate a slice of always 10 items starting from index $1
+# $1: start (tenth) index. CANNOT BE 0
+# $2: word list
+define list-file-always-gen-10
+	$$(hide) $$(HOST_ECHO_N) "$(wordlist $10,$19,$2) " >> $$@
+endef
+
+# Same as list-file-always-gen-10, except that the word list might be
+# empty at position $10 (i.e. $(1)0)
+define list-file-maybe-gen-10
+ifneq ($(word $10,$2),)
+	$$(hide) $$(HOST_ECHO_N) "$(wordlist $10,$19,$2) " >> $$@
+endif
+endef
+
+define list-file-start-gen-100
+$(call list-file-start-gen-10,$10,$2)
+$(call list-file-always-gen-10,$11,$2)
+$(call list-file-always-gen-10,$12,$2)
+$(call list-file-always-gen-10,$13,$2)
+$(call list-file-always-gen-10,$14,$2)
+$(call list-file-always-gen-10,$15,$2)
+$(call list-file-always-gen-10,$16,$2)
+$(call list-file-always-gen-10,$17,$2)
+$(call list-file-always-gen-10,$18,$2)
+$(call list-file-always-gen-10,$19,$2)
+endef
+
+define list-file-always-gen-100
+$(call list-file-always-gen-10,$10,$2)
+$(call list-file-always-gen-10,$11,$2)
+$(call list-file-always-gen-10,$12,$2)
+$(call list-file-always-gen-10,$13,$2)
+$(call list-file-always-gen-10,$14,$2)
+$(call list-file-always-gen-10,$15,$2)
+$(call list-file-always-gen-10,$16,$2)
+$(call list-file-always-gen-10,$17,$2)
+$(call list-file-always-gen-10,$18,$2)
+$(call list-file-always-gen-10,$19,$2)
+endef
+
+define list-file-maybe-gen-100
+ifneq ($(word $(call bump-0-to-1,$100),$2),)
+ifneq ($(word $199,$2),)
+$(call list-file-start-gen-10,$10,$2)
+$(call list-file-always-gen-10,$11,$2)
+$(call list-file-always-gen-10,$12,$2)
+$(call list-file-always-gen-10,$13,$2)
+$(call list-file-always-gen-10,$14,$2)
+$(call list-file-always-gen-10,$15,$2)
+$(call list-file-always-gen-10,$16,$2)
+$(call list-file-always-gen-10,$17,$2)
+$(call list-file-always-gen-10,$18,$2)
+$(call list-file-always-gen-10,$19,$2)
+else
+ifneq ($(word $150,$2),)
+$(call list-file-start-gen-10,$10,$2)
+$(call list-file-always-gen-10,$11,$2)
+$(call list-file-always-gen-10,$12,$2)
+$(call list-file-always-gen-10,$13,$2)
+$(call list-file-always-gen-10,$14,$2)
+$(call list-file-maybe-gen-10,$15,$2)
+$(call list-file-maybe-gen-10,$16,$2)
+$(call list-file-maybe-gen-10,$17,$2)
+$(call list-file-maybe-gen-10,$18,$2)
+$(call list-file-maybe-gen-10,$19,$2)
+else
+$(call list-file-start-gen-10,$10,$2)
+$(call list-file-maybe-gen-10,$11,$2)
+$(call list-file-maybe-gen-10,$12,$2)
+$(call list-file-maybe-gen-10,$13,$2)
+$(call list-file-maybe-gen-10,$14,$2)
+endif
+endif
+endif
+endef
+
+define list-file-maybe-gen-1000
+ifneq ($(word $(call bump-0-to-1,$1000),$2),)
+ifneq ($(word $1999,$2),)
+$(call list-file-start-gen-100,$10,$2)
+$(call list-file-always-gen-100,$11,$2)
+$(call list-file-always-gen-100,$12,$2)
+$(call list-file-always-gen-100,$13,$2)
+$(call list-file-always-gen-100,$14,$2)
+$(call list-file-always-gen-100,$15,$2)
+$(call list-file-always-gen-100,$16,$2)
+$(call list-file-always-gen-100,$17,$2)
+$(call list-file-always-gen-100,$18,$2)
+$(call list-file-always-gen-100,$19,$2)
+else
+ifneq ($(word $1500,$2),)
+$(call list-file-start-gen-100,$10,$2)
+$(call list-file-always-gen-100,$11,$2)
+$(call list-file-always-gen-100,$12,$2)
+$(call list-file-always-gen-100,$13,$2)
+$(call list-file-always-gen-100,$14,$2)
+$(call list-file-maybe-gen-100,$15,$2)
+$(call list-file-maybe-gen-100,$16,$2)
+$(call list-file-maybe-gen-100,$17,$2)
+$(call list-file-maybe-gen-100,$18,$2)
+$(call list-file-maybe-gen-100,$19,$2)
+else
+$(call list-file-start-gen-100,$10,$2)
+$(call list-file-maybe-gen-100,$11,$2)
+$(call list-file-maybe-gen-100,$12,$2)
+$(call list-file-maybe-gen-100,$13,$2)
+$(call list-file-maybe-gen-100,$14,$2)
+endif
+endif
+endif
+endef
+
+
+define generate-list-file-ev
+__list_file := $2
+
+.PHONY: $$(__list_file).tmp
+
+$$(call generate-file-dir,$$(__list_file).tmp)
+
+$$(__list_file).tmp:
+	$$(hide) $$(HOST_ECHO_N) "" > $$@
+$(call list-file-maybe-gen-1000,0,$1)
+$(call list-file-maybe-gen-1000,1,$1)
+$(call list-file-maybe-gen-1000,2,$1)
+$(call list-file-maybe-gen-1000,3,$1)
+$(call list-file-maybe-gen-1000,4,$1)
+$(call list-file-maybe-gen-1000,5,$1)
+
+$$(__list_file): $$(__list_file).tmp
+	$$(hide) $$(call host-copy-if-differ,[email protected],$$@)
+	$$(hide) $$(call host-rm,[email protected])
+
+endef
+
+generate-list-file = $(eval $(call generate-list-file-ev,$1,$2))
+
+# -----------------------------------------------------------------------------
+# Function : link-whole-archives
+# Arguments: 1: list of whole static libraries
+# Returns  : linker flags to use the whole static libraries
+# Usage    : $(call link-whole-archives,<libraries>)
+# Rationale: This function is used to put the list of whole static libraries
+#            inside a -Wl,--whole-archive ... -Wl,--no-whole-archive block.
+#            If the list is empty, it returns an empty string.
+#            This function also calls host-path to translate the library
+#            paths.
+# -----------------------------------------------------------------------------
+link-whole-archives = $(if $(strip $1),$(call link-whole-archive-flags,$1))
+link-whole-archive-flags = -Wl,--whole-archive $(call host-path,$1) -Wl,--no-whole-archive
+
+-test-link-whole-archive = \
+  $(call test-expect,,$(call link-whole-archives))\
+  $(eval _start := -Wl,--whole-archive)\
+  $(eval _end := -Wl,--no-whole-archive)\
+  $(call test-expect,$(_start) foo $(_end),$(call link-whole-archives,foo))\
+  $(call test-expect,$(_start) foo bar $(_end),$(call link-whole-archives,foo bar))
+
+# =============================================================================
+#
+# Modules database
+#
+# The following declarations are used to manage the list of modules
+# defined in application's Android.mk files.
+#
+# Technical note:
+#    We use __ndk_modules to hold the list of all modules corresponding
+#    to a given application.
+#
+#    For each module 'foo', __ndk_modules.foo.<field> is used
+#    to store module-specific information.
+#
+#        type         -> type of module (e.g. 'static', 'shared', ...)
+#        depends      -> list of other modules this module depends on
+#
+#    Also, LOCAL_XXXX values defined for a module are recorded in XXXX, e.g.:
+#
+#        PATH   -> recorded LOCAL_PATH for the module
+#        CFLAGS -> recorded LOCAL_CFLAGS for the module
+#        ...
+#
+#    Some of these are created by build scripts like BUILD_STATIC_LIBRARY:
+#
+#        MAKEFILE -> The Android.mk where the module is defined.
+#        LDFLAGS  -> Final linker flags
+#        OBJECTS  -> List of module objects
+#        BUILT_MODULE -> location of module built file (e.g. obj/<app>/<abi>/libfoo.so)
+#
+#    Note that some modules are never installed (e.g. static libraries).
+#
+# =============================================================================
+
+# The list of LOCAL_XXXX variables that are recorded for each module definition
+# These are documented by docs/ANDROID-MK.TXT. Exception is LOCAL_MODULE
+#
+modules-LOCALS := \
+    MODULE \
+    MODULE_FILENAME \
+    PATH \
+    SRC_FILES \
+    HAS_CPP \
+    CPP_EXTENSION \
+    C_INCLUDES \
+    CFLAGS \
+    CONLYFLAGS \
+    CXXFLAGS \
+    CPPFLAGS \
+    ASFLAGS \
+    ASMFLAGS \
+    STATIC_LIBRARIES \
+    WHOLE_STATIC_LIBRARIES \
+    SHARED_LIBRARIES \
+    LDLIBS \
+    ALLOW_UNDEFINED_SYMBOLS \
+    ARM_MODE \
+    ARM_NEON \
+    DISABLE_NO_EXECUTE \
+    DISABLE_RELRO \
+    DISABLE_FORMAT_STRING_CHECKS \
+    DISABLE_FATAL_LINKER_WARNINGS \
+    EXPORT_CFLAGS \
+    EXPORT_CONLYFLAGS \
+    EXPORT_CPPFLAGS \
+    EXPORT_ASMFLAGS \
+    EXPORT_LDFLAGS \
+    EXPORT_SHARED_LIBRARIES \
+    EXPORT_STATIC_LIBRARIES \
+    EXPORT_LDLIBS \
+    EXPORT_C_INCLUDES \
+    FILTER_ASM \
+    CPP_FEATURES \
+    SHORT_COMMANDS \
+    BUILT_MODULE_NOT_COPIED \
+    THIN_ARCHIVE \
+    PCH \
+    RENDERSCRIPT_INCLUDES \
+    RENDERSCRIPT_INCLUDES_OVERRIDE \
+    RENDERSCRIPT_FLAGS \
+    RENDERSCRIPT_TARGET_API
+
+# The following are generated by the build scripts themselves
+
+# LOCAL_MAKEFILE will contain the path to the Android.mk defining the module
+modules-LOCALS += MAKEFILE
+
+# LOCAL_LDFLAGS will contain the set of final linker flags for the module
+modules-LOCALS += LDFLAGS
+
+# LOCAL_OBJECTS will contain the list of object files generated from the
+# module's sources, if any.
+modules-LOCALS += OBJECTS
+
+# LOCAL_BUILT_MODULE will contain the location of the symbolic version of
+# the generated module (i.e. the one containing all symbols used during
+# native debugging). It is generally under $PROJECT/obj/local/
+modules-LOCALS += BUILT_MODULE
+
+# LOCAL_OBJS_DIR will contain the location where the object files for
+# this module will be stored. Usually $PROJECT/obj/local/<module>/obj
+modules-LOCALS += OBJS_DIR
+
+# LOCAL_INSTALLED will contain the location of the installed version
+# of the module. Usually $PROJECT/libs/<abi>/<prefix><module><suffix>
+# where <prefix> and <suffix> depend on the module class.
+modules-LOCALS += INSTALLED
+
+# LOCAL_MODULE_CLASS will contain the type of the module
+# (e.g. STATIC_LIBRARY, SHARED_LIBRARY, etc...)
+modules-LOCALS += MODULE_CLASS
+
+# the list of managed fields per module
+modules-fields = depends \
+                 $(modules-LOCALS)
+
+# -----------------------------------------------------------------------------
+# Function : modules-clear
+# Arguments: None
+# Returns  : None
+# Usage    : $(call modules-clear)
+# Rationale: clears the list of defined modules known by the build system
+# -----------------------------------------------------------------------------
+modules-clear = \
+    $(foreach __mod,$(__ndk_modules),\
+        $(foreach __field,$(modules-fields),\
+            $(eval __ndk_modules.$(__mod).$(__field) := $(empty))\
+        )\
+    )\
+    $(eval __ndk_modules := $(empty_set)) \
+    $(eval __ndk_top_modules := $(empty)) \
+    $(eval __ndk_import_list := $(empty)) \
+    $(eval __ndk_import_depth := $(empty))
+
+# -----------------------------------------------------------------------------
+# Function : modules-get-list
+# Arguments: None
+# Returns  : The list of all recorded modules
+# Usage    : $(call modules-get-list)
+# -----------------------------------------------------------------------------
+modules-get-list = $(__ndk_modules)
+
+# -----------------------------------------------------------------------------
+# Function : modules-get-top-list
+# Arguments: None
+# Returns  : The list of all recorded non-imported modules
+# Usage    : $(call modules-get-top-list)
+# -----------------------------------------------------------------------------
+modules-get-top-list = $(__ndk_top_modules)
+
+# -----------------------------------------------------------------------------
+# Function : module-add
+# Arguments: 1: module name
+# Returns  : None
+# Usage    : $(call module-add,<modulename>)
+# Rationale: add a new module. If it is already defined, print an error message
+#            and abort. This will record all LOCAL_XXX variables for the module.
+# -----------------------------------------------------------------------------
+module-add = \
+  $(call assert-defined,LOCAL_MAKEFILE LOCAL_BUILT_MODULE LOCAL_OBJS_DIR LOCAL_MODULE_CLASS)\
+  $(if $(call set_is_member,$(__ndk_modules),$1),\
+    $(call __ndk_info,Trying to define local module '$1' in $(LOCAL_MAKEFILE).)\
+    $(call __ndk_info,But this module was already defined by $(__ndk_modules.$1.MAKEFILE).)\
+    $(call __ndk_error,Aborting.)\
+  )\
+  $(eval __ndk_modules := $(call set_insert,$(__ndk_modules),$1))\
+  $(if $(strip $(__ndk_import_depth)),,\
+    $(eval __ndk_top_modules := $(call set_insert,$(__ndk_top_modules),$1))\
+  )\
+  $(if $(call module-class-is-installable,$(LOCAL_MODULE_CLASS)),\
+    $(eval LOCAL_INSTALLED := $(NDK_APP_DST_DIR)/$(notdir $(LOCAL_BUILT_MODULE))),\
+    $(eval LOCAL_INSTALLED := $(LOCAL_BUILT_MODULE))\
+  )\
+  $(foreach __field,STATIC_LIBRARIES WHOLE_STATIC_LIBRARIES SHARED_LIBRARIES,\
+    $(eval LOCAL_$(__field) := $(call strip-lib-prefix,$(LOCAL_$(__field)))))\
+  $(foreach __local,$(modules-LOCALS),\
+    $(eval __ndk_modules.$1.$(__local) := $(LOCAL_$(__local)))\
+  )\
+  $(call module-handle-c++-features,$1)
+
+
+# Retrieve the class of module $1
+module-get-class = $(__ndk_modules.$1.MODULE_CLASS)
+
+# Retrieve built location of module $1
+module-get-built = $(__ndk_modules.$1.BUILT_MODULE)
+
+# Returns $(true) is module $1 is installable
+# An installable module is one that will be copied to $PROJECT/libs/<abi>/
+# (e.g. shared libraries).
+#
+module-is-installable = $(call module-class-is-installable,$(call module-get-class,$1))
+
+# Returns $(true) if module $1 is a copyable prebuilt
+# A copyable prebuilt module is one that will be copied to $NDK_OUT/<abi>/
+# at build time. At the moment, this is only used for prebuilt shared
+# libraries, since it helps ndk-gdb.
+#
+module-is-copyable = $(call module-class-is-copyable,$(call module-get-class,$1))
+
+# -----------------------------------------------------------------------------
+# Function : module-get-export
+# Arguments: 1: module name
+#            2: export variable name without LOCAL_EXPORT_ prefix (e.g. 'CFLAGS')
+# Returns  : Exported value
+# Usage    : $(call module-get-export,<modulename>,<varname>)
+# Rationale: Return the recorded value of LOCAL_EXPORT_$2, if any, for module $1
+# -----------------------------------------------------------------------------
+module-get-export = $(__ndk_modules.$1.EXPORT_$2)
+
+# -----------------------------------------------------------------------------
+# Function : module-get-listed-export
+# Arguments: 1: list of module names
+#            2: export variable name without LOCAL_EXPORT_ prefix (e.g. 'CFLAGS')
+# Returns  : Exported values
+# Usage    : $(call module-get-listed-export,<module-list>,<varname>)
+# Rationale: Return the recorded value of LOCAL_EXPORT_$2, if any, for modules
+#            listed in $1.
+# -----------------------------------------------------------------------------
+module-get-listed-export = $(strip \
+    $(foreach __listed_module,$1,\
+        $(call module-get-export,$(__listed_module),$2)\
+    ))
+
+# -----------------------------------------------------------------------------
+# Function : modules-restore-locals
+# Arguments: 1: module name
+# Returns  : None
+# Usage    : $(call module-restore-locals,<modulename>)
+# Rationale: Restore the recorded LOCAL_XXX definitions for a given module.
+# -----------------------------------------------------------------------------
+module-restore-locals = \
+    $(foreach __local,$(modules-LOCALS),\
+        $(eval LOCAL_$(__local) := $(__ndk_modules.$1.$(__local)))\
+    )
+
+# Dump all module information. Only use this for debugging
+modules-dump-database = \
+    $(info Modules [$(TARGET_ARCH_ABI)]: $(__ndk_modules)) \
+    $(foreach __mod,$(__ndk_modules),\
+        $(info $(space4)$(__mod):)\
+        $(foreach __field,$(modules-fields),\
+            $(eval __fieldval := $(strip $(__ndk_modules.$(__mod).$(__field))))\
+            $(if $(__fieldval),\
+                $(if $(filter 1,$(words $(__fieldval))),\
+                    $(info $(space4)$(space4)$(__field): $(__fieldval)),\
+                    $(info $(space4)$(space4)$(__field): )\
+                    $(foreach __fielditem,$(__fieldval),\
+                        $(info $(space4)$(space4)$(space4)$(__fielditem))\
+                    )\
+                )\
+            )\
+        )\
+    )\
+    $(info Top modules: $(__ndk_top_modules))\
+    $(info --- end of modules list)
+
+
+# -----------------------------------------------------------------------------
+# Function : module-add-static-depends
+# Arguments: 1: module name
+#            2: list/set of static library modules this module depends on.
+# Returns  : None
+# Usage    : $(call module-add-static-depends,<modulename>,<list of module names>)
+# Rationale: Record that a module depends on a set of static libraries.
+#            Use module-get-static-dependencies to retrieve final list.
+# -----------------------------------------------------------------------------
+module-add-static-depends = \
+    $(call module-add-depends-any,$1,$2,depends) \
+
+# -----------------------------------------------------------------------------
+# Function : module-add-shared-depends
+# Arguments: 1: module name
+#            2: list/set of shared library modules this module depends on.
+# Returns  : None
+# Usage    : $(call module-add-shared-depends,<modulename>,<list of module names>)
+# Rationale: Record that a module depends on a set of shared libraries.
+#            Use modulge-get-shared-dependencies to retrieve final list.
+# -----------------------------------------------------------------------------
+module-add-shared-depends = \
+    $(call module-add-depends-any,$1,$2,depends) \
+
+# Used internally by module-add-static-depends and module-add-shared-depends
+# NOTE: this function must not modify the existing dependency order when new depends are added.
+#
+module-add-depends-any = \
+    $(eval __ndk_modules.$1.$3 += $(filter-out $(__ndk_modules.$1.$3),$2))
+
+
+# -----------------------------------------------------------------------------
+# Returns non-empty if a module is a static library
+# Arguments: 1: module name
+# Returns     : non-empty iff the module is a static library.
+# Usage       : $(if $(call module-is-static-library,<name>),...)
+# -----------------------------------------------------------------------------
+module-is-static-library = $(strip \
+  $(filter STATIC_LIBRARY PREBUILT_STATIC_LIBRARY,\
+    $(call module-get-class,$1)))
+
+# -----------------------------------------------------------------------------
+# Returns non-empty if a module is a shared library
+# Arguments: 1: module name
+# Returns     : non-empty iff the module is a shared library.
+# Usage       : $(if $(call module-is-shared-library,<name>),...)
+# -----------------------------------------------------------------------------
+module-is-shared-library = $(strip \
+  $(filter SHARED_LIBRARY PREBUILT_SHARED_LIBRARY,\
+    $(call module-get-class,$1)))
+
+# -----------------------------------------------------------------------------
+# Filter a list of module names to retain only the static libraries.
+# Arguments: 1: module name list
+# Returns     : input list modules which are static libraries.
+# -----------------------------------------------------------------------------
+module-filter-static-libraries = $(call filter-by,$1,module-is-static-library)
+
+# -----------------------------------------------------------------------------
+# Filter a list of module names to retain only the shared libraries.
+# Arguments: 1: module name list
+# Returns     : input list modules which are shared libraries.
+# -----------------------------------------------------------------------------
+module-filter-shared-libraries = $(call filter-by,$1,module-is-shared-library)
+
+# -----------------------------------------------------------------------------
+# Return the LOCAL_STATIC_LIBRARIES for a given module.
+# Arguments: 1: module name
+# Returns     : List of static library modules.
+# -----------------------------------------------------------------------------
+module-get-static-libs = $(__ndk_modules.$1.STATIC_LIBRARIES)
+
+# -----------------------------------------------------------------------------
+# Return the LOCAL_WHOLE_STATIC_LIBRARIES for a given module.
+# Arguments: 1: module name
+# Returns     : List of whole static library modules.
+# -----------------------------------------------------------------------------
+module-get-whole-static-libs = $(__ndk_modules.$1.WHOLE_STATIC_LIBRARIES)
+
+# -----------------------------------------------------------------------------
+# Return all static libraries for a given module.
+# Arguments: 1: module name
+# Returns     : List of static library modules (whole or not).
+# -----------------------------------------------------------------------------
+module-get-all-static-libs = $(strip \
+  $(__ndk_modules.$1.STATIC_LIBRARIES) \
+  $(__ndk_modules.$1.WHOLE_STATIC_LIBRARIES))
+
+# -----------------------------------------------------------------------------
+# Return the list of LOCAL_SHARED_LIBRARIES for a given module.
+# Arguments: 1: module name
+# Returns     : List of shared library modules.
+# -----------------------------------------------------------------------------
+module-get-shared-libs = $(__ndk_modules.$1.SHARED_LIBRARIES)
+
+# -----------------------------------------------------------------------------
+# Return the list of all libraries a modules depends directly on.
+# This is the concatenation of its LOCAL_STATIC_LIBRARIES,
+# LOCAL_WHOLE_STATIC_LIBRARIES, and LOCAL_SHARED_LIBRARIES variables.
+# Arguments: 1: module name
+# Returns     : List of library modules (static or shared).
+# -----------------------------------------------------------------------------
+module-get-direct-libs = $(strip \
+  $(__ndk_modules.$1.STATIC_LIBRARIES) \
+  $(__ndk_modules.$1.WHOLE_STATIC_LIBRARIES) \
+  $(__ndk_modules.$1.SHARED_LIBRARIES))
+
+
+# -----------------------------------------------------------------------------
+# Computes the full closure of a module and its dependencies. Order is
+# defined by a breadth-first walk of the graph.
+# $1 will be the first item in the result.
+#
+# Arguments: 1: module name
+# Returns     : List of all modules $1 depends on.
+#
+# Note: Do not use this to determine build dependencies. The returned list
+#       is much too large for this. For example consider the following
+#       dependency graph:
+#
+#   main.exe -> libA.a -> libfoo.so -> libB.a
+#
+#       This function will return all four modules in the result, while
+#       at link time building main.exe only requires the first three.
+#
+# -----------------------------------------------------------------------------
+module-get-all-dependencies = $(call -ndk-mod-get-closure,$1,module-get-depends)
+
+# Same as module-get-all-dependencies, but topologically sorted.
+module-get-all-dependencies-topo = \
+    $(call -ndk-mod-get-topological-depends,$1,module-get-all-dependencies)
+
+# -----------------------------------------------------------------------------
+# Compute the list of all static and shared libraries required to link a
+# given module.
+#
+# Note that the result is topologically ordered, i.e. if library A depends
+# on library B, then A will always appear after B in the result.
+#
+# Arguments: 1: module name
+# Returns     : List of all library $1 depends at link time.
+#
+# Note: This doesn't differentiate between regular and whole static
+#       libraries. Use module-extract-whole-static-libs to filter the
+#       result returned by this function.
+# -----------------------------------------------------------------------------
+module-get-link-libs = $(strip \
+  $(eval _ndk_mod_link_module := $1) \
+  $(call -ndk-mod-get-topological-depends,$1,-ndk-mod-link-deps))
+
+# Special dependency function used by module-get-link-libs.
+# The rules to follow are the following:
+#  - if $1 is the link module, or if it is a static library, then all
+#    direct dependencies.
+#  - otherwise, the module is a shared library, don't add build deps.
+-ndk-mod-link-deps = \
+  $(if $(call seq,$1,$(_ndk_mod_link_module))$(call module-is-static-library,$1),\
+    $(call module-get-direct-libs,$1))
+
+# -----------------------------------------------------------------------------
+# This function is used to extract the list of static libraries that need
+# to be linked as whole, i.e. placed in a special section on the final
+# link command.
+# Arguments: $1: module name.
+#            $2: list of all static link-time libraries (regular or whole).
+# Returns  : list of static libraries from '$2' that need to be linked
+#            as whole.
+# -----------------------------------------------------------------------------
+module-extract-whole-static-libs = $(strip \
+  $(eval _ndk_mod_whole_all := $(call map,module-get-whole-static-libs,$1 $2))\
+  $(eval _ndk_mod_whole_result := $(filter $(_ndk_mod_whole_all),$2))\
+  $(_ndk_mod_whole_result))
+
+# Used to recompute all dependencies once all module information has been recorded.
+modules-compute-dependencies = \
+    $(foreach __module,$(__ndk_modules),\
+        $(call module-compute-depends,$(__module))\
+    )
+
+# Recurses though modules imported by $1 to come up with the transitive closure
+# of imports.
+# $1: Module
+# $2: Import type (STATIC_LIBRARIES or SHARED_LIBRARIES)
+module_get_recursive_imports = \
+    $(eval _from_static_libs.$1 := \
+        $(call module-get-listed-export,\
+            $(__ndk_modules.$1.STATIC_LIBRARIES),$2))\
+    $(eval _from_shared_libs.$1 := \
+        $(call module-get-listed-export,\
+            $(__ndk_modules.$1.SHARED_LIBRARIES),$2))\
+    $(eval _from_imports.$1 := \
+        $(foreach _import,$(_from_static_libs.1),\
+            $(call module_get_recursive_imports,$(_import),$2))\
+        $(foreach _import,$(_from_shared_libs.$1),\
+            $(call module_get_recursive_imports,$(_import),$2)))\
+    $(_from_static_libs.$1) $(_from_shared_libs.$1) $(_from_imports.$1)
+
+# Fills __ndk_modules.$1.depends with a list of all the modules that $1 depends
+# on. Note that this runs before import-locals.mk is run (import-locals.mk needs
+# this information), so we have to explicitly check for exported libraries from
+# our dependencies. Imported libraries might in turn export more libraries to
+# us, so do this recursively.
+module-compute-depends = \
+    $(call module-add-static-depends,$1,$(__ndk_modules.$1.STATIC_LIBRARIES))\
+    $(call module-add-static-depends,$1,$(__ndk_modules.$1.WHOLE_STATIC_LIBRARIES))\
+    $(call module-add-shared-depends,$1,$(__ndk_modules.$1.SHARED_LIBRARIES))\
+    $(call module-add-static-depends,$1,\
+        $(call module_get_recursive_imports,$1,STATIC_LIBRARIES))\
+    $(call module-add-shared-depends,$1,\
+        $(call module_get_recursive_imports,$1,SHARED_LIBRARIES))\
+
+module-get-installed = $(__ndk_modules.$1.INSTALLED)
+
+module-get-depends = $(__ndk_modules.$1.depends)
+
+# -----------------------------------------------------------------------------
+# Function : modules-get-all-installable
+# Arguments: 1: list of module names
+# Returns  : List of all the installable modules $1 depends on transitively.
+# Usage    : $(call modules-all-get-installable,<list of module names>)
+# Rationale: This computes the closure of all installable module dependencies starting from $1
+# -----------------------------------------------------------------------------
+# For now, only the closure of LOCAL_SHARED_LIBRARIES is enough
+modules-get-all-installable = $(strip \
+    $(foreach __alldep,$(call module-get-all-dependencies,$1),\
+        $(if $(call module-is-installable,$(__alldep)),$(__alldep))\
+    ))
+
+# Return the C++ extension(s) of a given module
+# $1: module name
+module-get-c++-extensions = $(strip \
+    $(if $(__ndk_modules.$1.CPP_EXTENSION),\
+        $(__ndk_modules.$1.CPP_EXTENSION),\
+        $(default-c++-extensions)\
+    ))
+
+# Return the list of C++ sources of a given module
+#
+module-get-c++-sources = \
+    $(eval __files := $(__ndk_modules.$1.SRC_FILES:%.neon=%)) \
+    $(eval __files := $(__files:%.arm=%)) \
+    $(eval __extensions := $(call module-get-c++-extensions,$1))\
+    $(filter $(foreach __extension,$(__extensions),%$(__extension)),$(__files))
+
+# Returns true if a module has C++ sources
+#
+module-has-c++-sources = $(strip $(call module-get-c++-sources,$1) \
+                                 $(filter true,$(__ndk_modules.$1.HAS_CPP)))
+
+
+# Add C++ dependencies to any module that has C++ sources.
+# $1: list of C++ runtime static libraries (if any)
+# $2: list of C++ runtime shared libraries (if any)
+# $3: list of C++ runtime ldlibs (if any)
+modules-add-c++-dependencies = \
+    $(foreach __module,$(__ndk_modules),\
+        $(if $(call module-has-c++-sources,$(__module)),\
+            $(call ndk_log,Module '$(__module)' has C++ sources)\
+            $(call module-add-c++-deps,$(__module),$1,$2,$3),\
+        )\
+        $(if $(call module-has-c++-features,$(__module),rtti exceptions),\
+            $(if $(filter system,$(NDK_APP_STL)),\
+                $(call ndk_log,Module '$(__module)' uses C++ features and the system STL)\
+                $(call import-module,cxx-stl/llvm-libc++)\
+                $(call import-module,cxx-stl/llvm-libc++abi)\
+                $(call module-add-c++-deps,$(__module),c++abi)\
+                $(if $(filter true,$(NDK_PLATFORM_NEEDS_ANDROID_SUPPORT)),\
+                    $(call module-add-c++-deps,$(__module),android_support))\
+                $(if $(filter armeabi-v7a,$(TARGET_ARCH_ABI)),\
+                    $(call module-add-c++-deps,$(__module),unwind,,-ldl))))\
+    )
+
+
+# Return the compiler flags used to compile a C++ module
+# Order matters and should match the one used by the build command
+module-get-c++-flags = $(strip \
+    $(__ndk_modules.$1.CFLAGS) \
+    $(__ndk_modules.$1.CPPFLAGS) \
+    $(__ndk_modules.$1.CXXFLAGS))
+
+# This function is used to remove certain flags from a module compiler flags
+# $1: Module name
+# $2: List of flags to remove
+#
+module-filter-out-compiler-flags = \
+    $(eval __ndk_modules.$1.CFLAGS     := $(filter-out $2,$(__ndk_modules.$1.CFLAGS)))\
+    $(eval __ndk_modules.$1.CONLYFLAGS := $(filter-out $2,$(__ndk_modules.$1.CONLYFLAGS)))\
+    $(eval __ndk_modules.$1.CPPFLAGS   := $(filter-out $2,$(__ndk_modules.$1.CPPFLAGS)))\
+    $(eval __ndk_modules.$1.CXXFLAGS   := $(filter-out $2,$(__ndk_modules.$1.CXXFLAGS)))\
+    $(eval __ndk_modules.$1.ASMFLAGS   := $(filter-out $2,$(__ndk_modules.$1.ASMFLAGS)))
+
+# Return true if a module's compiler flags enable rtti
+# We just look at -frtti and -fno-rtti on the command-line
+# and keep the last one of these flags.
+module-flags-have-rtti = $(strip \
+        $(filter -frtti,\
+            $(lastword $(filter -frtti -fno-rtti,$(call module-get-c++-flags,$1)))\
+        )\
+    )
+
+# Same with C++ exception support (i.e. -fexceptions and -fno-exceptions)
+#
+module-flags-have-exceptions = $(strip \
+        $(filter -fexceptions,\
+            $(lastword $(filter -fexceptions -fno-execeptions,$(call module-get-c++-flags,$1)))\
+        )\
+    )
+
+# Handle the definition of LOCAL_CPP_FEATURES, i.e.:
+#
+#  - If it is defined, check that it only contains valid values
+#  - If it is undefined, try to compute its value automatically by
+#    looking at the C++ compiler flags used to build the module
+#
+# After this, we remove all features flags from the module's command-line
+# And add only the correct ones back in LOCAL_CPP_FLAGS
+#
+module-handle-c++-features = \
+    $(if $(strip $(__ndk_modules.$1.CPP_FEATURES)),\
+        $(eval __cxxbad := $(filter-out rtti exceptions,$(__ndk_modules.$1.CPP_FEATURES)))\
+        $(if $(__cxxbad),\
+            $(call __ndk_info,WARNING: Ignoring invalid values in LOCAL_CPP_FEATURES definition in $(__ndk_modules.$1.MAKEFILE): $(__cxxbad))\
+            $(eval __ndk_modules.$1.CPP_FEATURES := $(strip $(filter-out $(__cxxbad),$(__ndk_modules.$1.CPP_FEATURES))))\
+        )\
+    ,\
+        $(eval __ndk_modules.$1.CPP_FEATURES := $(strip \
+            $(if $(call module-flags-have-rtti,$1),rtti) \
+            $(if $(call module-flags-have-exceptions,$1),exceptions) \
+        )) \
+    )\
+    $(call module-filter-out-compiler-flags,$1,-frtti -fno-rtti -fexceptions -fno-exceptions)\
+
+# Returns true if a module or its dependencies have specific C++ features
+# (i.e. RTTI or Exceptions)
+#
+# $1: module name
+# $2: list of features (e.g. 'rtti' or 'exceptions')
+#
+module-has-c++-features = $(strip \
+    $(eval __cxxdeps  := $(call module-get-all-dependencies,$1))\
+    $(eval __cxxflags := $(foreach __cxxdep,$(__cxxdeps),$(__ndk_modules.$(__cxxdep).CPP_FEATURES)))\
+    $(if $(filter $2,$(__cxxflags)),true,)\
+    )
+
+# Add standard C++ dependencies to a given module
+#
+# $1: module name
+# $2: list of C++ runtime static libraries (if any)
+# $3: list of C++ runtime shared libraries (if any)
+# $4: list of C++ runtime ldlibs (if any)
+#
+module-add-c++-deps = \
+    $(if $(call strip,$2),$(call ndk_log,Add dependency '$(call strip,$2)' to module '$1'))\
+    $(eval __ndk_modules.$1.STATIC_LIBRARIES += $(2))\
+    $(if $(call strip,$3),$(call ndk_log,Add dependency '$(call strip,$3)' to module '$1'))\
+    $(eval __ndk_modules.$1.SHARED_LIBRARIES += $(3))\
+    $(if $(call strip,$4),$(call ndk_log,Add dependency '$(call strip,$4)' to module '$1'))\
+    $(eval __ndk_modules.$1.LDLIBS += $(4))
+
+
+# =============================================================================
+#
+# Utility functions
+#
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# Function : pretty-dir
+# Arguments: 1: path
+# Returns  : Remove NDK_PROJECT_PATH prefix from a given path. This can be
+#            used to perform pretty-printing for logs.
+# -----------------------------------------------------------------------------
+pretty-dir = $(patsubst $(NDK_ROOT)/%,<NDK>/%,\
+                 $(patsubst $(NDK_PROJECT_PATH)/%,%,$1))
+
+# Note: NDK_PROJECT_PATH is typically defined after this test is run.
+-test-pretty-dir = \
+  $(eval NDK_PROJECT_PATH ?= .)\
+  $(call test-expect,foo,$(call pretty-dir,foo))\
+  $(call test-expect,foo,$(call pretty-dir,$(NDK_PROJECT_PATH)/foo))\
+  $(call test-expect,foo/bar,$(call pretty-dir,$(NDK_PROJECT_PATH)/foo/bar))\
+  $(call test-expect,<NDK>/foo,$(call pretty-dir,$(NDK_ROOT)/foo))\
+  $(call test-expect,<NDK>/foo/bar,$(call pretty-dir,$(NDK_ROOT)/foo/bar))
+
+# -----------------------------------------------------------------------------
+# Function : check-user-define
+# Arguments: 1: name of variable that must be defined by the user
+#            2: name of Makefile where the variable should be defined
+#            3: name/description of the Makefile where the check is done, which
+#               must be included by $2
+# Returns  : None
+# -----------------------------------------------------------------------------
+check-user-define = $(if $(strip $($1)),,\
+  $(call __ndk_error,Missing $1 before including $3 in $2))
+
+# -----------------------------------------------------------------------------
+# This is used to check that LOCAL_MODULE is properly defined by an Android.mk
+# file before including one of the $(BUILD_SHARED_LIBRARY), etc... files.
+#
+# Function : check-user-LOCAL_MODULE
+# Arguments: 1: name/description of the included build Makefile where the
+#               check is done
+# Returns  : None
+# Usage    : $(call check-user-LOCAL_MODULE, BUILD_SHARED_LIBRARY)
+# -----------------------------------------------------------------------------
+check-defined-LOCAL_MODULE = \
+  $(call check-user-define,LOCAL_MODULE,$(local-makefile),$(1)) \
+  $(if $(call seq,$(words $(LOCAL_MODULE)),1),,\
+    $(call __ndk_info,LOCAL_MODULE definition in $(local-makefile) must not contain space)\
+    $(call __ndk_error,Please correct error. Aborting)\
+  )
+
+# -----------------------------------------------------------------------------
+# This is used to check that LOCAL_MODULE_FILENAME, if defined, is correct.
+#
+# Function : check-user-LOCAL_MODULE_FILENAME
+# Returns  : None
+# Usage    : $(call check-user-LOCAL_MODULE_FILENAME)
+# -----------------------------------------------------------------------------
+check-LOCAL_MODULE_FILENAME = \
+  $(if $(strip $(LOCAL_MODULE_FILENAME)),\
+    $(if $(call seq,$(words $(LOCAL_MODULE_FILENAME)),1),,\
+        $(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain spaces)\
+        $(call __ndk_error,Plase correct error. Aborting)\
+    )\
+    $(if $(filter %$(TARGET_LIB_EXTENSION) %$(TARGET_SONAME_EXTENSION),$(LOCAL_MODULE_FILENAME)),\
+        $(call __ndk_info,$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_MODULE_FILENAME should not include file extensions)\
+    )\
+  )
+
+# -----------------------------------------------------------------------------
+# Function  : handle-module-filename
+# Arguments : 1: default file prefix
+#             2: file suffix
+# Returns   : None
+# Usage     : $(call handle-module-filename,<prefix>,<suffix>)
+# Rationale : To be used to check and or set the module's filename through
+#             the LOCAL_MODULE_FILENAME variable.
+# -----------------------------------------------------------------------------
+handle-module-filename = $(eval $(call ev-handle-module-filename,$1,$2))
+
+#
+# Check that LOCAL_MODULE_FILENAME is properly defined
+# - with one single item
+# - without a library file extension
+# - with no directory separators
+#
+define ev-check-module-filename
+ifneq (1,$$(words $$(LOCAL_MODULE_FILENAME)))
+    $$(call __ndk_info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain any space)
+    $$(call __ndk_error,Aborting)
+endif
+ifneq (,$$(filter %$$(TARGET_LIB_EXTENSION) %$$(TARGET_SONAME_EXTENSION),$$(LOCAL_MODULE_FILENAME)))
+    $$(call __ndk_info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain a file extension)
+    $$(call __ndk_error,Aborting)
+endif
+ifneq (1,$$(words $$(subst /, ,$$(LOCAL_MODULE_FILENAME))))
+    $$(call __ndk_info,$$(LOCAL_MAKEFILE):$$(LOCAL_MODULE): LOCAL_MODULE_FILENAME must not contain directory separators)
+    $$(call __ndk_error,Aborting)
+endif
+endef
+
+#
+# Check the definition of LOCAL_MODULE_FILENAME. If none exists,
+# infer it from the LOCAL_MODULE name.
+#
+# $1: default file prefix
+# $2: default file suffix
+#
+define ev-handle-module-filename
+LOCAL_MODULE_FILENAME := $$(strip $$(LOCAL_MODULE_FILENAME))
+ifndef LOCAL_MODULE_FILENAME
+    LOCAL_MODULE_FILENAME := $1$$(LOCAL_MODULE)
+endif
+$$(eval $$(call ev-check-module-filename))
+LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME)$2
+endef
+
+handle-prebuilt-module-filename = $(eval $(call ev-handle-prebuilt-module-filename,$1))
+
+#
+# Check the definition of LOCAL_MODULE_FILENAME for a _prebuilt_ module.
+# If none exists, infer it from $(LOCAL_SRC_FILES)
+#
+# $1: default file suffix
+#
+define ev-handle-prebuilt-module-filename
+LOCAL_MODULE_FILENAME := $$(strip $$(LOCAL_MODULE_FILENAME))
+ifndef LOCAL_MODULE_FILENAME
+    LOCAL_MODULE_FILENAME := $$(notdir $(LOCAL_SRC_FILES))
+    LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME:%$$(TARGET_LIB_EXTENSION)=%)
+    LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME:%$$(TARGET_SONAME_EXTENSION)=%)
+endif
+LOCAL_MODULE_FILENAME := $$(LOCAL_MODULE_FILENAME)$1
+$$(eval $$(call ev-check-module-filename))
+endef
+
+
+# -----------------------------------------------------------------------------
+# Function  : handle-module-built
+# Returns   : None
+# Usage     : $(call handle-module-built)
+# Rationale : To be used to automatically compute the location of the generated
+#             binary file, and the directory where to place its object files.
+# -----------------------------------------------------------------------------
+handle-module-built = \
+    $(eval LOCAL_BUILT_MODULE := $(TARGET_OUT)/$(LOCAL_MODULE_FILENAME))\
+    $(eval LOCAL_OBJS_DIR     := $(TARGET_OBJS)/$(LOCAL_MODULE))
+
+# -----------------------------------------------------------------------------
+# Compute the real path of a prebuilt file.
+#
+# Function : local-prebuilt-path
+# Arguments: 1: prebuilt path (as listed in $(LOCAL_SRC_FILES))
+# Returns  : full path. If $1 begins with a /, the path is considered
+#            absolute and returned as-is. Otherwise, $(LOCAL_PATH)/$1 is
+#            returned instead.
+# Usage    : $(call local-prebuilt-path,$(LOCAL_SRC_FILES))
+# -----------------------------------------------------------------------------
+local-prebuilt-path = $(call local-source-file-path,$1)
+
+# -----------------------------------------------------------------------------
+# This is used to strip any lib prefix from LOCAL_MODULE, then check that
+# the corresponding module name is not already defined.
+#
+# Function : check-user-LOCAL_MODULE
+# Arguments: 1: path of Android.mk where this LOCAL_MODULE is defined
+# Returns  : None
+# Usage    : $(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+# -----------------------------------------------------------------------------
+check-LOCAL_MODULE = \
+  $(eval LOCAL_MODULE := $$(call strip-lib-prefix,$$(LOCAL_MODULE)))
+
+# -----------------------------------------------------------------------------
+# Macro    : my-dir
+# Returns  : the directory of the current Makefile
+# Usage    : $(my-dir)
+# -----------------------------------------------------------------------------
+my-dir = $(call parent-dir,$(lastword $(MAKEFILE_LIST)))
+
+# -----------------------------------------------------------------------------
+# Function : all-makefiles-under
+# Arguments: 1: directory path
+# Returns  : a list of all makefiles immediately below some directory
+# Usage    : $(call all-makefiles-under, <some path>)
+# -----------------------------------------------------------------------------
+all-makefiles-under = $(wildcard $1/*/Android.mk)
+
+# -----------------------------------------------------------------------------
+# Macro    : all-subdir-makefiles
+# Returns  : list of all makefiles in subdirectories of the current Makefile's
+#            location
+# Usage    : $(all-subdir-makefiles)
+# -----------------------------------------------------------------------------
+all-subdir-makefiles = $(call all-makefiles-under,$(call my-dir))
+
+# =============================================================================
+#
+# Source file tagging support.
+#
+# Each source file listed in LOCAL_SRC_FILES can have any number of
+# 'tags' associated to it. A tag name must not contain space, and its
+# usage can vary.
+#
+# For example, the 'debug' tag is used to sources that must be built
+# in debug mode, the 'arm' tag is used for sources that must be built
+# using the 32-bit instruction set on ARM platforms, and 'neon' is used
+# for sources that must be built with ARM Advanced SIMD (a.k.a. NEON)
+# support.
+#
+# More tags might be introduced in the future.
+#
+#  LOCAL_SRC_TAGS contains the list of all tags used (initially empty)
+#  LOCAL_SRC_FILES contains the list of all source files.
+#  LOCAL_SRC_TAG.<tagname> contains the set of source file names tagged
+#      with <tagname>
+#  LOCAL_SRC_FILES_TAGS.<filename> contains the set of tags for a given
+#      source file name
+#
+# Tags are processed by a toolchain-specific function (e.g. TARGET-compute-cflags)
+# which will call various functions to compute source-file specific settings.
+# These are currently stored as:
+#
+#  LOCAL_SRC_FILES_TARGET_CFLAGS.<filename> contains the list of
+#      target-specific C compiler flags used to compile a given
+#      source file. This is set by the function TARGET-set-cflags
+#      defined in the toolchain's setup.mk script.
+#
+#  LOCAL_SRC_FILES_TEXT.<filename> contains the 'text' that will be
+#      displayed along the label of the build output line. For example
+#      'thumb' or 'arm  ' with ARM-based toolchains.
+#
+# =============================================================================
+
+# -----------------------------------------------------------------------------
+# Macro    : escape-colon-in-path
+# Returns  : replace colon in $1 with $(colon)
+# Usage    : $(escape-colon-in-path,<file>)
+# -----------------------------------------------------------------------------
+escape-colon-in-path = $(subst $(colon),$$(colon),$1)
+
+# -----------------------------------------------------------------------------
+# Macro    : clear-all-src-tags
+# Returns  : remove all source file tags and associated data.
+# Usage    : $(clear-all-src-tags)
+# -----------------------------------------------------------------------------
+clear-all-src-tags = \
+$(foreach __tag,$(LOCAL_SRC_TAGS), \
+    $(eval LOCAL_SRC_TAG.$(__tag) := $(empty)) \
+) \
+$(foreach __src,$(LOCAL_SRC_FILES), \
+    $(eval LOCAL_SRC_FILES_TAGS.$(call escape-colon-in-path,$(__src)) := $(empty)) \
+    $(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(call escape-colon-in-path,$(__src)) := $(empty)) \
+    $(eval LOCAL_SRC_FILES_TEXT.$(call escape-colon-in-path,$(__src)) := $(empty)) \
+) \
+$(eval LOCAL_SRC_TAGS := $(empty_set))
+
+# -----------------------------------------------------------------------------
+# Macro    : tag-src-files
+# Arguments: 1: list of source files to tag
+#            2: tag name (must not contain space)
+# Usage    : $(call tag-src-files,<list-of-source-files>,<tagname>)
+# Rationale: Add a tag to a list of source files
+# -----------------------------------------------------------------------------
+tag-src-files = \
+$(eval LOCAL_SRC_TAGS := $(call set_insert,$2,$(LOCAL_SRC_TAGS))) \
+$(eval LOCAL_SRC_TAG.$2 := $(call set_union,$1,$(LOCAL_SRC_TAG.$2))) \
+$(foreach __src,$1, \
+    $(eval LOCAL_SRC_FILES_TAGS.$(call escape-colon-in-path,$(__src)) += $2) \
+)
+
+# -----------------------------------------------------------------------------
+# Macro    : get-src-files-with-tag
+# Arguments: 1: tag name
+# Usage    : $(call get-src-files-with-tag,<tagname>)
+# Return   : The list of source file names that have been tagged with <tagname>
+# -----------------------------------------------------------------------------
+get-src-files-with-tag = $(LOCAL_SRC_TAG.$1)
+
+# -----------------------------------------------------------------------------
+# Macro    : get-src-files-without-tag
+# Arguments: 1: tag name
+# Usage    : $(call get-src-files-without-tag,<tagname>)
+# Return   : The list of source file names that have NOT been tagged with <tagname>
+# -----------------------------------------------------------------------------
+get-src-files-without-tag = $(filter-out $(LOCAL_SRC_TAG.$1),$(LOCAL_SRC_FILES))
+
+# -----------------------------------------------------------------------------
+# Macro    : set-src-files-target-cflags
+# Arguments: 1: list of source files
+#            2: list of compiler flags
+# Usage    : $(call set-src-files-target-cflags,<sources>,<flags>)
+# Rationale: Set or replace the set of compiler flags that will be applied
+#            when building a given set of source files. This function should
+#            normally be called from the toolchain-specific function that
+#            computes all compiler flags for all source files.
+# -----------------------------------------------------------------------------
+set-src-files-target-cflags = \
+    $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(call escape-colon-in-path,$(__src)) := $2))
+
+# -----------------------------------------------------------------------------
+# Macro    : add-src-files-target-cflags
+# Arguments: 1: list of source files
+#            2: list of compiler flags
+# Usage    : $(call add-src-files-target-cflags,<sources>,<flags>)
+# Rationale: A variant of set-src-files-target-cflags that can be used
+#            to append, instead of replace, compiler flags for specific
+#            source files.
+# -----------------------------------------------------------------------------
+add-src-files-target-cflags = \
+    $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TARGET_CFLAGS.$(call escape-colon-in-path,$(__src)) += $2))
+
+# -----------------------------------------------------------------------------
+# Macro    : get-src-file-target-cflags
+# Arguments: 1: single source file name
+# Usage    : $(call get-src-file-target-cflags,<source>)
+# Rationale: Return the set of target-specific compiler flags that must be
+#            applied to a given source file. These must be set prior to this
+#            call using set-src-files-target-cflags or add-src-files-target-cflags
+# -----------------------------------------------------------------------------
+get-src-file-target-cflags = $(LOCAL_SRC_FILES_TARGET_CFLAGS.$1)
+
+# -----------------------------------------------------------------------------
+# Macro    : set-src-files-text
+# Arguments: 1: list of source files
+#            2: text
+# Usage    : $(call set-src-files-text,<sources>,<text>)
+# Rationale: Set or replace the 'text' associated to a set of source files.
+#            The text is a very short string that complements the build
+#            label. For example, it will be either 'thumb' or 'arm  ' for
+#            ARM-based toolchains. This function must be called by the
+#            toolchain-specific functions that processes all source files.
+# -----------------------------------------------------------------------------
+set-src-files-text = \
+    $(foreach __src,$1,$(eval LOCAL_SRC_FILES_TEXT.$(call escape-colon-in-path,$(__src)) := $2))
+
+# -----------------------------------------------------------------------------
+# Macro    : get-src-file-text
+# Arguments: 1: single source file
+# Usage    : $(call get-src-file-text,<source>)
+# Rationale: Return the 'text' associated to a given source file when
+#            set-src-files-text was called.
+# -----------------------------------------------------------------------------
+get-src-file-text = $(LOCAL_SRC_FILES_TEXT.$1)
+
+# This should only be called for debugging the source files tagging system
+dump-src-file-tags = \
+$(info LOCAL_SRC_TAGS := $(LOCAL_SRC_TAGS)) \
+$(info LOCAL_SRC_FILES = $(LOCAL_SRC_FILES)) \
+$(foreach __tag,$(LOCAL_SRC_TAGS),$(info LOCAL_SRC_TAG.$(__tag) = $(LOCAL_SRC_TAG.$(__tag)))) \
+$(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TAGS.$(__src) = $(LOCAL_SRC_FILES_TAGS.$(__src)))) \
+$(info WITH arm = $(call get-src-files-with-tag,arm)) \
+$(info WITHOUT arm = $(call get-src-files-without-tag,arm)) \
+$(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src) = $(LOCAL_SRC_FILES_TARGET_CFLAGS.$(__src)))) \
+$(foreach __src,$(LOCAL_SRC_FILES),$(info LOCAL_SRC_FILES_TEXT.$(__src) = $(LOCAL_SRC_FILES_TEXT.$(__src)))) \
+
+
+# =============================================================================
+#
+# Application.mk support
+#
+# =============================================================================
+
+# the list of variables that *must* be defined in Application.mk files
+NDK_APP_VARS_REQUIRED :=
+
+# the list of variables that *may* be defined in Application.mk files
+NDK_APP_VARS_OPTIONAL := \
+    APP_ABI \
+    APP_ASFLAGS \
+    APP_ASMFLAGS \
+    APP_BUILD_SCRIPT \
+    APP_CFLAGS \
+    APP_CONLYFLAGS \
+    APP_CPPFLAGS \
+    APP_CXXFLAGS \
+    APP_LDFLAGS \
+    APP_MODULES \
+    APP_OPTIM \
+    APP_PIE \
+    APP_PLATFORM \
+    APP_PROJECT_PATH \
+    APP_SHORT_COMMANDS \
+    APP_STL \
+    APP_THIN_ARCHIVE \
+    APP_WRAP_SH \
+
+# NDK_ALL_ABIS is not configured yet.
+NDK_APP_VARS_OPTIONAL += \
+    APP_WRAP_SH_armeabi-v7a \
+    APP_WRAP_SH_arm64-v8a \
+    APP_WRAP_SH_x86 \
+    APP_WRAP_SH_x86_64 \
+
+# the list of all variables that may appear in an Application.mk file
+# or defined by the build scripts.
+NDK_APP_VARS := \
+    $(NDK_APP_VARS_REQUIRED) \
+    $(NDK_APP_VARS_OPTIONAL) \
+    APP_DEBUG \
+    APP_DEBUGGABLE \
+    APP_MANIFEST \
+
+# =============================================================================
+#
+# Android.mk support
+#
+# =============================================================================
+
+# =============================================================================
+#
+# Build commands support
+#
+# =============================================================================
+
+get-object-name = $(strip \
+    $(subst ../,__/,\
+      $(subst :,_,\
+        $(eval __obj := $1)\
+        $(foreach __ext,.c .s .S .asm $(LOCAL_CPP_EXTENSION) $(LOCAL_RS_EXTENSION),\
+            $(eval __obj := $(__obj:%$(__ext)=%$(TARGET_OBJ_EXTENSION)))\
+        )\
+        $(__obj)\
+    )))
+
+-test-get-object-name = \
+  $(eval TARGET_OBJ_EXTENSION=.o)\
+  $(eval LOCAL_CPP_EXTENSION ?= .cpp)\
+  $(eval LOCAL_RS_EXTENSION ?= .rs)\
+  $(call test-expect,foo.o,$(call get-object-name,foo.c))\
+  $(call test-expect,bar.o,$(call get-object-name,bar.s))\
+  $(call test-expect,zoo.o,$(call get-object-name,zoo.S))\
+  $(call test-expect,tot.o,$(call get-object-name,tot.cpp))\
+  $(call test-expect,RS.o,$(call get-object-name,RS.rs))\
+  $(call test-expect,goo.o,$(call get-object-name,goo.asm))
+
+get-rs-scriptc-name = $(strip \
+    $(subst ../,__/,\
+      $(subst :,_,\
+        $(eval __obj := $1)\
+        $(foreach __ext,$(LOCAL_RS_EXTENSION),\
+            $(eval __obj := $(__obj:%$(__ext)=%.cpp))\
+        )\
+        $(dir $(__obj))ScriptC_$(notdir $(__obj))\
+    )))
+
+get-rs-bc-name = $(strip \
+    $(subst ../,__/,\
+      $(subst :,_,\
+        $(eval __obj := $1)\
+        $(foreach __ext,$(LOCAL_RS_EXTENSION),\
+            $(eval __obj := $(__obj:%$(__ext)=%.bc))\
+        )\
+        $(__obj)\
+    )))
+
+get-rs-so-name = $(strip \
+    $(subst ../,__/,\
+      $(subst :,_,\
+        $(eval __obj := $1)\
+        $(foreach __ext,$(LOCAL_RS_EXTENSION),\
+            $(eval __obj := $(__obj:%$(__ext)=%$(TARGET_SONAME_EXTENSION)))\
+        )\
+        $(notdir $(__obj))\
+    )))
+
+# -----------------------------------------------------------------------------
+# Macro    : hide
+# Returns  : nothing
+# Usage    : $(hide)<make commands>
+# Rationale: To be used as a prefix for Make build commands to hide them
+#            by default during the build. To show them, set V=1 in your
+#            environment or command-line.
+#
+#            For example:
+#
+#                foo.o: foo.c
+#                -->|$(hide) <build-commands>
+#
+#            Where '-->|' stands for a single tab character.
+#
+# -----------------------------------------------------------------------------
+ifeq ($(V),1)
+hide = $(empty)
+else
+hide = @
+endif
+
+
+# -----------------------------------------------------------------------------
+# Function  : local-source-file-path
+# Parameters: $1: source file (as listed in LOCAL_SRC_FILES)
+# Returns   : full source file path of $1
+# Usage     : $(call local-source-file-path,$1)
+# Rationale : Used to compute the full path of a source listed in
+#             LOCAL_SRC_FILES. If it is an absolute path, then this
+#             returns the input, otherwise, prepends $(LOCAL_PATH)/
+#             to the result.
+# -----------------------------------------------------------------------------
+local-source-file-path = $(if $(call host-path-is-absolute,$1),$1,$(LOCAL_PATH)/$1)
+
+# This assumes that many variables have been pre-defined:
+# _SRC: source file
+# _OBJ: destination file
+# _CC: 'compiler' command
+# _FLAGS: 'compiler' flags
+# _TEXT: Display text (e.g. "Compile++ thumb", must be EXACTLY 15 chars long)
+#
+define ev-build-file
+$$(_OBJ): PRIVATE_ABI      := $$(TARGET_ARCH_ABI)
+$$(_OBJ): PRIVATE_SRC      := $$(_SRC)
+$$(_OBJ): PRIVATE_OBJ      := $$(_OBJ)
+$$(_OBJ): PRIVATE_DEPS     := $$(call host-path,$$(_OBJ).d)
+$$(_OBJ): PRIVATE_MODULE   := $$(LOCAL_MODULE)
+$$(_OBJ): PRIVATE_TEXT     := $$(_TEXT)
+$$(_OBJ): PRIVATE_CC       := $$(_CC)
+$$(_OBJ): PRIVATE_CFLAGS   := $$(_FLAGS)
+
+ifeq ($$(LOCAL_SHORT_COMMANDS),true)
+_OPTIONS_LISTFILE := $$(_OBJ).cflags
+$$(_OBJ): $$(call generate-list-file,$$(_FLAGS),$$(_OPTIONS_LISTFILE))
+$$(_OBJ): PRIVATE_CFLAGS := @$$(call host-path,$$(_OPTIONS_LISTFILE))
+$$(_OBJ): $$(_OPTIONS_LISTFILE)
+endif
+
+$$(call generate-file-dir,$$(_OBJ))
+$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) $(LOCAL_RS_OBJECTS)
+	$$(call host-echo-build-step,$$(PRIVATE_ABI),$$(PRIVATE_TEXT)) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))"
+	$$(hide) $$(PRIVATE_CC) -MMD -MP -MF $$(PRIVATE_DEPS) $$(PRIVATE_CFLAGS) $$(call host-path,$$(PRIVATE_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ))
+endef
+
+
+# For renderscript: slightly different from the above ev-build-file
+# _RS_SRC: RS source file
+# _CPP_SRC: ScriptC_RS.cpp source file
+# _BC_SRC: Bitcode source file
+# _BC_SO: Bitcode SO name, no path
+# _OBJ: destination file
+# _RS_CC: 'compiler' command for _RS_SRC
+# _RS_BCC: 'compiler' command for _BC_SRC
+# _CXX: 'compiler' command for _CPP_SRC
+# _RS_FLAGS: 'compiler' flags for _RS_SRC
+# _CPP_FLAGS: 'compiler' flags for _CPP_SRC
+# _LD_FLAGS: 'compiler' flags for linking
+# _TEXT: Display text (e.g. "Compile RS")
+# _OUT: output dir
+# _COMPAT: 'true' if bcc_compat is required
+#
+define ev-build-rs-file
+$$(_OBJ): PRIVATE_ABI       := $$(TARGET_ARCH_ABI)
+$$(_OBJ): PRIVATE_RS_SRC    := $$(_RS_SRC)
+$$(_OBJ): PRIVATE_CPP_SRC   := $$(_CPP_SRC)
+$$(_OBJ): PRIVATE_BC_SRC    := $$(_BC_SRC)
+$$(_OBJ): PRIVATE_OBJ       := $$(_OBJ)
+$$(_OBJ): PRIVATE_BC_OBJ    := $$(_BC_SRC)$(TARGET_OBJ_EXTENSION)
+$$(_OBJ): PRIVATE_BC_SO     := $$(_BC_SO)
+$$(_OBJ): PRIVATE_DEPS      := $$(call host-path,$$(_OBJ).d)
+$$(_OBJ): PRIVATE_MODULE    := $$(LOCAL_MODULE)
+$$(_OBJ): PRIVATE_TEXT      := $$(_TEXT)
+$$(_OBJ): PRIVATE_RS_CC     := $$(_RS_CC)
+$$(_OBJ): PRIVATE_RS_BCC    := $$(_RS_BCC)
+$$(_OBJ): PRIVATE_CXX       := $$(_CXX)
+$$(_OBJ): PRIVATE_RS_FLAGS  := $$(_RS_FLAGS)
+$$(_OBJ): PRIVATE_CPPFLAGS  := $$(_CPP_FLAGS)
+$$(_OBJ): PRIVATE_LD        := $$(TARGET_LD)
+$$(_OBJ): PRIVATE_LDFLAGS   := $$(_LD_FLAGS)
+$$(_OBJ): PRIVATE_OUT       := $$(TARGET_OUT)
+$$(_OBJ): PRIVATE_RS_TRIPLE := $$(RS_TRIPLE)
+$$(_OBJ): PRIVATE_COMPAT    := $$(_COMPAT)
+$$(_OBJ): PRIVATE_LIB_PATH  := $$(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/platform/$(TARGET_ARCH)
+
+ifeq ($$(LOCAL_SHORT_COMMANDS),true)
+_OPTIONS_LISTFILE := $$(_OBJ).cflags
+$$(_OBJ): $$(call generate-list-file,$$(_CPP_FLAGS),$$(_OPTIONS_LISTFILE))
+$$(_OBJ): PRIVATE_CPPFLAGS := @$$(call host-path,$$(_OPTIONS_LISTFILE))
+$$(_OBJ): $$(_OPTIONS_LISTFILE)
+endif
+
+# x86_64 & mips64 has both lib/ and lib64/, use lib64 for 64bit RenderScript compilation.
+ifneq ($(filter x86_64 mips64,$(TARGET_ARCH_ABI)),)
+$$(_OBJ): PRIVATE_SYS_PATH := $$(call host-path,$(SYSROOT_LINK)/usr/lib64)
+else
+$$(_OBJ): PRIVATE_SYS_PATH := $$(call host-path,$(SYSROOT_LINK)/usr/lib)
+endif
+
+# llvm-rc-cc.exe has problem accepting input *.rs with path. To workaround:
+# cd ($dir $(_SRC)) ; llvm-rs-cc $(notdir $(_SRC)) -o ...full-path...
+#
+ifeq ($$(_COMPAT),true)
+	# In COMPAT mode, use LD instead of CXX to bypass the gradle check for their book-keeping of native libs.
+	# And this is what we do with SDK.
+	# TODO: We could use CXX after gradle can correctly handle librs.*.so.
+$$(_OBJ): $$(_RS_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK)
+	$$(call host-echo-build-step,$$(PRIVATE_ABI),$$(PRIVATE_TEXT)) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_RS_SRC))"
+	$$(hide) \
+	cd $$(call host-path,$$(dir $$(PRIVATE_RS_SRC))) && $$(PRIVATE_RS_CC) -o $$(call host-path,$$(abspath $$(dir $$(PRIVATE_OBJ))))/ -d $$(abspath $$(call host-path,$$(dir $$(PRIVATE_OBJ)))) -MD -reflect-c++ -target-api $(strip $(subst android-,,$(APP_PLATFORM))) $$(PRIVATE_RS_FLAGS) $$(notdir $$(PRIVATE_RS_SRC))
+	$$(hide) \
+	$$(PRIVATE_RS_BCC) -O3 -o $$(call host-path,$$(PRIVATE_BC_OBJ)) -fPIC -shared -rt-path $$(PRIVATE_LIB_PATH)/librsrt.bc -mtriple $$(PRIVATE_RS_TRIPLE) $$(call host-path,$$(PRIVATE_BC_SRC)) && \
+	$$(PRIVATE_LD) -shared -Bsymbolic -z noexecstack -z relro -z now -nostdlib $$(call host-path,$$(PRIVATE_BC_OBJ)) $$(PRIVATE_LIB_PATH)/libcompiler_rt.a -o $$(call host-path,$$(PRIVATE_OUT)/librs.$$(PRIVATE_BC_SO)) -L $$(PRIVATE_SYS_PATH) -L $$(PRIVATE_LIB_PATH) -lRSSupport -lm -lc && \
+	$$(PRIVATE_CXX) -MMD -MP -MF $$(PRIVATE_DEPS) $$(PRIVATE_CPPFLAGS) $$(call host-path,$$(PRIVATE_CPP_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ))
+else
+$$(_OBJ): $$(_RS_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK)
+	$$(call host-echo-build-step,$$(PRIVATE_ABI),$$(PRIVATE_TEXT)) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_RS_SRC))"
+	$$(hide) \
+	cd $$(call host-path,$$(dir $$(PRIVATE_RS_SRC))) && $$(PRIVATE_RS_CC) -o $$(call host-path,$$(abspath $$(dir $$(PRIVATE_OBJ))))/ -d $$(abspath $$(call host-path,$$(dir $$(PRIVATE_OBJ)))) -MD -reflect-c++ -target-api $(strip $(subst android-,,$(APP_PLATFORM))) $$(PRIVATE_RS_FLAGS) $$(notdir $$(PRIVATE_RS_SRC))
+	$$(hide) \
+	$$(PRIVATE_CXX) -MMD -MP -MF $$(PRIVATE_DEPS) $$(PRIVATE_CPPFLAGS) $$(call host-path,$$(PRIVATE_CPP_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ))
+endif
+endef
+
+# This assumes the same things than ev-build-file, but will handle
+# the definition of LOCAL_FILTER_ASM as well.
+define ev-build-source-file
+LOCAL_DEPENDENCY_DIRS += $$(dir $$(_OBJ))
+ifndef LOCAL_FILTER_ASM
+  # Trivial case: Directly generate an object file
+  $$(eval $$(call ev-build-file))
+else
+  # This is where things get hairy, we first transform
+  # the source into an assembler file, send it to the
+  # filter, then generate a final object file from it.
+  #
+
+  # First, remember the original settings and compute
+  # the location of our temporary files.
+  #
+  _ORG_SRC := $$(_SRC)
+  _ORG_OBJ := $$(_OBJ)
+  _ORG_FLAGS := $$(_FLAGS)
+  _ORG_TEXT  := $$(_TEXT)
+
+  _OBJ_ASM_ORIGINAL := $$(patsubst %$$(TARGET_OBJ_EXTENSION),%.s,$$(_ORG_OBJ))
+  _OBJ_ASM_FILTERED := $$(patsubst %$$(TARGET_OBJ_EXTENSION),%.filtered.s,$$(_ORG_OBJ))
+
+  # If the source file is a plain assembler file, we're going to
+  # use it directly in our filter.
+  ifneq (,$$(filter %.s,$$(_SRC)))
+    _OBJ_ASM_ORIGINAL := $$(_SRC)
+  endif
+
+  #$$(info SRC=$$(_SRC) OBJ=$$(_OBJ) OBJ_ORIGINAL=$$(_OBJ_ASM_ORIGINAL) OBJ_FILTERED=$$(_OBJ_ASM_FILTERED))
+
+  # We need to transform the source into an assembly file, instead of
+  # an object. The proper way to do that depends on the file extension.
+  #
+  # For C and C++ source files, simply replace the -c by an -S in the
+  # compilation command (this forces the compiler to generate an
+  # assembly file).
+  #
+  # For assembler templates (which end in .S), replace the -c with -E
+  # to send it to the preprocessor instead.
+  #
+  # Don't do anything for plain assembly files (which end in .s)
+  #
+  ifeq (,$$(filter %.s,$$(_SRC)))
+    _OBJ   := $$(_OBJ_ASM_ORIGINAL)
+    ifneq (,$$(filter %.S,$$(_SRC)))
+      _FLAGS := $$(patsubst -c,-E,$$(_ORG_FLAGS))
+    else
+      _FLAGS := $$(patsubst -c,-S,$$(_ORG_FLAGS))
+    endif
+    $$(eval $$(call ev-build-file))
+  endif
+
+  # Next, process the assembly file with the filter
+  $$(_OBJ_ASM_FILTERED): PRIVATE_ABI    := $$(TARGET_ARCH_ABI)
+  $$(_OBJ_ASM_FILTERED): PRIVATE_SRC    := $$(_OBJ_ASM_ORIGINAL)
+  $$(_OBJ_ASM_FILTERED): PRIVATE_DST    := $$(_OBJ_ASM_FILTERED)
+  $$(_OBJ_ASM_FILTERED): PRIVATE_FILTER := $$(LOCAL_FILTER_ASM)
+  $$(_OBJ_ASM_FILTERED): PRIVATE_MODULE := $$(LOCAL_MODULE)
+  $$(_OBJ_ASM_FILTERED): $$(_OBJ_ASM_ORIGINAL)
+	$$(call host-echo-build-step,$$(PRIVATE_ABI),AsmFilter) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))"
+	$$(hide) $$(PRIVATE_FILTER) $$(PRIVATE_SRC) $$(PRIVATE_DST)
+
+  # Then, generate the final object, we need to keep assembler-specific
+  # flags which look like -Wa,<option>:
+  _SRC   := $$(_OBJ_ASM_FILTERED)
+  _OBJ   := $$(_ORG_OBJ)
+  _FLAGS := $$(filter -Wa%,$$(_ORG_FLAGS)) -c
+  _TEXT  := Assembly
+  $$(eval $$(call ev-build-file))
+endif
+endef
+
+# -----------------------------------------------------------------------------
+# Template  : ev-compile-c-source
+# Arguments : 1: single C source file name (relative to LOCAL_PATH)
+#             2: target object file (without path)
+# Returns   : None
+# Usage     : $(eval $(call ev-compile-c-source,<srcfile>,<objfile>)
+# Rationale : Internal template evaluated by compile-c-source and
+#             compile-s-source
+# -----------------------------------------------------------------------------
+define  ev-compile-c-source
+_SRC:=$$(call local-source-file-path,$(1))
+_OBJ:=$$(LOCAL_OBJS_DIR:%/=%)/$(2)
+
+_FLAGS := $$($$(my)CFLAGS) \
+          $$(call get-src-file-target-cflags,$(1)) \
+          $$(call host-c-includes,$$(LOCAL_C_INCLUDES) $$(LOCAL_PATH)) \
+          $$(NDK_APP_CFLAGS) \
+          $$(NDK_APP_CONLYFLAGS) \
+          $$(LOCAL_CFLAGS) \
+          $$(LOCAL_CONLYFLAGS) \
+          --sysroot $$(call host-path,$$(SYSROOT_INC)) \
+          $(SYSROOT_ARCH_INC_ARG) \
+          -c \
+
+_TEXT := Compile $$(call get-src-file-text,$1)
+_CC   := $$(NDK_CCACHE) $$(TARGET_CC)
+
+$$(eval $$(call ev-build-source-file))
+endef
+
+# -----------------------------------------------------------------------------
+# Template  : ev-compile-s-source
+# Arguments : 1: single .S source file name (relative to LOCAL_PATH)
+#             2: target object file (without path)
+# Returns   : None
+# Usage     : $(eval $(call ev-compile-s-source,<srcfile>,<objfile>)
+# -----------------------------------------------------------------------------
+define  ev-compile-s-source
+_SRC:=$$(call local-source-file-path,$(1))
+_OBJ:=$$(LOCAL_OBJS_DIR:%/=%)/$(2)
+
+_FLAGS := $$($$(my)CFLAGS) \
+          $$(call get-src-file-target-cflags,$(1)) \
+          $$(call host-c-includes,$$(LOCAL_C_INCLUDES) $$(LOCAL_PATH)) \
+          $$(NDK_APP_CFLAGS) \
+          $$(NDK_APP_ASFLAGS) \
+          $$(LOCAL_CFLAGS) \
+          $$(LOCAL_ASFLAGS) \
+          --sysroot $$(call host-path,$$(SYSROOT_INC)) \
+          $(SYSROOT_ARCH_INC_ARG) \
+          -c \
+
+_TEXT := Compile $$(call get-src-file-text,$1)
+_CC   := $$(NDK_CCACHE) $$(TARGET_CC)
+
+$$(eval $$(call ev-build-source-file))
+endef
+
+# -----------------------------------------------------------------------------
+# Template  : ev-compile-asm-source
+# Arguments : 1: single ASM source file name (relative to LOCAL_PATH)
+#             2: target object file (without path)
+# Returns   : None
+# Usage     : $(eval $(call ev-compile-asm-source,<srcfile>,<objfile>)
+# Rationale : Internal template evaluated by compile-asm-source
+# -----------------------------------------------------------------------------
+define  ev-compile-asm-source
+_SRC:=$$(call local-source-file-path,$(1))
+_OBJ:=$$(LOCAL_OBJS_DIR:%/=%)/$(2)
+
+_FLAGS := $$(call host-c-includes,$$(LOCAL_C_INCLUDES) $$(LOCAL_PATH)) \
+          $$(LOCAL_ASMFLAGS) \
+          $$(NDK_APP_ASMFLAGS) \
+          -I $$(call host-path,$$(SYSROOT_INC)/usr/include) \
+          $(subst -isystem,-I,$(SYSROOT_ARCH_INC_ARG)) \
+          $$(if $$(filter x86_64, $$(TARGET_ARCH_ABI)), -f elf64, -f elf32 -m x86)
+
+_TEXT := Assemble $$(call get-src-file-text,$1)
+_CC   := $$(NDK_CCACHE) $$(TARGET_ASM)
+
+$$(_OBJ): PRIVATE_ABI      := $$(TARGET_ARCH_ABI)
+$$(_OBJ): PRIVATE_SRC      := $$(_SRC)
+$$(_OBJ): PRIVATE_OBJ      := $$(_OBJ)
+$$(_OBJ): PRIVATE_MODULE   := $$(LOCAL_MODULE)
+$$(_OBJ): PRIVATE_TEXT     := $$(_TEXT)
+$$(_OBJ): PRIVATE_CC       := $$(_CC)
+$$(_OBJ): PRIVATE_CFLAGS   := $$(_FLAGS)
+
+ifeq ($$(LOCAL_SHORT_COMMANDS),true)
+_OPTIONS_LISTFILE := $$(_OBJ).cflags
+$$(_OBJ): $$(call generate-list-file,$$(_FLAGS),$$(_OPTIONS_LISTFILE))
+$$(_OBJ): PRIVATE_CFLAGS := @$$(call host-path,$$(_OPTIONS_LISTFILE))
+$$(_OBJ): $$(_OPTIONS_LISTFILE)
+endif
+
+$$(call generate-file-dir,$$(_OBJ))
+$$(_OBJ): $$(_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) $(LOCAL_RS_OBJECTS)
+	$$(call host-echo-build-step,$$(PRIVATE_ABI),$$(PRIVATE_TEXT)) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))"
+	$$(hide) $$(PRIVATE_CC) $$(PRIVATE_CFLAGS) $$(call host-path,$$(PRIVATE_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ))
+endef
+
+# -----------------------------------------------------------------------------
+# Function  : compile-c-source
+# Arguments : 1: single C source file name (relative to LOCAL_PATH)
+#             2: object file
+# Returns   : None
+# Usage     : $(call compile-c-source,<srcfile>,<objfile>)
+# Rationale : Setup everything required to build a single C source file
+# -----------------------------------------------------------------------------
+compile-c-source = $(eval $(call ev-compile-c-source,$1,$2))
+
+# -----------------------------------------------------------------------------
+# Function  : compile-s-source
+# Arguments : 1: single Assembly source file name (relative to LOCAL_PATH)
+#             2: object file
+# Returns   : None
+# Usage     : $(call compile-s-source,<srcfile>,<objfile>)
+# Rationale : Setup everything required to build a single Assembly source file
+# -----------------------------------------------------------------------------
+compile-s-source = $(eval $(call ev-compile-s-source,$1,$2))
+
+# -----------------------------------------------------------------------------
+# Function  : compile-asm-source
+# Arguments : 1: single Assembly source file name (relative to LOCAL_PATH)
+#             2: object file
+# Returns   : None
+# Usage     : $(call compile-asm-source,<srcfile>,<objfile>)
+# Rationale : Setup everything required to build a single Assembly source file
+# -----------------------------------------------------------------------------
+compile-asm-source = $(eval $(call ev-compile-asm-source,$1,$2))
+
+# -----------------------------------------------------------------------------
+# Template  : ev-compile-cpp-source
+# Arguments : 1: single C++ source file name (relative to LOCAL_PATH)
+#             2: target object file (without path)
+# Returns   : None
+# Usage     : $(eval $(call ev-compile-cpp-source,<srcfile>,<objfile>)
+# Rationale : Internal template evaluated by compile-cpp-source
+# -----------------------------------------------------------------------------
+
+define  ev-compile-cpp-source
+_SRC:=$$(call local-source-file-path,$(1))
+_OBJ:=$$(LOCAL_OBJS_DIR:%/=%)/$(2)
+_FLAGS := $$($$(my)CXXFLAGS) \
+          $$(call get-src-file-target-cflags,$(1)) \
+          $$(call host-c-includes, $$(LOCAL_C_INCLUDES) $$(LOCAL_PATH)) \
+          $(STL_DEFAULT_STD_VERSION) \
+          $$(NDK_APP_CFLAGS) \
+          $$(NDK_APP_CPPFLAGS) \
+          $$(NDK_APP_CXXFLAGS) \
+          $$(LOCAL_CFLAGS) \
+          $$(LOCAL_CPPFLAGS) \
+          $$(LOCAL_CXXFLAGS) \
+          --sysroot $$(call host-path,$$(SYSROOT_INC)) \
+          $(SYSROOT_ARCH_INC_ARG) \
+          -c \
+
+_CC   := $$(NDK_CCACHE) $$($$(my)CXX)
+_TEXT := Compile++ $$(call get-src-file-text,$1)
+
+$$(eval $$(call ev-build-source-file))
+endef
+
+# -----------------------------------------------------------------------------
+# Function  : compile-cpp-source
+# Arguments : 1: single C++ source file name (relative to LOCAL_PATH)
+#           : 2: object file name
+# Returns   : None
+# Usage     : $(call compile-cpp-source,<srcfile>)
+# Rationale : Setup everything required to build a single C++ source file
+# -----------------------------------------------------------------------------
+compile-cpp-source = $(eval $(call ev-compile-cpp-source,$1,$2))
+
+# -----------------------------------------------------------------------------
+# Template  : ev-compile-rs-source
+# Arguments : 1: single RS source file name (relative to LOCAL_PATH)
+#             2: intermediate cpp file (without path)
+#             3: intermediate bc file (without path)
+#             4: so file from bc (without path)
+#             5: target object file (without path)
+#             6: 'true' if bcc_compat is required
+# Returns   : None
+# Usage     : $(eval $(call ev-compile-rs-source,<srcfile>,<cppfile>,<objfile>)
+# Rationale : Internal template evaluated by compile-rs-source
+# -----------------------------------------------------------------------------
+
+define  ev-compile-rs-source
+_RS_SRC:=$$(call local-source-file-path,$(1))
+_CPP_SRC:=$$(LOCAL_OBJS_DIR:%/=%)/$(2)
+_BC_SRC:=$$(LOCAL_OBJS_DIR:%/=%)/$(3)
+_BC_SO:=$(4)
+_OBJ:=$$(LOCAL_OBJS_DIR:%/=%)/$(5)
+_COMPAT := $(6)
+_CPP_FLAGS := $$($$(my)CXXFLAGS) \
+          $$(call get-src-file-target-cflags,$(1)) \
+          $$(call host-c-includes, $$(LOCAL_C_INCLUDES) $$(LOCAL_PATH)) \
+          $$(NDK_APP_CFLAGS) \
+          $$(NDK_APP_CPPFLAGS) \
+          $$(NDK_APP_CXXFLAGS) \
+          $$(LOCAL_CFLAGS) \
+          $$(LOCAL_CPPFLAGS) \
+          $$(LOCAL_CXXFLAGS) \
+          --sysroot $$(call host-path,$$(SYSROOT_INC)) \
+          $(SYSROOT_ARCH_INC_ARG) \
+          -fno-rtti \
+          -c \
+
+_LD_FLAGS := $$(TARGET_LDFLAGS)
+
+_RS_FLAGS := $$(call host-c-includes, $$(LOCAL_RENDERSCRIPT_INCLUDES) $$(LOCAL_PATH)) \
+          $$($$(my)RS_FLAGS) \
+          $$(LOCAL_RENDERSCRIPT_FLAGS) \
+          $$(call host-c-includes,$$($(my)RENDERSCRIPT_INCLUDES)) \
+
+_RS_CC  := $$(NDK_CCACHE) $$($$(my)RS_CC)
+_RS_BCC := $$(NDK_CCACHE) $$($$(my)RS_BCC)
+_CXX    := $$(NDK_CCACHE) $$($$(my)CXX)
+_TEXT   := Compile RS
+_OUT    := $$($$(my)OUT)
+
+$$(eval $$(call ev-build-rs-file))
+endef
+
+# -----------------------------------------------------------------------------
+# Function  : compile-rs-source
+# Arguments : 1: single RS source file name (relative to LOCAL_PATH)
+#             2: intermediate cpp file name
+#             3: intermediate bc file
+#             4: so file from bc (without path)
+#             5: object file name
+#             6: 'true' if bcc_compat is required
+# Returns   : None
+# Usage     : $(call compile-rs-source,<srcfile>)
+# Rationale : Setup everything required to build a single RS source file
+# -----------------------------------------------------------------------------
+compile-rs-source = $(eval $(call ev-compile-rs-source,$1,$2,$3,$4,$5,$6))
+
+#
+#  Module imports
+#
+
+# Initialize import list
+import-init = $(eval __ndk_import_dirs :=)
+
+# Add an optional single directory to the list of import paths
+#
+import-add-path-optional = \
+  $(if $(strip $(wildcard $1)),\
+    $(call ndk_log,Adding import directory: $1)\
+    $(eval __ndk_import_dirs += $1)\
+  )\
+
+# Add a directory to the list of import paths
+# This will warn if the directory does not exist
+#
+import-add-path = \
+  $(if $(strip $(wildcard $1)),\
+    $(call ndk_log,Adding import directory: $1)\
+    $(eval __ndk_import_dirs += $1)\
+  ,\
+    $(call __ndk_info,WARNING: Ignoring unknown import directory: $1)\
+  )\
+
+import-find-module = $(strip \
+      $(eval __imported_module :=)\
+      $(foreach __import_dir,$(__ndk_import_dirs),\
+        $(if $(__imported_module),,\
+          $(call ndk_log,  Probing $(__import_dir)/$1/Android.mk)\
+          $(if $(strip $(wildcard $(__import_dir)/$1/Android.mk)),\
+            $(eval __imported_module := $(__import_dir)/$1)\
+          )\
+        )\
+      )\
+      $(__imported_module)\
+    )
+
+# described in docs/IMPORT-MODULE.TXT
+# $1: tag name for the lookup
+#
+# Small technical note on __ndk_import_depth: we use this variable to
+# record the depth of recursive import-module calls. The variable is
+# initially empty, and we append a "x" to it each time import-module is
+# called. I.e. for three recursive calls to import-module, we would get
+# the values:
+#
+#   first call:   x
+#   second call:  xx
+#   third call:   xxx
+#
+# This is used in module-add to add the top-level modules (i.e. those
+# that are not added with import-module) to __ndk_top_modules, corresponding
+# to the default list of wanted modules (see setup-toolchain.mk).
+#
+import-module = \
+    $(eval __import_tag := $(strip $1))\
+    $(if $(call seq,$(words $(__import_tag)),1),,\
+      $(call __ndk_info,$(call local-makefile): Cannot import module with spaces in tag: '$(__import_tag)')\
+    )\
+    $(if $(call set_is_member,$(__ndk_import_list),$(__import_tag)),\
+      $(call ndk_log,Skipping duplicate import for module with tag '$(__import_tag)')\
+    ,\
+      $(call ndk_log,Looking for imported module with tag '$(__import_tag)')\
+      $(eval __imported_path := $(call import-find-module,$(__import_tag)))\
+      $(if $(__imported_path),\
+        $(call ndk_log,    Found in $(__imported_path))\
+        $(eval __ndk_import_depth := $(__ndk_import_depth)x) \
+        $(eval __ndk_import_list := $(call set_insert,$(__ndk_import_list),$(__import_tag)))\
+        $(eval include $(__imported_path)/Android.mk)\
+        $(eval __ndk_import_depth := $(__ndk_import_depth:%x=%))\
+      ,\
+        $(call __ndk_info,$(call local-makefile): Cannot find module with tag '$(__import_tag)' in import path)\
+        $(call __ndk_info,Are you sure your NDK_MODULE_PATH variable is properly defined ?)\
+        $(call __ndk_info,The following directories were searched:)\
+        $(for __import_dir,$(__ndk_import_dirs),\
+          $(call __ndk_info,    $(__import_dir))\
+        )\
+        $(call __ndk_error,Aborting.)\
+      )\
+   )
+
+# Only used for debugging
+#
+import-debug = \
+    $(info IMPORT DIRECTORIES:)\
+    $(foreach __dir,$(__ndk_import_dirs),\
+      $(info -- $(__dir))\
+    )\
+
+#
+#  Module classes
+#
+NDK_MODULE_CLASSES :=
+
+# Register a new module class
+# $1: class name (e.g. STATIC_LIBRARY)
+# $2: optional file prefix (e.g. 'lib')
+# $3: optional file suffix (e.g. '.so')
+#
+module-class-register = \
+    $(eval NDK_MODULE_CLASSES += $1) \
+    $(eval NDK_MODULE_CLASS.$1.FILE_PREFIX := $2) \
+    $(eval NDK_MODULE_CLASS.$1.FILE_SUFFIX := $3) \
+    $(eval NDK_MODULE_CLASS.$1.INSTALLABLE := $(false)) \
+
+# Same a module-class-register, for installable modules
+#
+# An installable module is one that will be copied to $PROJECT/libs/<abi>/
+# during the NDK build.
+#
+# $1: class name
+# $2: optional file prefix
+# $3: optional file suffix
+#
+module-class-register-installable = \
+    $(call module-class-register,$1,$2,$3) \
+    $(eval NDK_MODULE_CLASS.$1.INSTALLABLE := $(true))
+
+# Returns $(true) if $1 is a valid/registered LOCAL_MODULE_CLASS value
+#
+module-class-check = $(call set_is_member,$(NDK_MODULE_CLASSES),$1)
+
+# Returns $(true) if $1 corresponds to an installable module class
+#
+module-class-is-installable = $(if $(NDK_MODULE_CLASS.$1.INSTALLABLE),$(true),$(false))
+
+# Returns $(true) if $1 corresponds to a copyable prebuilt module class
+#
+module-class-is-copyable = $(if $(call seq,$1,PREBUILT_SHARED_LIBRARY),$(true),$(false))
+
+#
+# Register valid module classes
+#
+
+# static libraries:
+# <foo> -> lib<foo>.a by default
+$(call module-class-register,STATIC_LIBRARY,lib,$(TARGET_LIB_EXTENSION))
+
+# shared libraries:
+# <foo> -> lib<foo>.so
+# a shared library is installable.
+$(call module-class-register-installable,SHARED_LIBRARY,lib,$(TARGET_SONAME_EXTENSION))
+
+# executable
+# <foo> -> <foo>
+# an executable is installable.
+$(call module-class-register-installable,EXECUTABLE,,)
+
+# prebuilt shared library
+# <foo> -> <foo>  (we assume it is already well-named)
+# it is installable
+$(call module-class-register-installable,PREBUILT_SHARED_LIBRARY,,)
+
+# prebuilt static library
+# <foo> -> <foo> (we assume it is already well-named)
+$(call module-class-register,PREBUILT_STATIC_LIBRARY,,)
+
+#
+# C++ STL support
+#
+
+# The list of registered STL implementations we support
+NDK_STL_LIST :=
+
+# Used internally to register a given STL implementation, see below.
+#
+# $1: STL name as it appears in APP_STL (e.g. system)
+# $2: STL module path (e.g. cxx-stl/system)
+# $3: list of static libraries all modules will depend on
+# $4: list of shared libraries all modules will depend on
+# $5: Default standard version for this STL (with `-std` prefix).
+#
+ndk-stl-register = \
+    $(eval __ndk_stl := $(strip $1)) \
+    $(eval NDK_STL_LIST += $(__ndk_stl)) \
+    $(eval NDK_STL.$(__ndk_stl).IMPORT_MODULE := $(strip $2)) \
+    $(eval NDK_STL.$(__ndk_stl).STATIC_LIBS := $(strip $(call strip-lib-prefix,$3))) \
+    $(eval NDK_STL.$(__ndk_stl).SHARED_LIBS := $(strip $(call strip-lib-prefix,$4))) \
+    $(eval NDK_STL.$(__ndk_stl).DEFAULT_STD_VERSION := $(strip $5))
+
+# Called to check that the value of APP_STL is a valid one.
+# $1: STL name as it apperas in APP_STL (e.g. 'system')
+#
+ndk-stl-check = \
+    $(if $(call set_is_member,$(NDK_STL_LIST),$1),,\
+        $(call __ndk_info,Invalid APP_STL value: $1)\
+        $(call __ndk_info,Please use one of the following instead: $(NDK_STL_LIST))\
+        $(call __ndk_error,Aborting))
+
+# Called before the top-level Android.mk is parsed to
+# select the STL implementation.
+# $1: STL name as it appears in APP_STL (e.g. system)
+#
+ndk-stl-select = \
+    $(call import-module,$(NDK_STL.$1.IMPORT_MODULE)) \
+    $(eval STL_DEFAULT_STD_VERSION := $(strip $(NDK_STL.$1.DEFAULT_STD_VERSION)))
+
+# Called after all Android.mk files are parsed to add
+# proper STL dependencies to every C++ module.
+# $1: STL name as it appears in APP_STL (e.g. system)
+#
+ndk-stl-add-dependencies = \
+    $(call modules-add-c++-dependencies,\
+        $(NDK_STL.$1.STATIC_LIBS),\
+        $(NDK_STL.$1.SHARED_LIBS),\
+        $(NDK_STL.$1.LDLIBS))
+
+#
+#
+
+# Register the 'system' STL implementation
+#
+$(call ndk-stl-register,\
+    system,\
+    cxx-stl/system,\
+    libstdc++,\
+    ,\
+    \
+    )
+
+# Register the 'stlport_static' STL implementation
+#
+$(call ndk-stl-register,\
+    stlport_static,\
+    cxx-stl/stlport,\
+    stlport_static,\
+    ,\
+    \
+    )
+
+# Register the 'stlport_shared' STL implementation
+#
+$(call ndk-stl-register,\
+    stlport_shared,\
+    cxx-stl/stlport,\
+    ,\
+    stlport_shared,\
+    \
+    )
+
+# Register the 'gnustl_static' STL implementation
+#
+$(call ndk-stl-register,\
+    gnustl_static,\
+    cxx-stl/gnu-libstdc++,\
+    gnustl_static,\
+    ,\
+    \
+    )
+
+# Register the 'gnustl_shared' STL implementation
+#
+$(call ndk-stl-register,\
+    gnustl_shared,\
+    cxx-stl/gnu-libstdc++,\
+    ,\
+    gnustl_shared,\
+    \
+    )
+
+# Register the 'c++_static' STL implementation
+#
+$(call ndk-stl-register,\
+    c++_static,\
+    cxx-stl/llvm-libc++,\
+    c++_static,\
+    ,\
+    -std=c++11\
+    )
+
+# Register the 'c++_shared' STL implementation
+#
+$(call ndk-stl-register,\
+    c++_shared,\
+    cxx-stl/llvm-libc++,\
+    ,\
+    c++_shared,\
+    -std=c++11\
+    )
+
+# The 'none' APP_STL value corresponds to no C++ support at
+# all. Used by some of the STLport and GAbi++ test projects.
+#
+$(call ndk-stl-register,\
+    none,\
+    cxx-stl/system,\
+    )
+
+ifneq (,$(NDK_UNIT_TESTS))
+$(call ndk-run-all-tests)
+endif
diff --git a/build/core/gdb.mk b/build/core/gdb.mk
new file mode 100644
index 0000000..bd154fc
--- /dev/null
+++ b/build/core/gdb.mk
@@ -0,0 +1,59 @@
+#
+# Copyright (C) 2018 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.
+#
+
+# Ensure that for debuggable applications, gdbserver will be copied to
+# the proper location
+
+NDK_APP_GDBSERVER := $(NDK_APP_DST_DIR)/gdbserver
+NDK_APP_GDBSETUP := $(NDK_APP_DST_DIR)/gdb.setup
+
+ifeq ($(NDK_APP_DEBUGGABLE),true)
+ifeq ($(TARGET_SONAME_EXTENSION),.so)
+
+installed_modules: $(NDK_APP_GDBSERVER)
+
+$(NDK_APP_GDBSERVER): PRIVATE_ABI     := $(TARGET_ARCH_ABI)
+$(NDK_APP_GDBSERVER): PRIVATE_NAME    := $(TOOLCHAIN_NAME)
+$(NDK_APP_GDBSERVER): PRIVATE_SRC     := $(TARGET_GDBSERVER)
+$(NDK_APP_GDBSERVER): PRIVATE_DST     := $(NDK_APP_GDBSERVER)
+
+$(call generate-file-dir,$(NDK_APP_GDBSERVER))
+
+$(NDK_APP_GDBSERVER): clean-installed-binaries
+	$(call host-echo-build-step,$(PRIVATE_ABI),Gdbserver) "[$(PRIVATE_NAME)] $(call pretty-dir,$(PRIVATE_DST))"
+	$(hide) $(call host-install,$(PRIVATE_SRC),$(PRIVATE_DST))
+endif
+
+# Install gdb.setup for both .so and .bc projects
+ifneq (,$(filter $(TARGET_SONAME_EXTENSION),.so .bc))
+installed_modules: $(NDK_APP_GDBSETUP)
+
+$(NDK_APP_GDBSETUP): PRIVATE_ABI := $(TARGET_ARCH_ABI)
+$(NDK_APP_GDBSETUP): PRIVATE_DST := $(NDK_APP_GDBSETUP)
+$(NDK_APP_GDBSETUP): PRIVATE_SOLIB_PATH := $(TARGET_OUT)
+$(NDK_APP_GDBSETUP): PRIVATE_SRC_DIRS := $(SYSROOT_INC)
+
+$(NDK_APP_GDBSETUP):
+	$(call host-echo-build-step,$(PRIVATE_ABI),Gdbsetup) "$(call pretty-dir,$(PRIVATE_DST))"
+	$(hide) $(HOST_ECHO) "set solib-search-path $(call host-path,$(PRIVATE_SOLIB_PATH))" > $(PRIVATE_DST)
+	$(hide) $(HOST_ECHO) "directory $(call host-path,$(call remove-duplicates,$(PRIVATE_SRC_DIRS)))" >> $(PRIVATE_DST)
+
+$(call generate-file-dir,$(NDK_APP_GDBSETUP))
+
+# This prevents parallel execution to clear gdb.setup after it has been written to
+$(NDK_APP_GDBSETUP): clean-installed-binaries
+endif
+endif
diff --git a/build/core/import-locals.mk b/build/core/import-locals.mk
new file mode 100644
index 0000000..3a97dd5
--- /dev/null
+++ b/build/core/import-locals.mk
@@ -0,0 +1,88 @@
+# Copyright (C) 2009 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.
+#
+# Handle local variable expor/import during the build
+#
+
+$(call assert-defined,LOCAL_MODULE)
+
+# For LOCAL_CFLAGS, LOCAL_CONLYFLAGS, LOCAL_CPPFLAGS and LOCAL_C_INCLUDES, etc,
+# we need to use the exported definitions of the closure of all modules
+# we depend on.
+#
+# I.e. If module 'foo' depends on 'bar' which depends on 'zoo',
+# then 'foo' will get the CFLAGS/CONLYFLAGS/CPPFLAGS/C_INCLUDES/... of both 'bar'
+# and 'zoo'
+#
+
+all_depends := $(call module-get-all-dependencies-topo,$(LOCAL_MODULE))
+all_depends := $(filter-out $(LOCAL_MODULE),$(all_depends))
+
+imported_CFLAGS     := $(call module-get-listed-export,$(all_depends),CFLAGS)
+imported_CONLYFLAGS := $(call module-get-listed-export,$(all_depends),CONLYFLAGS)
+imported_CPPFLAGS   := $(call module-get-listed-export,$(all_depends),CPPFLAGS)
+imported_RENDERSCRIPT_FLAGS := $(call module-get-listed-export,$(all_depends),RENDERSCRIPT_FLAGS)
+imported_ASMFLAGS   := $(call module-get-listed-export,$(all_depends),ASMFLAGS)
+imported_C_INCLUDES := $(call module-get-listed-export,$(all_depends),C_INCLUDES)
+imported_LDFLAGS    := $(call module-get-listed-export,$(all_depends),LDFLAGS)
+imported_SHARED_LIBRARIES := $(call module-get-listed-export,$(all_depends),SHARED_LIBRARIES)
+imported_STATIC_LIBRARIES := $(call module-get-listed-export,$(all_depends),STATIC_LIBRARIES)
+
+ifdef NDK_DEBUG_IMPORTS
+    $(info Imports for module $(LOCAL_MODULE):)
+    $(info   CFLAGS='$(imported_CFLAGS)')
+    $(info   CONLYFLAGS='$(imported_CONLYFLAGS)')
+    $(info   CPPFLAGS='$(imported_CPPFLAGS)')
+    $(info   RENDERSCRIPT_FLAGS='$(imported_RENDERSCRIPT_FLAGS)')
+    $(info   ASMFLAGS='$(imported_ASMFLAGS)')
+    $(info   C_INCLUDES='$(imported_C_INCLUDES)')
+    $(info   LDFLAGS='$(imported_LDFLAGS)')
+    $(info   SHARED_LIBRARIES='$(imported_SHARED_LIBRARIES)')
+    $(info   STATIC_LIBRARIES='$(imported_STATIC_LIBRARIES)')
+    $(info All depends='$(all_depends)')
+endif
+
+#
+# The imported compiler flags are prepended to their LOCAL_XXXX value
+# (this allows the module to override them).
+#
+LOCAL_CFLAGS     := $(strip $(imported_CFLAGS) $(LOCAL_CFLAGS))
+LOCAL_CONLYFLAGS := $(strip $(imported_CONLYFLAGS) $(LOCAL_CONLYFLAGS))
+LOCAL_CPPFLAGS   := $(strip $(imported_CPPFLAGS) $(LOCAL_CPPFLAGS))
+LOCAL_RENDERSCRIPT_FLAGS := $(strip $(imported_RENDERSCRIPT_FLAGS) $(LOCAL_RENDERSCRIPT_FLAGS))
+LOCAL_ASMFLAGS := $(strip $(imported_ASMFLAGS) $(LOCAL_ASMFLAGS))
+LOCAL_LDFLAGS    := $(strip $(imported_LDFLAGS) $(LOCAL_LDFLAGS))
+
+__ndk_modules.$(LOCAL_MODULE).STATIC_LIBRARIES += \
+    $(strip $(call strip-lib-prefix,$(imported_STATIC_LIBRARIES)))
+__ndk_modules.$(LOCAL_MODULE).SHARED_LIBRARIES += \
+    $(strip $(call strip-lib-prefix,$(imported_SHARED_LIBRARIES)))
+$(call module-add-static-depends,$(LOCAL_MODULE),$(imported_STATIC_LIBRARIES))
+$(call module-add-shared-depends,$(LOCAL_MODULE),$(imported_SHARED_LIBRARIES))
+
+#
+# The imported include directories are appended to their LOCAL_XXX value
+# (this allows the module to override them)
+#
+LOCAL_C_INCLUDES := $(strip $(LOCAL_C_INCLUDES) $(imported_C_INCLUDES))
+
+# Similarly, you want the imported flags to appear _after_ the LOCAL_LDLIBS
+# due to the way Unix linkers work (depending libraries must appear before
+# dependees on final link command).
+#
+imported_LDLIBS := $(call module-get-listed-export,$(all_depends),LDLIBS)
+
+LOCAL_LDLIBS := $(strip $(LOCAL_LDLIBS) $(imported_LDLIBS))
+
+# We're done here
diff --git a/build/core/init.mk b/build/core/init.mk
new file mode 100644
index 0000000..2e6683f
--- /dev/null
+++ b/build/core/init.mk
@@ -0,0 +1,588 @@
+# Copyright (C) 2009-2010 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.
+#
+
+# Initialization of the NDK build system. This file is included by
+# several build scripts.
+#
+
+# Disable GNU Make implicit rules
+
+# this turns off the suffix rules built into make
+.SUFFIXES:
+
+# this turns off the RCS / SCCS implicit rules of GNU Make
+% : RCS/%,v
+% : RCS/%
+% : %,v
+% : s.%
+% : SCCS/s.%
+
+# If a rule fails, delete $@.
+.DELETE_ON_ERROR:
+
+
+# Define NDK_LOG=1 in your environment to display log traces when
+# using the build scripts. See also the definition of ndk_log below.
+#
+NDK_LOG := $(strip $(NDK_LOG))
+ifeq ($(NDK_LOG),true)
+    override NDK_LOG := 1
+endif
+
+# Check that we have at least GNU Make 3.81
+# We do this by detecting whether 'lastword' is supported
+#
+MAKE_TEST := $(lastword a b c d e f)
+ifneq ($(MAKE_TEST),f)
+    $(error Android NDK: GNU Make version $(MAKE_VERSION) is too low (should be >= 3.81))
+endif
+ifeq ($(NDK_LOG),1)
+    $(info Android NDK: GNU Make version $(MAKE_VERSION) detected)
+endif
+
+# NDK_ROOT *must* be defined and point to the root of the NDK installation
+NDK_ROOT := $(strip $(NDK_ROOT))
+ifndef NDK_ROOT
+    $(error ERROR while including init.mk: NDK_ROOT must be defined !)
+endif
+ifneq ($(words $(NDK_ROOT)),1)
+    $(info,The Android NDK installation path contains spaces: '$(NDK_ROOT)')
+    $(error,Please fix the problem by reinstalling to a different location.)
+endif
+
+# ====================================================================
+#
+# Define a few useful variables and functions.
+# More stuff will follow in definitions.mk.
+#
+# ====================================================================
+
+# Used to output warnings and error from the library, it's possible to
+# disable any warnings or errors by overriding these definitions
+# manually or by setting NDK_NO_WARNINGS or NDK_NO_ERRORS
+
+__ndk_name    := Android NDK
+__ndk_info     = $(info $(__ndk_name): $1 $2 $3 $4 $5)
+__ndk_warning  = $(warning $(__ndk_name): $1 $2 $3 $4 $5)
+__ndk_error    = $(error $(__ndk_name): $1 $2 $3 $4 $5)
+
+ifdef NDK_NO_INFO
+__ndk_info :=
+endif
+ifdef NDK_NO_WARNINGS
+__ndk_warning :=
+endif
+ifdef NDK_NO_ERRORS
+__ndk_error :=
+endif
+
+# -----------------------------------------------------------------------------
+# Function : ndk_log
+# Arguments: 1: text to print when NDK_LOG is defined to 1
+# Returns  : None
+# Usage    : $(call ndk_log,<some text>)
+# -----------------------------------------------------------------------------
+ifeq ($(NDK_LOG),1)
+ndk_log = $(info $(__ndk_name): $1)
+else
+ndk_log :=
+endif
+
+# -----------------------------------------------------------------------------
+# Function : host-toolchain-path
+# Arguments: 1: NDK root
+#            2: Toolchain name
+# Returns  : The parent path of all toolchains for this host. Note that
+#            HOST_TAG64 == HOST_TAG for 32-bit systems.
+# -----------------------------------------------------------------------------
+ifeq ($(NDK_NEW_TOOLCHAINS_LAYOUT),true)
+    host-toolchain-path = $1/$(HOST_TAG64)/$2
+else
+    host-toolchain-path = $1/$2/prebuilt/$(HOST_TAG64)
+endif
+
+# -----------------------------------------------------------------------------
+# Function : get-toolchain-root
+# Arguments: 1: Toolchain name
+# Returns  : Path to the given prebuilt toolchain.
+# -----------------------------------------------------------------------------
+get-toolchain-root = $(call host-toolchain-path,$(NDK_TOOLCHAINS_ROOT),$1)
+
+# -----------------------------------------------------------------------------
+# Function : get-binutils-root
+# Arguments: 1: NDK root
+#            2: Toolchain name (no version number)
+# Returns  : Path to the given prebuilt binutils.
+# -----------------------------------------------------------------------------
+get-binutils-root = $1/binutils/$2
+
+# -----------------------------------------------------------------------------
+# Function : get-gcclibs-path
+# Arguments: 1: NDK root
+#            2: Toolchain name (no version number)
+# Returns  : Path to the given prebuilt gcclibs.
+# -----------------------------------------------------------------------------
+get-gcclibs-path = $1/gcclibs/$2
+
+# ====================================================================
+#
+# Host system auto-detection.
+#
+# ====================================================================
+
+#
+# Determine host system and architecture from the environment
+#
+HOST_OS := $(strip $(HOST_OS))
+ifndef HOST_OS
+    # On all modern variants of Windows (including Cygwin and Wine)
+    # the OS environment variable is defined to 'Windows_NT'
+    #
+    # The value of PROCESSOR_ARCHITECTURE will be x86 or AMD64
+    #
+    ifeq ($(OS),Windows_NT)
+        HOST_OS := windows
+    else
+        # For other systems, use the `uname` output
+        UNAME := $(shell uname -s)
+        ifneq (,$(findstring Linux,$(UNAME)))
+            HOST_OS := linux
+        endif
+        ifneq (,$(findstring Darwin,$(UNAME)))
+            HOST_OS := darwin
+        endif
+        # We should not be there, but just in case !
+        ifneq (,$(findstring CYGWIN,$(UNAME)))
+            HOST_OS := windows
+        endif
+        ifeq ($(HOST_OS),)
+            $(call __ndk_info,Unable to determine HOST_OS from uname -s: $(UNAME))
+            $(call __ndk_info,Please define HOST_OS in your environment.)
+            $(call __ndk_error,Aborting.)
+        endif
+    endif
+    $(call ndk_log,Host OS was auto-detected: $(HOST_OS))
+else
+    $(call ndk_log,Host OS from environment: $(HOST_OS))
+endif
+
+# For all systems, we will have HOST_OS_BASE defined as
+# $(HOST_OS), except on Cygwin where we will have:
+#
+#  HOST_OS      == cygwin
+#  HOST_OS_BASE == windows
+#
+# Trying to detect that we're running from Cygwin is tricky
+# because we can't use $(OSTYPE): It's a Bash shell variable
+# that is not exported to sub-processes, and isn't defined by
+# other shells (for those with really weird setups).
+#
+# Instead, we assume that a program named /bin/uname.exe
+# that can be invoked and returns a valid value corresponds
+# to a Cygwin installation.
+#
+HOST_OS_BASE := $(HOST_OS)
+
+ifeq ($(HOST_OS),windows)
+    ifneq (,$(strip $(wildcard /bin/uname.exe)))
+        $(call ndk_log,Found /bin/uname.exe on Windows host, checking for Cygwin)
+        # NOTE: The 2>NUL here is for the case where we're running inside the
+        #       native Windows shell. On cygwin, this will create an empty NUL file
+        #       that we're going to remove later (see below).
+        UNAME := $(shell /bin/uname.exe -s 2>NUL)
+        $(call ndk_log,uname -s returned: $(UNAME))
+        ifneq (,$(filter CYGWIN%,$(UNAME)))
+            $(call ndk_log,Cygwin detected: $(shell uname -a))
+            HOST_OS := cygwin
+            DUMMY := $(shell rm -f NUL) # Cleaning up
+        else
+            ifneq (,$(filter MINGW32%,$(UNAME)))
+                $(call ndk_log,MSys detected: $(shell uname -a))
+                HOST_OS := cygwin
+            else
+                $(call ndk_log,Cygwin *not* detected!)
+            endif
+        endif
+    endif
+endif
+
+ifneq ($(HOST_OS),$(HOST_OS_BASE))
+    $(call ndk_log, Host operating system detected: $(HOST_OS), base OS: $(HOST_OS_BASE))
+else
+    $(call ndk_log, Host operating system detected: $(HOST_OS))
+endif
+
+HOST_ARCH := $(strip $(HOST_ARCH))
+HOST_ARCH64 :=
+ifndef HOST_ARCH
+    ifeq ($(HOST_OS_BASE),windows)
+        HOST_ARCH := $(PROCESSOR_ARCHITECTURE)
+        ifeq ($(HOST_ARCH),AMD64)
+            HOST_ARCH := x86
+        endif
+        # Windows is 64-bit if either ProgramW6432 or ProgramFiles(x86) is set
+        ifneq ("/",$(shell echo "%ProgramW6432%/%ProgramFiles(x86)%"))
+            HOST_ARCH64 := x86_64
+        endif
+        $(call ndk_log,Host CPU was auto-detected: $(HOST_ARCH))
+    else
+        HOST_ARCH := x86
+        HOST_ARCH64 := x86_64
+    endif
+else
+    $(call ndk_log,Host CPU from environment: $(HOST_ARCH))
+endif
+
+ifeq (,$(HOST_ARCH64))
+    HOST_ARCH64 := $(HOST_ARCH)
+endif
+
+HOST_TAG := $(HOST_OS_BASE)-$(HOST_ARCH)
+HOST_TAG64 := $(HOST_OS_BASE)-$(HOST_ARCH64)
+
+# The directory separator used on this host
+HOST_DIRSEP := :
+ifeq ($(HOST_OS),windows)
+  HOST_DIRSEP := ;
+endif
+
+# The host executable extension
+HOST_EXEEXT :=
+ifeq ($(HOST_OS),windows)
+  HOST_EXEEXT := .exe
+endif
+
+ifeq ($(HOST_TAG),windows-x86)
+    # If we are on Windows, we need to check that we are not running Cygwin 1.5,
+    # which is deprecated and won't run our toolchain binaries properly.
+    ifeq ($(HOST_OS),cygwin)
+        # On cygwin, 'uname -r' returns something like 1.5.23(0.225/5/3)
+        # We recognize 1.5. as the prefix to look for then.
+        CYGWIN_VERSION := $(shell uname -r)
+        ifneq ($(filter XX1.5.%,XX$(CYGWIN_VERSION)),)
+            $(call __ndk_info,You seem to be running Cygwin 1.5, which is not supported.)
+            $(call __ndk_info,Please upgrade to Cygwin 1.7 or higher.)
+            $(call __ndk_error,Aborting.)
+        endif
+    endif
+
+    # special-case the host-tag
+    HOST_TAG := windows
+
+    # For 32-bit systems, HOST_TAG64 should be HOST_TAG, but we just updated
+    # HOST_TAG, so update HOST_TAG64 to match.
+    ifeq ($(HOST_ARCH64),x86)
+        HOST_TAG64 = $(HOST_TAG)
+    endif
+endif
+
+$(call ndk_log,HOST_TAG set to $(HOST_TAG))
+
+# Check for NDK-specific versions of our host tools
+HOST_TOOLS_ROOT := $(NDK_ROOT)/prebuilt/$(HOST_TAG64)
+HOST_PREBUILT := $(strip $(wildcard $(HOST_TOOLS_ROOT)/bin))
+HOST_MAKE := $(strip $(NDK_HOST_MAKE))
+HOST_PYTHON := $(strip $(NDK_HOST_PYTHON))
+ifdef HOST_PREBUILT
+    $(call ndk_log,Host tools prebuilt directory: $(HOST_PREBUILT))
+    # The windows prebuilt binaries are for ndk-build.cmd
+    # On cygwin, we must use the Cygwin version of these tools instead.
+    ifneq ($(HOST_OS),cygwin)
+        ifndef HOST_MAKE
+            HOST_MAKE := $(wildcard $(HOST_PREBUILT)/make$(HOST_EXEEXT))
+        endif
+       ifndef HOST_PYTHON
+            HOST_PYTHON := $(wildcard $(HOST_PREBUILT)/python$(HOST_EXEEXT))
+        endif
+    endif
+else
+    $(call ndk_log,Host tools prebuilt directory not found, using system tools)
+endif
+ifndef HOST_PYTHON
+    HOST_PYTHON := python
+endif
+
+HOST_ECHO := $(strip $(NDK_HOST_ECHO))
+ifdef HOST_PREBUILT
+    ifndef HOST_ECHO
+        # Special case, on Cygwin, always use the host echo, not our prebuilt one
+        # which adds \r\n at the end of lines.
+        ifneq ($(HOST_OS),cygwin)
+            HOST_ECHO := $(strip $(wildcard $(HOST_PREBUILT)/echo$(HOST_EXEEXT)))
+        endif
+    endif
+endif
+ifndef HOST_ECHO
+    HOST_ECHO := echo
+endif
+$(call ndk_log,Host 'echo' tool: $(HOST_ECHO))
+
+# Define HOST_ECHO_N to perform the equivalent of 'echo -n' on all platforms.
+ifeq ($(HOST_OS),windows)
+  # Our custom toolbox echo binary supports -n.
+  HOST_ECHO_N := $(HOST_ECHO) -n
+else
+  # On Posix, just use bare printf.
+  HOST_ECHO_N := printf %s
+endif
+$(call ndk_log,Host 'echo -n' tool: $(HOST_ECHO_N))
+
+HOST_CMP := $(strip $(NDK_HOST_CMP))
+ifdef HOST_PREBUILT
+    ifndef HOST_CMP
+        HOST_CMP := $(strip $(wildcard $(HOST_PREBUILT)/cmp$(HOST_EXEEXT)))
+    endif
+endif
+ifndef HOST_CMP
+    HOST_CMP := cmp
+endif
+$(call ndk_log,Host 'cmp' tool: $(HOST_CMP))
+
+# Location of python build helpers.
+BUILD_PY := $(NDK_ROOT)/build
+
+#
+# On Cygwin/MSys, define the 'cygwin-to-host-path' function here depending on the
+# environment. The rules are the following:
+#
+# 1/ If NDK_USE_CYGPATH=1 and cygpath does exist in your path, cygwin-to-host-path
+#    calls "cygpath -m" for each host path.  Since invoking 'cygpath -m' from GNU
+#    Make for each source file is _very_ slow, this is only a backup plan in
+#    case our automatic substitution function (described below) doesn't work.
+#
+# 2/ Generate a Make function that performs the mapping from cygwin/msys to host
+#    paths through simple substitutions.  It's really a series of nested patsubst
+#    calls, that loo like:
+#
+#     cygwin-to-host-path = $(patsubst /cygdrive/c/%,c:/%,\
+#                             $(patsusbt /cygdrive/d/%,d:/%, \
+#                              $1)
+#    or in MSys:
+#     cygwin-to-host-path = $(patsubst /c/%,c:/%,\
+#                             $(patsusbt /d/%,d:/%, \
+#                              $1)
+#
+# except that the actual definition is built from the list of mounted
+# drives as reported by "mount" and deals with drive letter cases (i.e.
+# '/cygdrive/c' and '/cygdrive/C')
+#
+ifeq ($(HOST_OS),cygwin)
+    CYGPATH := $(strip $(HOST_CYGPATH))
+    ifndef CYGPATH
+        $(call ndk_log, Probing for 'cygpath' program)
+        CYGPATH := $(strip $(shell which cygpath 2>/dev/null))
+        ifndef CYGPATH
+            $(call ndk_log, 'cygpath' was *not* found in your path)
+        else
+            $(call ndk_log, 'cygpath' found as: $(CYGPATH))
+        endif
+    endif
+
+    ifeq ($(NDK_USE_CYGPATH),1)
+        ifndef CYGPATH
+            $(call __ndk_info,No cygpath)
+            $(call __ndk_error,Aborting)
+        endif
+        $(call ndk_log, Forced usage of 'cygpath -m' through NDK_USE_CYGPATH=1)
+        cygwin-to-host-path = $(strip $(shell $(CYGPATH) -m $1))
+    else
+        # Call a Python script to generate a Makefile function that approximates
+        # cygpath.
+        WINDOWS_HOST_PATH_FRAGMENT := $(shell mount | $(HOST_PYTHON) $(BUILD_PY)/gen_cygpath.py)
+        $(eval cygwin-to-host-path = $(WINDOWS_HOST_PATH_FRAGMENT))
+    endif
+endif # HOST_OS == cygwin
+
+# The location of the build system files
+BUILD_SYSTEM := $(NDK_ROOT)/build/core
+
+# Include common definitions
+include $(BUILD_SYSTEM)/definitions.mk
+
+# ====================================================================
+#
+# Read all platform-specific configuration files.
+#
+# Each platform must be located in build/platforms/android-<apilevel>
+# where <apilevel> corresponds to an API level number, with:
+#   3 -> Android 1.5
+#   4 -> next platform release
+#
+# ====================================================================
+
+# The platform files were moved in the Android source tree from
+# $TOP/ndk/build/platforms to $TOP/development/ndk/platforms. However,
+# the official NDK release packages still place them under the old
+# location for now, so deal with this here
+#
+NDK_PLATFORMS_ROOT := $(strip $(NDK_PLATFORMS_ROOT))
+ifndef NDK_PLATFORMS_ROOT
+    NDK_PLATFORMS_ROOT := $(strip $(wildcard $(NDK_ROOT)/platforms))
+    ifndef NDK_PLATFORMS_ROOT
+        NDK_PLATFORMS_ROOT := $(strip $(wildcard $(NDK_ROOT)/build/platforms))
+    endif
+
+    ifndef NDK_PLATFORMS_ROOT
+        $(call __ndk_info,Could not find platform files (headers and libraries))
+        $(if $(strip $(wildcard $(NDK_ROOT)/RELEASE.TXT)),\
+            $(call __ndk_info,Please define NDK_PLATFORMS_ROOT to point to a valid directory.)\
+        )
+        $(call __ndk_error,Aborting)
+    endif
+
+    $(call ndk_log,Found platform root directory: $(NDK_PLATFORMS_ROOT))
+endif
+ifeq ($(strip $(wildcard $(NDK_PLATFORMS_ROOT)/android-*)),)
+    $(call __ndk_info,Your NDK_PLATFORMS_ROOT points to an invalid directory)
+    $(call __ndk_info,Current value: $(NDK_PLATFORMS_ROOT))
+    $(call __ndk_error,Aborting)
+endif
+
+NDK_ALL_PLATFORMS := $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/android-*)))
+$(call ndk_log,Found supported platforms: $(NDK_ALL_PLATFORMS))
+
+$(foreach _platform,$(NDK_ALL_PLATFORMS),\
+  $(eval include $(BUILD_SYSTEM)/add-platform.mk)\
+)
+
+# we're going to find the maximum platform number of the form android-<number>
+# ignore others, which could correspond to special and experimental cases
+NDK_ALL_PLATFORM_LEVELS := $(filter android-%,$(NDK_ALL_PLATFORMS))
+NDK_ALL_PLATFORM_LEVELS := $(patsubst android-%,%,$(NDK_ALL_PLATFORM_LEVELS))
+$(call ndk_log,Found stable platform levels: $(NDK_ALL_PLATFORM_LEVELS))
+
+NDK_MIN_PLATFORM_LEVEL := 14
+NDK_MIN_PLATFORM := android-$(NDK_MIN_PLATFORM_LEVEL)
+
+NDK_MAX_PLATFORM_LEVEL := 3
+$(foreach level,$(NDK_ALL_PLATFORM_LEVELS),\
+  $(eval NDK_MAX_PLATFORM_LEVEL := $$(call max,$$(NDK_MAX_PLATFORM_LEVEL),$$(level)))\
+)
+NDK_MAX_PLATFORM := android-$(NDK_MAX_PLATFORM_LEVEL)
+
+$(call ndk_log,Found max platform level: $(NDK_MAX_PLATFORM_LEVEL))
+
+# Allow the user to point at an alternate location for the toolchains. This is
+# particularly helpful if we want to use prebuilt toolchains for building an NDK
+# module. Specifically, we use this to build libc++ using ndk-build instead of
+# the old build-cxx-stl.sh and maintaining two sets of build rules.
+NDK_TOOLCHAINS_ROOT := $(strip $(NDK_TOOLCHAINS_ROOT))
+ifndef NDK_TOOLCHAINS_ROOT
+    NDK_TOOLCHAINS_ROOT := $(strip $(NDK_ROOT)/toolchains)
+endif
+
+# ====================================================================
+#
+# Read all toolchain-specific configuration files.
+#
+# Each toolchain must have a corresponding config.mk file located
+# in build/toolchains/<name>/ that will be included here.
+#
+# Each one of these files should define the following variables:
+#   TOOLCHAIN_NAME   toolchain name (e.g. arm-linux-androideabi-4.9)
+#   TOOLCHAIN_ABIS   list of target ABIs supported by the toolchain.
+#
+# Then, it should include $(ADD_TOOLCHAIN) which will perform
+# book-keeping for the build system.
+#
+# ====================================================================
+
+# the build script to include in each toolchain config.mk
+ADD_TOOLCHAIN := $(BUILD_SYSTEM)/add-toolchain.mk
+
+# ABI information is kept in meta/abis.json so it can be shared among multiple
+# build systems. Use Python to convert the JSON into make, replace the newlines
+# as necessary (make helpfully turns newlines into spaces for us...
+# https://www.gnu.org/software/make/manual/html_node/Shell-Function.html) and
+# eval the result.
+$(eval $(subst %NEWLINE%,$(newline),$(shell $(HOST_PYTHON) \
+    $(BUILD_PY)/import_abi_metadata.py $(NDK_ROOT)/meta/abis.json)))
+
+NDK_KNOWN_DEVICE_ABIS := $(NDK_KNOWN_DEVICE_ABI64S) $(NDK_KNOWN_DEVICE_ABI32S)
+
+NDK_APP_ABI_ALL_EXPANDED := $(NDK_KNOWN_DEVICE_ABIS)
+NDK_APP_ABI_ALL32_EXPANDED := $(NDK_KNOWN_DEVICE_ABI32S)
+NDK_APP_ABI_ALL64_EXPANDED := $(NDK_KNOWN_DEVICE_ABI64S)
+
+# The first API level ndk-build enforces -fPIE for executable
+NDK_FIRST_PIE_PLATFORM_LEVEL := 16
+
+# the list of all toolchains in this NDK
+NDK_ALL_TOOLCHAINS :=
+NDK_ALL_ABIS       :=
+NDK_ALL_ARCHS      :=
+
+TOOLCHAIN_CONFIGS := $(wildcard $(NDK_ROOT)/build/core/toolchains/*/config.mk)
+$(foreach _config_mk,$(TOOLCHAIN_CONFIGS),\
+  $(eval include $(BUILD_SYSTEM)/add-toolchain.mk)\
+)
+
+NDK_ALL_TOOLCHAINS   := $(sort $(NDK_ALL_TOOLCHAINS))
+NDK_ALL_ABIS         := $(sort $(NDK_ALL_ABIS))
+NDK_ALL_ARCHS        := $(sort $(NDK_ALL_ARCHS))
+
+# Check that each ABI has a single architecture definition
+$(foreach _abi,$(strip $(NDK_ALL_ABIS)),\
+  $(if $(filter-out 1,$(words $(NDK_ABI.$(_abi).arch))),\
+    $(call __ndk_info,INTERNAL ERROR: The $(_abi) ABI should have exactly one architecture definitions. Found: '$(NDK_ABI.$(_abi).arch)')\
+    $(call __ndk_error,Aborting...)\
+  )\
+)
+
+# Allow the user to define NDK_TOOLCHAIN to a custom toolchain name.
+# This is normally used when the NDK release comes with several toolchains
+# for the same architecture (generally for backwards-compatibility).
+#
+NDK_TOOLCHAIN := $(strip $(NDK_TOOLCHAIN))
+ifdef NDK_TOOLCHAIN
+    # check that the toolchain name is supported
+    $(if $(filter-out $(NDK_ALL_TOOLCHAINS),$(NDK_TOOLCHAIN)),\
+      $(call __ndk_info,NDK_TOOLCHAIN is defined to the unsupported value $(NDK_TOOLCHAIN)) \
+      $(call __ndk_info,Please use one of the following values: $(NDK_ALL_TOOLCHAINS))\
+      $(call __ndk_error,Aborting)\
+    ,)
+    $(call ndk_log, Using specific toolchain $(NDK_TOOLCHAIN))
+endif
+
+# Allow the user to define NDK_TOOLCHAIN_VERSION to override the toolchain
+# version number. Unlike NDK_TOOLCHAIN, this only changes the suffix of
+# the toolchain path we're using.
+#
+# For example, if GCC 4.8 is the default, defining NDK_TOOLCHAIN_VERSION=4.9
+# will ensure that ndk-build uses the following toolchains, depending on
+# the target architecture:
+#
+#    arm -> arm-linux-androideabi-4.9
+#    x86 -> x86-android-linux-4.9
+#    mips -> mips64el-linux-android-4.9
+#
+# This is used in setup-toolchain.mk
+#
+NDK_TOOLCHAIN_VERSION := $(strip $(NDK_TOOLCHAIN_VERSION))
+
+# Default to Clang.
+ifeq ($(NDK_TOOLCHAIN_VERSION),)
+    NDK_TOOLCHAIN_VERSION := clang
+endif
+
+$(call ndk_log, This NDK supports the following target architectures and ABIS:)
+$(foreach arch,$(NDK_ALL_ARCHS),\
+    $(call ndk_log, $(space)$(space)$(arch): $(NDK_ARCH.$(arch).abis))\
+)
+$(call ndk_log, This NDK supports the following toolchains and target ABIs:)
+$(foreach tc,$(NDK_ALL_TOOLCHAINS),\
+    $(call ndk_log, $(space)$(space)$(tc):  $(NDK_TOOLCHAIN.$(tc).abis))\
+)
+
diff --git a/build/core/install_sanitizer.mk b/build/core/install_sanitizer.mk
new file mode 100644
index 0000000..fac02f6
--- /dev/null
+++ b/build/core/install_sanitizer.mk
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2018 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.
+#
+
+# Generates rules to install sanitizer runtime libraries to the out directory if
+# the sanitizer is requested in the app's ldflags.
+#
+# Args:
+#   NDK_SANTIZER_NAME:
+#       Sanitizer name used as the variable name component to find the library.
+#       i.e. $(TARGET_$(2)_BASENAME) is the name of the library to install. This
+#       is also used as the name printed to the terminal for the build step.
+#   NDK_SANITIZER_FSANITIZE_ARGS:
+#       -fsanitize= arguments that require this runtime library.
+#
+# Example usage:
+#   NDK_SANITIZER_NAME := UBSAN
+#   NDK_SANITIZER_FSANITIZE_ARGS := undefined
+#   include $(BUILD_SYSTEM)/install_sanitizer.mk
+
+ifneq (,$(filter $(NDK_SANITIZER_FSANITIZE_ARGS),$(NDK_SANITIZERS)))
+installed_modules: $(NDK_APP_$(NDK_SANITIZER_NAME))
+
+NDK_SANITIZER_TARGET := $(NDK_APP_$(NDK_SANITIZER_NAME))
+NDK_SANITIZER_LIB_PATH := $(NDK_TOOLCHAIN_LIB_DIR)/$(TARGET_$(NDK_SANITIZER_NAME)_BASENAME)
+
+$(NDK_SANITIZER_TARGET): PRIVATE_ABI := $(TARGET_ARCH_ABI)
+$(NDK_SANITIZER_TARGET): PRIVATE_NAME := $(NDK_SANITIZER_NAME)
+$(NDK_SANITIZER_TARGET): PRIVATE_SRC := $(NDK_SANITIZER_LIB_PATH)
+$(NDK_SANITIZER_TARGET): PRIVATE_DST := $(NDK_APP_$(NDK_SANITIZER_NAME))
+
+$(call generate-file-dir,$(NDK_APP_$(NDK_SANITIZER_NAME)))
+
+$(NDK_SANITIZER_TARGET): clean-installed-binaries
+	$(call host-echo-build-step,$(PRIVATE_ABI),$(PRIVATE_NAME) "$(call pretty-dir,$(PRIVATE_DST))")
+	$(hide) $(call host-install,$(PRIVATE_SRC),$(PRIVATE_DST))
+endif
diff --git a/build/core/install_wrap_sh.mk b/build/core/install_wrap_sh.mk
new file mode 100644
index 0000000..b570190
--- /dev/null
+++ b/build/core/install_wrap_sh.mk
@@ -0,0 +1,29 @@
+#
+# Copyright (C) 2018 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.
+#
+
+# Generates rules to install wrap.sh files to the app's out directory.
+
+NDK_WRAP_SH := $(NDK_APP_DST_DIR)/wrap.sh
+$(call generate-file-dir,$(NDK_WRAP_SH))
+
+installed_modules: $(NDK_WRAP_SH)
+
+WRAP_SH_SRC := $(call local-source-file-path,$(NDK_APP_WRAP_SH_$(TARGET_ARCH_ABI)))
+
+$(NDK_WRAP_SH): PRIVATE_ABI := $(TARGET_ARCH_ABI)
+$(NDK_WRAP_SH): $(WRAP_SH_SRC) clean-installed-binaries
+	$(call host-echo-build-step,$(PRIVATE_ABI),wrap.sh "$(call pretty-dir,$@)")
+	$(hide) $(call host-install,$<,$@)
diff --git a/build/core/prebuilt-library.mk b/build/core/prebuilt-library.mk
new file mode 100644
index 0000000..4c7d93d
--- /dev/null
+++ b/build/core/prebuilt-library.mk
@@ -0,0 +1,74 @@
+# Copyright (C) 2010 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.
+#
+
+# this file is included from prebuilt-shared-library.mk or
+# prebuilt-static-library.mk to declare prebuilt library binaries.
+#
+
+$(call assert-defined, LOCAL_BUILD_SCRIPT LOCAL_MAKEFILE LOCAL_PREBUILT_PREFIX LOCAL_PREBUILT_SUFFIX)
+
+$(call check-defined-LOCAL_MODULE,$(LOCAL_BUILD_SCRIPT))
+$(call check-LOCAL_MODULE,$(LOCAL_MAKEFILE))
+$(call check-LOCAL_MODULE_FILENAME)
+
+# Check that LOCAL_SRC_FILES contains only the path to one library
+ifneq ($(words $(LOCAL_SRC_FILES)),1)
+$(call __ndk_info,ERROR:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): The LOCAL_SRC_FILES for a prebuilt library should only contain one item))
+$(call __ndk_error,Aborting)
+endif
+
+bad_prebuilts := $(filter-out %$(LOCAL_PREBUILT_SUFFIX),$(LOCAL_SRC_FILES))
+ifdef bad_prebuilts
+$(call __ndk_info,ERROR:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_SRC_FILES should point to a file ending with "$(LOCAL_PREBUILT_SUFFIX)")
+$(call __ndk_info,The following file is unsupported: $(bad_prebuilts))
+$(call __ndk_error,Aborting)
+endif
+
+prebuilt_path := $(call local-prebuilt-path,$(LOCAL_SRC_FILES))
+prebuilt := $(strip $(wildcard $(prebuilt_path)))
+
+ifndef prebuilt
+$(call __ndk_info,ERROR:$(LOCAL_MAKEFILE):$(LOCAL_MODULE): LOCAL_SRC_FILES points to a missing file)
+$(call __ndk_info,Check that $(prebuilt_path) exists, or that its path is correct)
+$(call __ndk_error,Aborting)
+endif
+
+# If LOCAL_MODULE_FILENAME is defined, it will be used to name the file
+# in the TARGET_OUT directory, and then the installation one. Note that
+# it shouldn't have an .a or .so extension nor contain directory separators.
+#
+# If the variable is not defined, we determine its value from LOCAL_SRC_FILES
+#
+LOCAL_MODULE_FILENAME := $(strip $(LOCAL_MODULE_FILENAME))
+ifndef LOCAL_MODULE_FILENAME
+    LOCAL_MODULE_FILENAME := $(notdir $(LOCAL_SRC_FILES))
+    LOCAL_MODULE_FILENAME := $(LOCAL_MODULE_FILENAME:%$(LOCAL_PREBUILT_SUFFIX)=%)
+endif
+$(eval $(call ev-check-module-filename))
+
+# If LOCAL_BUILT_MODULE is not defined, then ensure that the prebuilt is
+# copied to TARGET_OUT during the build.
+LOCAL_BUILT_MODULE := $(strip $(LOCAL_BUILT_MODULE))
+ifndef LOCAL_BUILT_MODULE
+  LOCAL_BUILT_MODULE := $(TARGET_OUT)/$(LOCAL_MODULE_FILENAME)$(LOCAL_PREBUILT_SUFFIX)
+  LOCAL_OBJECTS      := $(prebuilt)
+
+  $(LOCAL_BUILT_MODULE): $(LOCAL_OBJECTS)
+endif
+
+LOCAL_OBJS_DIR  := $(TARGET_OBJS)/$(LOCAL_MODULE)
+LOCAL_SRC_FILES :=
+
+include $(BUILD_SYSTEM)/build-module.mk
diff --git a/build/core/prebuilt-shared-library.mk b/build/core/prebuilt-shared-library.mk
new file mode 100644
index 0000000..77ccb11
--- /dev/null
+++ b/build/core/prebuilt-shared-library.mk
@@ -0,0 +1,27 @@
+# Copyright (C) 2010 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.
+#
+
+# this file is included from Android.mk files to build a target-specific
+# shared library
+#
+
+LOCAL_BUILD_SCRIPT := PREBUILT_SHARED_LIBRARY
+LOCAL_MODULE_CLASS := PREBUILT_SHARED_LIBRARY
+LOCAL_MAKEFILE     := $(local-makefile)
+
+LOCAL_PREBUILT_PREFIX := lib
+LOCAL_PREBUILT_SUFFIX := $(TARGET_SONAME_EXTENSION)
+
+include $(BUILD_SYSTEM)/prebuilt-library.mk
diff --git a/build/core/prebuilt-static-library.mk b/build/core/prebuilt-static-library.mk
new file mode 100644
index 0000000..07d981b
--- /dev/null
+++ b/build/core/prebuilt-static-library.mk
@@ -0,0 +1,33 @@
+# Copyright (C) 2010 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.
+#
+
+# this file is included from Android.mk files to build a target-specific
+# shared library
+#
+
+LOCAL_BUILD_SCRIPT := PREBUILT_STATIC_LIBRARY
+LOCAL_MODULE_CLASS := PREBUILT_STATIC_LIBRARY
+LOCAL_MAKEFILE     := $(local-makefile)
+
+LOCAL_PREBUILT_PREFIX := lib
+LOCAL_PREBUILT_SUFFIX := $(TARGET_LIB_EXTENSION)
+
+# Prebuilt static libraries don't need to be copied to TARGET_OUT
+# to facilitate debugging, so use the prebuilt version directly
+# at link time.
+LOCAL_BUILT_MODULE := $(call local-prebuilt-path,$(LOCAL_SRC_FILES))
+LOCAL_BUILT_MODULE_NOT_COPIED := true
+
+include $(BUILD_SYSTEM)/prebuilt-library.mk
diff --git a/build/core/sanitizers.mk b/build/core/sanitizers.mk
new file mode 100644
index 0000000..70ae4ec
--- /dev/null
+++ b/build/core/sanitizers.mk
@@ -0,0 +1,50 @@
+#
+# Copyright (C) 2018 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.
+#
+
+NDK_TOOLCHAIN_LIB_SUFFIX := 64
+ifeq ($(HOST_ARCH64),x86)
+    NDK_TOOLCHAIN_LIB_SUFFIX :=
+endif
+
+NDK_TOOLCHAIN_LIB_DIR := \
+    $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/lib$(NDK_TOOLCHAIN_LIB_SUFFIX)/clang/6.0.2/lib/linux
+
+NDK_APP_ASAN := $(NDK_APP_DST_DIR)/$(TARGET_ASAN_BASENAME)
+NDK_APP_UBSAN := $(NDK_APP_DST_DIR)/$(TARGET_UBSAN_BASENAME)
+
+NDK_MODULES_LDFLAGS :=
+$(foreach __module,$(__ndk_modules),\
+    $(eval NDK_MODULES_LDFLAGS += --module $(__ndk_modules.$(__module).LDFLAGS)))
+NDK_SANITIZERS := $(strip \
+    $(shell $(HOST_PYTHON) $(BUILD_PY)/ldflags_to_sanitizers.py \
+    $(NDK_APP_LDFLAGS) $(NDK_MODULES_LDFLAGS)))
+
+NDK_SANITIZER_NAME := UBSAN
+NDK_SANITIZER_FSANITIZE_ARGS := undefined
+include $(BUILD_SYSTEM)/install_sanitizer.mk
+
+NDK_SANITIZER_NAME := ASAN
+NDK_SANITIZER_FSANITIZE_ARGS := address
+include $(BUILD_SYSTEM)/install_sanitizer.mk
+
+# If the user has not specified their own wrap.sh and is using ASAN, install a
+# default ASAN wrap.sh for them.
+ifneq (,$(filter address,$(NDK_SANITIZERS)))
+    ifeq ($(NDK_NO_USER_WRAP_SH),true)
+        NDK_APP_WRAP_SH_$(TARGET_ARCH_ABI) := \
+            $(NDK_ROOT)/wrap.sh/asan.$(TARGET_ARCH_ABI).sh
+    endif
+endif
diff --git a/build/core/setup-abi.mk b/build/core/setup-abi.mk
new file mode 100644
index 0000000..773960c
--- /dev/null
+++ b/build/core/setup-abi.mk
@@ -0,0 +1,93 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is included multiple times by build/core/setup-app.mk
+#
+
+$(call ndk_log,Building application '$(NDK_APP_NAME)' for ABI '$(TARGET_ARCH_ABI)')
+
+TARGET_ARCH := $(strip $(NDK_ABI.$(TARGET_ARCH_ABI).arch))
+ifndef TARGET_ARCH
+    $(call __ndk_info,ERROR: The $(TARGET_ARCH_ABI) ABI has no associated architecture!)
+    $(call __ndk_error,Aborting...)
+endif
+
+TARGET_OUT := $(NDK_APP_OUT)/$(_app)/$(TARGET_ARCH_ABI)
+
+# For x86 and mips: the minimal platform level is android-9
+TARGET_PLATFORM_SAVED := $(TARGET_PLATFORM)
+
+# For 64-bit ABIs: the minimal platform level is android-21
+ifneq ($(filter $(NDK_KNOWN_DEVICE_ABI64S),$(TARGET_ARCH_ABI)),)
+$(foreach _plat,3 4 5 8 9 10 11 12 13 14 15 16 17 18 19 20,\
+    $(eval TARGET_PLATFORM := $$(subst android-$(_plat),android-21,$$(TARGET_PLATFORM)))\
+)
+endif
+
+TARGET_PLATFORM_LEVEL := $(strip $(subst android-,,$(TARGET_PLATFORM)))
+ifneq (,$(call gte,$(TARGET_PLATFORM_LEVEL),$(NDK_FIRST_PIE_PLATFORM_LEVEL)))
+    TARGET_PIE := true
+    $(call ndk_log,  Enabling -fPIE for TARGET_PLATFORM $(TARGET_PLATFORM))
+else
+    TARGET_PIE := false
+endif
+
+# If we're targeting a new enough platform version, we don't actually need to
+# cover any gaps in libc for libc++ support. In those cases, save size in the
+# APK by avoiding libandroid_support.
+#
+# This is also a requirement for static executables, since using
+# libandroid_support with a modern libc.a will result in multiple symbol
+# definition errors.
+NDK_PLATFORM_NEEDS_ANDROID_SUPPORT := true
+ifeq ($(call gte,$(TARGET_PLATFORM_LEVEL),21),$(true))
+    NDK_PLATFORM_NEEDS_ANDROID_SUPPORT := false
+endif
+
+# Separate the debug and release objects. This prevents rebuilding
+# everything when you switch between these two modes. For projects
+# with lots of C++ sources, this can be a considerable time saver.
+ifeq ($(NDK_APP_OPTIM),debug)
+TARGET_OBJS := $(TARGET_OUT)/objs-debug
+else
+TARGET_OBJS := $(TARGET_OUT)/objs
+endif
+
+TARGET_GDB_SETUP := $(TARGET_OUT)/setup.gdb
+
+# RS triple
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+  RS_TRIPLE := armv7-none-linux-gnueabi
+endif
+ifeq ($(TARGET_ARCH_ABI),armeabi)
+  RS_TRIPLE := arm-none-linux-gnueabi
+endif
+ifeq ($(TARGET_ARCH_ABI),arm64-v8a)
+  RS_TRIPLE := aarch64-linux-android
+endif
+ifeq ($(TARGET_ARCH_ABI),mips)
+  RS_TRIPLE := mipsel-unknown-linux
+endif
+ifeq ($(TARGET_ARCH_ABI),x86)
+  RS_TRIPLE := i686-unknown-linux
+endif
+ifeq ($(TARGET_ARCH_ABI),x86_64)
+  RS_TRIPLE := x86_64-unknown-linux
+endif
+
+include $(BUILD_SYSTEM)/setup-toolchain.mk
+
+# Restore TARGET_PLATFORM, see above.
+TARGET_PLATFORM := $(TARGET_PLATFORM_SAVED)
diff --git a/build/core/setup-app-platform.mk b/build/core/setup-app-platform.mk
new file mode 100644
index 0000000..c91be99
--- /dev/null
+++ b/build/core/setup-app-platform.mk
@@ -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.
+#
+
+# Included from add-application.mk to configure the APP_PLATFORM setting.
+
+ifeq (null,$(APP_PROJECT_PATH))
+
+ifndef APP_PLATFORM
+    $(call __ndk_info,APP_PLATFORM not set. Defaulting to minimum supported \
+        version $(NDK_MIN_PLATFORM).)
+    APP_PLATFORM := $(NDK_MIN_PLATFORM)
+endif
+
+else
+
+# Set APP_PLATFORM with the following precedence:
+#
+# 1. APP_PLATFORM setting from the user.
+# 2. Value in project.properties.
+# 3. Minimum supported platform level.
+APP_PLATFORM := $(strip $(APP_PLATFORM))
+ifndef APP_PLATFORM
+    _local_props := $(strip $(wildcard $(APP_PROJECT_PATH)/project.properties))
+    ifndef _local_props
+        # NOTE: project.properties was called default.properties before
+        _local_props := $(strip \
+            $(wildcard $(APP_PROJECT_PATH)/default.properties))
+    endif
+
+    ifdef _local_props
+        APP_PLATFORM := $(strip \
+            $(shell $(HOST_PYTHON) $(BUILD_PY)/extract_platform.py \
+                $(call host-path,$(_local_props))))
+        $(call __ndk_info,Found platform level in $(_local_props). Setting \
+            APP_PLATFORM to $(APP_PLATFORM).)
+    else
+        $(call __ndk_info,APP_PLATFORM not set. Defaulting to minimum \
+            supported version $(NDK_MIN_PLATFORM).)
+        APP_PLATFORM := $(NDK_MIN_PLATFORM)
+    endif
+endif
+
+ifeq ($(APP_PLATFORM),latest)
+    $(call __ndk_info,Using latest available APP_PLATFORM: $(NDK_MAX_PLATFORM).)
+    override APP_PLATFORM := $(NDK_MAX_PLATFORM)
+endif
+
+# Handle any platform codenames.
+ifeq ($(APP_PLATFORM),android-I)
+    override APP_PLATFORM := android-14
+else ifeq ($(APP_PLATFORM),android-J)
+    override APP_PLATFORM := android-16
+else ifeq ($(APP_PLATFORM),android-J-MR1)
+    override APP_PLATFORM := android-17
+else ifeq ($(APP_PLATFORM),android-J-MR2)
+    override APP_PLATFORM := android-18
+else ifeq ($(APP_PLATFORM),android-K)
+    override APP_PLATFORM := android-19
+else ifeq ($(APP_PLATFORM),android-L)
+    override APP_PLATFORM := android-21
+else ifeq ($(APP_PLATFORM),android-L-MR1)
+    override APP_PLATFORM := android-22
+else ifeq ($(APP_PLATFORM),android-M)
+    override APP_PLATFORM := android-23
+else ifeq ($(APP_PLATFORM),android-N)
+    override APP_PLATFORM := android-24
+else ifeq ($(APP_PLATFORM),android-N-MR1)
+    override APP_PLATFORM := android-25
+else ifeq ($(APP_PLATFORM),android-O)
+    override APP_PLATFORM := android-26
+endif
+
+endif # APP_PROJECT_PATH == null
+
+# Though the platform emits library directories for every API level, the
+# deprecated headers have gaps, and we only end up shipping libraries that match
+# a directory for which we actually have deprecated headers. We'll need to fix
+# this soon since we'll be adding O APIs to only the new headers, but for now
+# just preserve the old behavior.
+APP_PLATFORM_LEVEL := $(strip $(subst android-,,$(APP_PLATFORM)))
+ifneq (,$(filter 20,$(APP_PLATFORM_LEVEL)))
+    override APP_PLATFORM := android-19
+else ifneq (,$(filter 25,$(APP_PLATFORM_LEVEL)))
+    override APP_PLATFORM := android-24
+endif
+
+# For APP_PLATFORM values set below the minimum supported version, we could
+# either pull up or error out. Since it's very unlikely that someone actually
+# *needs* a lower platform level to build their app, we'll emit a warning and
+# pull up.
+APP_PLATFORM_LEVEL := $(strip $(subst android-,,$(APP_PLATFORM)))
+ifneq ($(call lt,$(APP_PLATFORM_LEVEL),$(NDK_MIN_PLATFORM_LEVEL)),)
+    $(call __ndk_info,$(APP_PLATFORM) is unsupported. Using minimum supported \
+        version $(NDK_MIN_PLATFORM).)
+    override APP_PLATFORM := $(NDK_MIN_PLATFORM)
+endif
+
+# There are two reasons (aside from user error) a user might have picked an API
+# level that is higher than what we support:
+#
+# 1. To get a pseudo "latest" version that will raise with each new version.
+# 2. Their using an old NDK that doesn't support the required API level.
+#
+# For 1, we now support `APP_PLATFORM := latest`, and users should just switch
+# to that.
+#
+# For 2, clamping to the maximum API level for the older NDK when a newer API
+# level is in fact needed to compile the project will just present the user with
+# a lot of unclear errors. We'll save them time by failing early.
+ifneq ($(call gt,$(APP_PLATFORM_LEVEL),$(NDK_MAX_PLATFORM_LEVEL)),)
+    $(call __ndk_info,$(APP_PLATFORM) is above the maximum supported version \
+        $(NDK_MAX_PLATFORM). Choose a supported API level or set APP_PLATFORM \
+        to "latest".)
+    $(call __ndk_error,Aborting.)
+endif
+
+# We pull low values up, fill in gaps, replace platform code names, replace
+# "latest", and error out on high values. Anything left is either a gap or
+# codename we missed, or user error.
+ifneq (,$(strip $(filter-out $(NDK_ALL_PLATFORMS),$(APP_PLATFORM))))
+    $(call __ndk_info,APP_PLATFORM set to unknown platform: $(APP_PLATFORM).)
+    $(call __ndk_error,Aborting)
+endif
+
+ifneq (null,$(APP_PROJECT_PATH))
+
+# Check platform level (after adjustment) against android:minSdkVersion in AndroidManifest.xml
+#
+APP_MANIFEST := $(strip $(wildcard $(APP_PROJECT_PATH)/AndroidManifest.xml))
+APP_PLATFORM_LEVEL := $(strip $(subst android-,,$(APP_PLATFORM)))
+ifdef APP_MANIFEST
+    _minsdkversion := $(strip \
+        $(shell $(HOST_PYTHON) $(BUILD_PY)/extract_manifest.py \
+            minSdkVersion $(call host-path,$(APP_MANIFEST))))
+    ifndef _minsdkversion
+        # minSdkVersion defaults to 1.
+        # https://developer.android.com/guide/topics/manifest/uses-sdk-element.html
+        _minsdkversion := 1
+    endif
+
+    ifneq (,$(call gt,$(APP_PLATFORM_LEVEL),$(_minsdkversion)))
+        $(call __ndk_info,WARNING: APP_PLATFORM $(APP_PLATFORM) is higher than \
+            android:minSdkVersion $(_minsdkversion) in $(APP_MANIFEST). NDK \
+            binaries will *not* be compatible with devices older than \
+            $(APP_PLATFORM). See \
+            https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md \
+            for more information.)
+    endif
+endif
+
+endif # APP_PROJECT_PATH == null
diff --git a/build/core/setup-app.mk b/build/core/setup-app.mk
new file mode 100644
index 0000000..de73403
--- /dev/null
+++ b/build/core/setup-app.mk
@@ -0,0 +1,113 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is included repeatedly from build/core/main.mk
+# and is used to prepare for app-specific build rules.
+#
+
+$(call assert-defined,_app)
+
+_map := NDK_APP.$(_app)
+
+# ok, let's parse all Android.mk source files in order to build
+# the modules for this app.
+#
+
+# Restore the APP_XXX variables just for this pass as NDK_APP_XXX
+#
+NDK_APP_NAME           := $(_app)
+NDK_APP_APPLICATION_MK := $(call get,$(_map),Application.mk)
+
+$(foreach __name,$(NDK_APP_VARS),\
+  $(eval NDK_$(__name) := $(call get,$(_map),$(__name)))\
+)
+
+# make the application depend on the modules it requires
+.PHONY: ndk-app-$(_app)
+ndk-app-$(_app): $(NDK_APP_MODULES)
+all: ndk-app-$(_app)
+
+# which platform/abi/toolchain are we going to use?
+TARGET_PLATFORM := $(call get,$(_map),APP_PLATFORM)
+
+# The ABI(s) to use
+NDK_APP_ABI := $(subst $(comma),$(space),$(strip $(NDK_APP_ABI)))
+ifndef NDK_APP_ABI
+    NDK_APP_ABI := $(NDK_DEFAULT_ABIS)
+endif
+
+NDK_ABI_FILTER := $(strip $(NDK_ABI_FILTER))
+ifdef NDK_ABI_FILTER
+    $(eval $(NDK_ABI_FILTER))
+endif
+
+# If APP_ABI is 'all', then set it to all supported ABIs
+# Otherwise, check that we don't have an invalid value here.
+#
+ifeq ($(NDK_APP_ABI),all)
+    NDK_APP_ABI := $(NDK_APP_ABI_ALL_EXPANDED)
+else ifeq ($(NDK_APP_ABI),all32)
+    NDK_APP_ABI := $(NDK_APP_ABI_ALL32_EXPANDED)
+else ifeq ($(NDK_APP_ABI),all64)
+    NDK_APP_ABI := $(NDK_APP_ABI_ALL64_EXPANDED)
+else
+    # check the target ABIs for this application
+    _bad_abis = $(strip $(filter-out $(NDK_ALL_ABIS),$(NDK_APP_ABI)))
+    ifneq ($(_bad_abis),)
+        ifneq ($(filter $(_bad_abis),armeabi-v7a-hard),)
+            $(call __ndk_info,armeabi-v7a-hard is no longer supported. Use armeabi-v7a.)
+            $(call __ndk_info,See https://android.googlesource.com/platform/ndk/+/master/docs/HardFloatAbi.md)
+        else ifneq ($(filter $(_bad_abis),armeabi),)
+            $(call __ndk_info,The armeabi ABI is no longer supported. Use armeabi-v7a.)
+        else ifneq ($(filter $(_bad_abis),mips mips64),)
+            $(call __ndk_info,MIPS and MIPS64 are no longer supported.)
+        endif
+        $(call __ndk_info,NDK Application '$(_app)' targets unknown ABI(s): $(_bad_abis))
+        $(call __ndk_info,Please fix the APP_ABI definition in $(NDK_APP_APPLICATION_MK))
+        $(call __ndk_error,Aborting)
+    endif
+endif
+
+_deprecated_abis := $(filter $(NDK_DEPRECATED_ABIS),$(NDK_APP_ABI))
+ifneq ($(_deprecated_abis),)
+    $(call __ndk_warning,Application targets deprecated ABI(s): $(_deprecated_abis))
+    $(call __ndk_warning,Support for these ABIs will be removed in a future NDK release.)
+endif
+
+# Clear all installed binaries for this application
+# This ensures that if the build fails, you're not going to mistakenly
+# package an obsolete version of it. Or if you change the ABIs you're targetting,
+# you're not going to leave a stale shared library for the old one.
+#
+ifeq ($(NDK_APP.$(_app).cleaned_binaries),)
+    NDK_APP.$(_app).cleaned_binaries := true
+    clean-installed-binaries::
+	$(hide) $(call host-rm,$(NDK_ALL_ABIS:%=$(NDK_APP_LIBS_OUT)/%/*))
+	$(hide) $(call host-rm,$(NDK_ALL_ABIS:%=$(NDK_APP_LIBS_OUT)/%/gdbserver))
+	$(hide) $(call host-rm,$(NDK_ALL_ABIS:%=$(NDK_APP_LIBS_OUT)/%/gdb.setup))
+endif
+
+# Renderscript
+
+RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,renderscript)
+RENDERSCRIPT_TOOLCHAIN_PREFIX := $(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/bin/
+RENDERSCRIPT_TOOLCHAIN_HEADER := $(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/clang-include
+RENDERSCRIPT_PLATFORM_HEADER := $(RENDERSCRIPT_TOOLCHAIN_PREBUILT_ROOT)/platform/rs
+
+# Each ABI
+$(foreach _abi,$(NDK_APP_ABI),\
+    $(eval TARGET_ARCH_ABI := $(_abi))\
+    $(eval include $(BUILD_SYSTEM)/setup-abi.mk) \
+)
diff --git a/build/core/setup-imports.mk b/build/core/setup-imports.mk
new file mode 100644
index 0000000..96fc1d5
--- /dev/null
+++ b/build/core/setup-imports.mk
@@ -0,0 +1,36 @@
+# Copyright (C) 2009-2010 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.
+#
+
+# ====================================================================
+#
+# Check the import path
+#
+# ====================================================================
+
+NDK_MODULE_PATH := $(strip $(NDK_MODULE_PATH))
+ifdef NDK_MODULE_PATH
+  ifneq ($(words $(NDK_MODULE_PATH)),1)
+    $(call __ndk_info,ERROR: You NDK_MODULE_PATH variable contains spaces)
+    $(call __ndk_info,Please fix the error and start again.)
+    $(call __ndk_error,Aborting)
+  endif
+endif
+
+$(call import-init)
+$(foreach __path,$(subst $(HOST_DIRSEP),$(space),$(NDK_MODULE_PATH)),\
+  $(call import-add-path,$(__path))\
+)
+$(call import-add-path-optional,$(NDK_ROOT)/sources)
+$(call import-add-path-optional,$(NDK_ROOT)/../development/ndk/sources)
diff --git a/build/core/setup-toolchain.mk b/build/core/setup-toolchain.mk
new file mode 100644
index 0000000..9dc2d8c
--- /dev/null
+++ b/build/core/setup-toolchain.mk
@@ -0,0 +1,222 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is included repeatedly from build/core/setup-abi.mk and is used
+# to setup the target toolchain for a given platform/abi combination.
+#
+
+$(call assert-defined,TARGET_PLATFORM TARGET_ARCH TARGET_ARCH_ABI)
+$(call assert-defined,NDK_APPS NDK_APP_STL)
+
+# Check that we have a toolchain that supports the current ABI.
+# NOTE: If NDK_TOOLCHAIN is defined, we're going to use it.
+ifndef NDK_TOOLCHAIN
+    # This is a sorted list of toolchains that support the given ABI. For older
+    # NDKs this was a bit more complicated, but now we just have the GCC and the
+    # Clang toolchains with GCC being first (named "*-4.9", whereas clang is
+    # "*-clang").
+    TARGET_TOOLCHAIN_LIST := \
+        $(strip $(sort $(NDK_ABI.$(TARGET_ARCH_ABI).toolchains)))
+
+    ifneq ($(words $(TARGET_TOOLCHAIN_LIST)),2)
+        $(call __ndk_error,Expected two items in TARGET_TOOLCHAIN_LIST, \
+            found "$(TARGET_TOOLCHAIN_LIST)")
+    endif
+
+    ifndef TARGET_TOOLCHAIN_LIST
+        $(call __ndk_info,There is no toolchain that supports the $(TARGET_ARCH_ABI) ABI.)
+        $(call __ndk_info,Please modify the APP_ABI definition in $(NDK_APP_APPLICATION_MK) to use)
+        $(call __ndk_info,a set of the following values: $(NDK_ALL_ABIS))
+        $(call __ndk_error,Aborting)
+    endif
+
+    # We default to using Clang, which is the last item in the list.
+    TARGET_TOOLCHAIN := $(lastword $(TARGET_TOOLCHAIN_LIST))
+
+    # If NDK_TOOLCHAIN_VERSION is defined, we replace the toolchain version
+    # suffix with it.
+    ifdef NDK_TOOLCHAIN_VERSION
+        # We assume the toolchain name uses dashes (-) as separators and doesn't
+        # contain any space. The following is a bit subtle, but essentially
+        # does the following:
+        #
+        #   1/ Use 'subst' to convert dashes into spaces, this generates a list
+        #   2/ Use 'chop' to remove the last element of the list
+        #   3/ Use 'subst' again to convert the spaces back into dashes
+        #
+        # So it TARGET_TOOLCHAIN is 'foo-bar-zoo-xxx', then
+        # TARGET_TOOLCHAIN_BASE will be 'foo-bar-zoo'
+        #
+        TARGET_TOOLCHAIN_BASE := \
+            $(subst $(space),-,$(call chop,$(subst -,$(space),$(TARGET_TOOLCHAIN))))
+        # if TARGET_TOOLCHAIN_BASE is llvm, remove clang from NDK_TOOLCHAIN_VERSION
+        VERSION := $(NDK_TOOLCHAIN_VERSION)
+        TARGET_TOOLCHAIN := $(TARGET_TOOLCHAIN_BASE)-$(VERSION)
+        $(call ndk_log,Using target toolchain '$(TARGET_TOOLCHAIN)' for '$(TARGET_ARCH_ABI)' ABI (through NDK_TOOLCHAIN_VERSION))
+        ifeq ($(NDK_TOOLCHAIN_VERSION),4.9)
+            $(call __ndk_info,WARNING: Deprecated NDK_TOOLCHAIN_VERSION value: \
+                $(NDK_TOOLCHAIN_VERSION). GCC is no longer supported and will \
+                be removed in the next release. See \
+                https://android.googlesource.com/platform/ndk/+/master/docs/ClangMigration.md.)
+        endif
+    else
+        $(call ndk_log,Using target toolchain '$(TARGET_TOOLCHAIN)' for '$(TARGET_ARCH_ABI)' ABI)
+    endif
+else # NDK_TOOLCHAIN is not empty
+    TARGET_TOOLCHAIN_LIST := $(strip $(filter $(NDK_TOOLCHAIN),$(NDK_ABI.$(TARGET_ARCH_ABI).toolchains)))
+    ifndef TARGET_TOOLCHAIN_LIST
+        $(call __ndk_info,The selected toolchain ($(NDK_TOOLCHAIN)) does not support the $(TARGET_ARCH_ABI) ABI.)
+        $(call __ndk_info,Please modify the APP_ABI definition in $(NDK_APP_APPLICATION_MK) to use)
+        $(call __ndk_info,a set of the following values: $(NDK_TOOLCHAIN.$(NDK_TOOLCHAIN).abis))
+        $(call __ndk_info,Or change your NDK_TOOLCHAIN definition.)
+        $(call __ndk_error,Aborting)
+    endif
+    TARGET_TOOLCHAIN := $(NDK_TOOLCHAIN)
+endif # NDK_TOOLCHAIN is not empty
+
+TARGET_ABI := $(TARGET_PLATFORM)-$(TARGET_ARCH_ABI)
+
+TARGET_PREBUILT_SHARED_LIBRARIES :=
+
+# Define default values for TOOLCHAIN_NAME, this can be overriden in
+# the setup file.
+TOOLCHAIN_NAME   := $(TARGET_TOOLCHAIN)
+TOOLCHAIN_VERSION := $(call last,$(subst -,$(space),$(TARGET_TOOLCHAIN)))
+
+# Define the root path where toolchain prebuilts are stored
+TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,$(TOOLCHAIN_NAME))
+
+# Do the same for TOOLCHAIN_PREFIX. Note that we must chop the version
+# number from the toolchain name, e.g. arm-eabi-4.4.0 -> path/bin/arm-eabi-
+# to do that, we split at dashes, remove the last element, then merge the
+# result. Finally, add the complete path prefix.
+#
+TOOLCHAIN_PREFIX := $(call merge,-,$(call chop,$(call split,-,$(TOOLCHAIN_NAME))))-
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREBUILT_ROOT)/bin/$(TOOLCHAIN_PREFIX)
+
+# We expect the gdbserver binary for this toolchain to be located at its root.
+TARGET_GDBSERVER := $(NDK_ROOT)/prebuilt/android-$(TARGET_ARCH)/gdbserver/gdbserver
+
+# compute NDK_APP_DST_DIR as the destination directory for the generated files
+NDK_APP_DST_DIR := $(NDK_APP_LIBS_OUT)/$(TARGET_ARCH_ABI)
+
+# Default build commands, can be overriden by the toolchain's setup script
+include $(BUILD_SYSTEM)/default-build-commands.mk
+
+# now call the toolchain-specific setup script
+include $(NDK_TOOLCHAIN.$(TARGET_TOOLCHAIN).setup)
+
+# Setup sysroot variables.
+# SYSROOT_INC points to a directory that contains all public header files for a
+# given platform, and SYSROOT_LINK points to libraries and object files used for
+# linking the generated target files properly.
+SYSROOT_BASE := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-$(TARGET_ARCH)
+SYSROOT_INC := $(SYSROOT_BASE)
+
+# TODO(danalbert): Use the new libraries.
+# This still points at the old tree for the libraries. We need to either:
+#
+# 1. Add crt_begin.o, libc.a, etc. to the new sysroots.
+# 2. Replace the old stub libraries with the new ones.
+#
+# Option 1 is what we will need to do long term, but will require several more
+# Soong changes. This will likely delay the release for a handful of weeks.
+# Option 2 can be done quickly. The disadvantage is that if there's anything
+# wrong with the stub libraries, we'll break everything and not just unified
+# headers. The advantage to this is that if this does break anything, it
+# probably only breaks things that are broken (libraries reporting they have
+# things they actually don't).
+SYSROOT_LINK := $(SYSROOT_BASE)
+
+ifndef NDK_UNIFIED_SYSROOT_PATH
+    NDK_UNIFIED_SYSROOT_PATH := $(NDK_ROOT)/sysroot
+endif
+SYSROOT_INC := $(NDK_UNIFIED_SYSROOT_PATH)
+
+# The compiler driver doesn't check any arch specific include locations
+# (though maybe we should add that). Architecture specific headers like asm/
+# and machine/ are installed to an arch-$ARCH subdirectory of the sysroot.
+header_triple_arm := arm-linux-androideabi
+header_triple_arm64 := aarch64-linux-android
+header_triple_mips := mipsel-linux-android
+header_triple_mips64 := mips64el-linux-android
+header_triple_x86 := i686-linux-android
+header_triple_x86_64 := x86_64-linux-android
+SYSROOT_ARCH_INC_ARG := \
+    -isystem $(SYSROOT_INC)/usr/include/$(header_triple_$(TARGET_ARCH))
+
+clean-installed-binaries::
+
+include $(BUILD_SYSTEM)/gdb.mk
+
+# free the dictionary of LOCAL_MODULE definitions
+$(call modules-clear)
+
+$(call ndk-stl-select,$(NDK_APP_STL))
+
+# now parse the Android.mk for the application, this records all
+# module declarations, but does not populate the dependency graph yet.
+include $(NDK_APP_BUILD_SCRIPT)
+
+# Avoid computing sanitizer/wrap.sh things in the DUMP_VAR case because both of
+# these will create build rules and we want to avoid that. The DUMP_VAR case
+# also doesn't parse the module definitions, so we're missing a lot of the
+# information we need.
+ifeq (,$(DUMP_VAR))
+    # Comes after NDK_APP_BUILD_SCRIPT because we need to know if *any* module
+    # has -fsanitize in its ldflags.
+    include $(BUILD_SYSTEM)/sanitizers.mk
+
+    ifneq ($(NDK_APP_WRAP_SH_$(TARGET_ARCH_ABI)),)
+        include $(BUILD_SYSTEM)/install_wrap_sh.mk
+    endif
+endif
+
+$(call ndk-stl-add-dependencies,$(NDK_APP_STL))
+
+# recompute all dependencies between modules
+$(call modules-compute-dependencies)
+
+# for debugging purpose
+ifdef NDK_DEBUG_MODULES
+$(call modules-dump-database)
+endif
+
+# now, really build the modules, the second pass allows one to deal
+# with exported values
+$(foreach __pass2_module,$(__ndk_modules),\
+    $(eval LOCAL_MODULE := $(__pass2_module))\
+    $(eval include $(BUILD_SYSTEM)/build-binary.mk)\
+)
+
+# Now compute the closure of all module dependencies.
+#
+# If APP_MODULES is not defined in the Application.mk, we
+# will build all modules that were listed from the top-level Android.mk
+# and the installable imported ones they depend on
+#
+ifeq ($(strip $(NDK_APP_MODULES)),)
+    WANTED_MODULES := $(call modules-get-all-installable,$(modules-get-top-list))
+    ifeq (,$(strip $(WANTED_MODULES)))
+        WANTED_MODULES := $(modules-get-top-list)
+        $(call ndk_log,[$(TARGET_ARCH_ABI)] No installable modules in project - forcing static library build)
+    endif
+else
+    WANTED_MODULES := $(call module-get-all-dependencies,$(NDK_APP_MODULES))
+endif
+
+$(call ndk_log,[$(TARGET_ARCH_ABI)] Modules to build: $(WANTED_MODULES))
+
+WANTED_INSTALLED_MODULES += $(call map,module-get-installed,$(WANTED_MODULES))
diff --git a/build/core/toolchains/aarch64-linux-android-4.9/config.mk b/build/core/toolchains/aarch64-linux-android-4.9/config.mk
new file mode 100644
index 0000000..79efda1
--- /dev/null
+++ b/build/core/toolchains/aarch64-linux-android-4.9/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2014 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.
+#
+
+# config file for the arm64 gcc-4.9 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := arm64
+TOOLCHAIN_ABIS := arm64-v8a
diff --git a/build/core/toolchains/aarch64-linux-android-4.9/setup.mk b/build/core/toolchains/aarch64-linux-android-4.9/setup.mk
new file mode 100644
index 0000000..5e4b776
--- /dev/null
+++ b/build/core/toolchains/aarch64-linux-android-4.9/setup.mk
@@ -0,0 +1,56 @@
+# Copyright (C) 2014 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.
+#
+
+# this file is used to prepare the NDK to build with the arm64 gcc-4.9
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+TOOLCHAIN_NAME   := aarch64-linux-android-4.9
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREBUILT_ROOT)/bin/aarch64-linux-android-
+
+TARGET_CFLAGS := \
+    -fpic \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -no-canonical-prefixes \
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS := -no-canonical-prefixes
+
+TARGET_arm64_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_arm64_debug_CFLAGS := \
+    -O0 \
+    -UNDEBUG \
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, $(__debug_sources), $(TARGET_arm64_debug_CFLAGS)) \
+$(call set-src-files-target-cflags, $(__release_sources),$(TARGET_arm64_release_CFLAGS)) \
diff --git a/build/core/toolchains/aarch64-linux-android-clang/config.mk b/build/core/toolchains/aarch64-linux-android-clang/config.mk
new file mode 100644
index 0000000..a294825
--- /dev/null
+++ b/build/core/toolchains/aarch64-linux-android-clang/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2014 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.
+#
+
+# config file for the arm64 llvm toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := arm64
+TOOLCHAIN_ABIS := arm64-v8a
diff --git a/build/core/toolchains/aarch64-linux-android-clang/setup.mk b/build/core/toolchains/aarch64-linux-android-clang/setup.mk
new file mode 100644
index 0000000..4402c7b
--- /dev/null
+++ b/build/core/toolchains/aarch64-linux-android-clang/setup.mk
@@ -0,0 +1,75 @@
+# Copyright (C) 2014 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.
+#
+
+# this file is used to prepare the NDK to build with the arm64 clang toolchain
+# any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+#
+# Override the toolchain prefix
+#
+
+TOOLCHAIN_NAME := aarch64-linux-android
+BINUTILS_ROOT := $(call get-binutils-root,$(NDK_ROOT),$(TOOLCHAIN_NAME))
+TOOLCHAIN_ROOT := $(call get-toolchain-root,$(TOOLCHAIN_NAME)-4.9)
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_ROOT)/bin/$(TOOLCHAIN_NAME)-
+
+LLVM_TRIPLE := aarch64-none-linux-android
+
+TARGET_ASAN_BASENAME := libclang_rt.asan-aarch64-android.so
+TARGET_UBSAN_BASENAME := libclang_rt.ubsan_standalone-aarch64-android.so
+
+TARGET_CFLAGS := \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -target $(LLVM_TRIPLE) \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -fpic \
+    -Wno-invalid-command-line-argument \
+    -Wno-unused-command-line-argument \
+    -no-canonical-prefixes \
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS += \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -target $(LLVM_TRIPLE) \
+    -no-canonical-prefixes \
+
+TARGET_arm64_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_arm64_debug_CFLAGS := \
+    -O0 \
+    -UNDEBUG \
+    -fno-limit-debug-info \
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, $(__debug_sources), $(TARGET_arm64_debug_CFLAGS)) \
+$(call set-src-files-target-cflags, $(__release_sources),$(TARGET_arm64_release_CFLAGS)) \
diff --git a/build/core/toolchains/arm-linux-androideabi-4.9/config.mk b/build/core/toolchains/arm-linux-androideabi-4.9/config.mk
new file mode 100644
index 0000000..ae8ce14
--- /dev/null
+++ b/build/core/toolchains/arm-linux-androideabi-4.9/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2009 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.
+#
+
+# config file for the arm gcc-4.9 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := arm
+TOOLCHAIN_ABIS := armeabi-v7a
diff --git a/build/core/toolchains/arm-linux-androideabi-4.9/setup.mk b/build/core/toolchains/arm-linux-androideabi-4.9/setup.mk
new file mode 100644
index 0000000..605f714
--- /dev/null
+++ b/build/core/toolchains/arm-linux-androideabi-4.9/setup.mk
@@ -0,0 +1,93 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is used to prepare the NDK to build with the arm gcc-4.9
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+TARGET_CFLAGS := \
+    -fpic \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -no-canonical-prefixes \
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS := -no-canonical-prefixes
+
+TARGET_CFLAGS += \
+    -march=armv7-a \
+    -mfpu=vfpv3-d16 \
+    -mfloat-abi=softfp \
+
+TARGET_LDFLAGS += \
+    -march=armv7-a \
+    -Wl,--fix-cortex-a8 \
+
+TARGET_CFLAGS.neon := -mfpu=neon
+
+TARGET_arm_release_CFLAGS := \
+    -marm \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_thumb_release_CFLAGS := \
+    -mthumb \
+    -Os \
+    -DNDEBUG \
+
+TARGET_arm_debug_CFLAGS := \
+    -marm \
+    -O0 \
+    -UNDEBUG \
+
+TARGET_thumb_debug_CFLAGS := \
+    -mthumb \
+    -O0 \
+    -UNDEBUG \
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __arm_sources := $(call get-src-files-with-tag,arm)) \
+$(eval __thumb_sources := $(call get-src-files-without-tag,arm)) \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, \
+    $(call set_intersection,$(__arm_sources),$(__debug_sources)), \
+    $(TARGET_arm_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(call set_intersection,$(__arm_sources),$(__release_sources)),\
+    $(TARGET_arm_release_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(call set_intersection,$(__thumb_sources),$(__debug_sources)),\
+    $(TARGET_thumb_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(call set_intersection,$(__thumb_sources),$(__release_sources)),\
+    $(TARGET_thumb_release_CFLAGS)) \
+$(call add-src-files-target-cflags,\
+    $(call get-src-files-with-tag,neon),\
+    $(TARGET_CFLAGS.neon)) \
+$(call set-src-files-text,$(__arm_sources),arm) \
+$(call set-src-files-text,$(__thumb_sources),thumb)
diff --git a/build/core/toolchains/arm-linux-androideabi-clang/config.mk b/build/core/toolchains/arm-linux-androideabi-clang/config.mk
new file mode 100644
index 0000000..be21fb6
--- /dev/null
+++ b/build/core/toolchains/arm-linux-androideabi-clang/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2014 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.
+#
+
+# config file for the arm llvm toolchain for the Android NDK the real meat is in
+# the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := arm
+TOOLCHAIN_ABIS := armeabi-v7a
diff --git a/build/core/toolchains/arm-linux-androideabi-clang/setup.mk b/build/core/toolchains/arm-linux-androideabi-clang/setup.mk
new file mode 100644
index 0000000..35e5018
--- /dev/null
+++ b/build/core/toolchains/arm-linux-androideabi-clang/setup.mk
@@ -0,0 +1,124 @@
+# Copyright (C) 2014 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.
+#
+
+# this file is used to prepare the NDK to build with the arm clang toolchain any
+# number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+#
+# Override the toolchain prefix
+#
+
+TOOLCHAIN_NAME := arm-linux-androideabi
+BINUTILS_ROOT := $(call get-binutils-root,$(NDK_ROOT),$(TOOLCHAIN_NAME))
+TOOLCHAIN_ROOT := $(call get-toolchain-root,$(TOOLCHAIN_NAME)-4.9)
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_ROOT)/bin/$(TOOLCHAIN_NAME)-
+
+#
+# CFLAGS and LDFLAGS
+#
+
+TARGET_ASAN_BASENAME := libclang_rt.asan-arm-android.so
+TARGET_UBSAN_BASENAME := libclang_rt.ubsan_standalone-arm-android.so
+
+TARGET_CFLAGS := \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -fpic \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -Wno-invalid-command-line-argument \
+    -Wno-unused-command-line-argument \
+    -no-canonical-prefixes
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS += \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -no-canonical-prefixes
+
+LLVM_TRIPLE := armv7-none-linux-androideabi$(APP_PLATFORM_LEVEL)
+
+TARGET_CFLAGS += -target $(LLVM_TRIPLE) \
+                 -march=armv7-a \
+                 -mfloat-abi=softfp \
+                 -mfpu=vfpv3-d16
+
+TARGET_LDFLAGS += -target $(LLVM_TRIPLE) \
+                  -Wl,--fix-cortex-a8
+
+GCCLIB_SUBDIR := armv7-a
+
+# Append the platform level for __attribute__((availability)).
+LLVM_TRIPLE := $(LLVM_TRIPLE)$(APP_PLATFORM_LEVEL)
+
+GCCLIB_ROOT := $(call get-gcclibs-path,$(NDK_ROOT),$(TOOLCHAIN_NAME))
+
+TARGET_CFLAGS.neon := -mfpu=neon
+
+TARGET_arm_release_CFLAGS := \
+    -marm \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_thumb_release_CFLAGS := \
+    -mthumb \
+    -Os \
+    -DNDEBUG \
+
+TARGET_arm_debug_CFLAGS := \
+    -marm \
+    -O0 \
+    -UNDEBUG \
+    -fno-limit-debug-info \
+
+TARGET_thumb_debug_CFLAGS := \
+    -mthumb \
+    -O0 \
+    -UNDEBUG \
+    -fno-limit-debug-info \
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __arm_sources := $(call get-src-files-with-tag,arm)) \
+$(eval __thumb_sources := $(call get-src-files-without-tag,arm)) \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, \
+    $(call set_intersection,$(__arm_sources),$(__debug_sources)), \
+    $(TARGET_arm_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(call set_intersection,$(__arm_sources),$(__release_sources)),\
+    $(TARGET_arm_release_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(call set_intersection,$(__thumb_sources),$(__debug_sources)),\
+    $(TARGET_thumb_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(call set_intersection,$(__thumb_sources),$(__release_sources)),\
+    $(TARGET_thumb_release_CFLAGS)) \
+$(call add-src-files-target-cflags,\
+    $(call get-src-files-with-tag,neon),\
+    $(TARGET_CFLAGS.neon)) \
+$(call set-src-files-text,$(__arm_sources),arm) \
+$(call set-src-files-text,$(__thumb_sources),thumb)
diff --git a/build/core/toolchains/x86-4.9/config.mk b/build/core/toolchains/x86-4.9/config.mk
new file mode 100644
index 0000000..42e6a0b
--- /dev/null
+++ b/build/core/toolchains/x86-4.9/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2009 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.
+#
+
+# config file for the x86 gcc-4.9 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := x86
+TOOLCHAIN_ABIS := x86
diff --git a/build/core/toolchains/x86-4.9/setup.mk b/build/core/toolchains/x86-4.9/setup.mk
new file mode 100644
index 0000000..7cc501a
--- /dev/null
+++ b/build/core/toolchains/x86-4.9/setup.mk
@@ -0,0 +1,61 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is used to prepare the NDK to build with the x86 gcc-4.9
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+TOOLCHAIN_NAME   := x86-4.9
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREBUILT_ROOT)/bin/i686-linux-android-
+
+TARGET_CFLAGS := \
+    -ffunction-sections \
+    -funwind-tables \
+    -no-canonical-prefixes \
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+# Add and LDFLAGS for the target here
+TARGET_LDFLAGS := -no-canonical-prefixes
+
+TARGET_CFLAGS += -fstack-protector-strong
+
+TARGET_x86_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_x86_debug_CFLAGS := \
+    -O0 \
+    -UNDEBUG \
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, $(__debug_sources), $(TARGET_x86_debug_CFLAGS)) \
+$(call set-src-files-target-cflags, $(__release_sources),$(TARGET_x86_release_CFLAGS)) \
+
+# The ABI-specific sub-directory that the SDK tools recognize for
+# this toolchain's generated binaries
+TARGET_ABI_SUBDIR := x86
diff --git a/build/core/toolchains/x86-clang/config.mk b/build/core/toolchains/x86-clang/config.mk
new file mode 100644
index 0000000..571afe0
--- /dev/null
+++ b/build/core/toolchains/x86-clang/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2014 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.
+#
+
+# config file for the x86 clang toolchain for the Android NDK the real meat is
+# in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := x86
+TOOLCHAIN_ABIS := x86
diff --git a/build/core/toolchains/x86-clang/setup.mk b/build/core/toolchains/x86-clang/setup.mk
new file mode 100644
index 0000000..d52a2b7
--- /dev/null
+++ b/build/core/toolchains/x86-clang/setup.mk
@@ -0,0 +1,81 @@
+# Copyright (C) 2014 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.
+#
+
+# this file is used to prepare the NDK to build with the x86 llvm toolchain any
+# number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+#
+# Override the toolchain prefix
+#
+
+TOOLCHAIN_NAME := i686-linux-android
+BINUTILS_ROOT := $(call get-binutils-root,$(NDK_ROOT),$(TOOLCHAIN_NAME))
+TOOLCHAIN_ROOT := $(call get-toolchain-root,x86-4.9)
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_ROOT)/bin/$(TOOLCHAIN_NAME)-
+
+LLVM_TRIPLE := i686-none-linux-android
+
+TARGET_ASAN_BASENAME := libclang_rt.asan-i686-android.so
+TARGET_UBSAN_BASENAME := libclang_rt.ubsan_standalone-i686-android.so
+
+TARGET_CFLAGS := \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -target $(LLVM_TRIPLE) \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -fPIC \
+    -Wno-invalid-command-line-argument \
+    -Wno-unused-command-line-argument \
+    -no-canonical-prefixes
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+# Add and LDFLAGS for the target here
+TARGET_LDFLAGS += \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -target $(LLVM_TRIPLE) \
+    -no-canonical-prefixes
+
+TARGET_x86_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+# When building for debug, compile everything as x86.
+TARGET_x86_debug_CFLAGS := \
+    -O0 \
+    -UNDEBUG \
+    -fno-limit-debug-info \
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, $(__debug_sources), $(TARGET_x86_debug_CFLAGS)) \
+$(call set-src-files-target-cflags, $(__release_sources),$(TARGET_x86_release_CFLAGS)) \
+
+# The ABI-specific sub-directory that the SDK tools recognize for
+# this toolchain's generated binaries
+TARGET_ABI_SUBDIR := x86
diff --git a/build/core/toolchains/x86_64-4.9/config.mk b/build/core/toolchains/x86_64-4.9/config.mk
new file mode 100644
index 0000000..e3ec61d
--- /dev/null
+++ b/build/core/toolchains/x86_64-4.9/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2009 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.
+#
+
+# config file for the x86_64 gcc-4.9 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := x86_64
+TOOLCHAIN_ABIS := x86_64
diff --git a/build/core/toolchains/x86_64-4.9/setup.mk b/build/core/toolchains/x86_64-4.9/setup.mk
new file mode 100644
index 0000000..a9525b8
--- /dev/null
+++ b/build/core/toolchains/x86_64-4.9/setup.mk
@@ -0,0 +1,59 @@
+# Copyright (C) 2009 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.
+#
+
+# this file is used to prepare the NDK to build with the x86_64 gcc-4.9
+# toolchain any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+TOOLCHAIN_NAME   := x86_64-4.9
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_PREBUILT_ROOT)/bin/x86_64-linux-android-
+
+TARGET_CFLAGS := \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -no-canonical-prefixes \
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS := -no-canonical-prefixes
+
+TARGET_x86_64_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_x86_64_debug_CFLAGS := \
+    -O0 \
+    -UNDEBUG \
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, $(__debug_sources), $(TARGET_x86_64_debug_CFLAGS)) \
+$(call set-src-files-target-cflags, $(__release_sources),$(TARGET_x86_64_release_CFLAGS)) \
+
+# The ABI-specific sub-directory that the SDK tools recognize for
+# this toolchain's generated binaries
+TARGET_ABI_SUBDIR := x86_64
diff --git a/build/core/toolchains/x86_64-clang/config.mk b/build/core/toolchains/x86_64-clang/config.mk
new file mode 100644
index 0000000..0a00f90
--- /dev/null
+++ b/build/core/toolchains/x86_64-clang/config.mk
@@ -0,0 +1,20 @@
+# Copyright (C) 2014 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.
+#
+
+# config file for the x86_64 clang toolchain for the Android NDK the real meat
+# is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := x86_64
+TOOLCHAIN_ABIS := x86_64
diff --git a/build/core/toolchains/x86_64-clang/setup.mk b/build/core/toolchains/x86_64-clang/setup.mk
new file mode 100644
index 0000000..e442765
--- /dev/null
+++ b/build/core/toolchains/x86_64-clang/setup.mk
@@ -0,0 +1,79 @@
+# Copyright (C) 2014 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.
+#
+
+# this file is used to prepare the NDK to build with the x86_64 llvm toolchain
+# any number of source files
+#
+# its purpose is to define (or re-define) templates used to build
+# various sources into target object files, libraries or executables.
+#
+# Note that this file may end up being parsed several times in future
+# revisions of the NDK.
+#
+
+#
+# Override the toolchain prefix
+#
+
+TOOLCHAIN_NAME := x86_64-linux-android
+BINUTILS_ROOT := $(call get-binutils-root,$(NDK_ROOT),$(TOOLCHAIN_NAME))
+TOOLCHAIN_ROOT := $(call get-toolchain-root,x86_64-4.9)
+TOOLCHAIN_PREFIX := $(TOOLCHAIN_ROOT)/bin/$(TOOLCHAIN_NAME)-
+
+LLVM_TRIPLE := x86_64-none-linux-android
+
+TARGET_ASAN_BASENAME := libclang_rt.asan-x86_64-android.so
+TARGET_UBSAN_BASENAME := libclang_rt.ubsan_standalone-x86_64-android.so
+
+TARGET_CFLAGS := \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -target $(LLVM_TRIPLE) \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -fPIC \
+    -Wno-invalid-command-line-argument \
+    -Wno-unused-command-line-argument \
+    -no-canonical-prefixes \
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS += \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -target $(LLVM_TRIPLE) \
+    -no-canonical-prefixes \
+
+TARGET_x86_64_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_x86_64_debug_CFLAGS := \
+    -O0 \
+    -UNDEBUG \
+    -fno-limit-debug-info \
+
+# This function will be called to determine the target CFLAGS used to build
+# a C or Assembler source file, based on its tags.
+#
+TARGET-process-src-files-tags = \
+$(eval __debug_sources := $(call get-src-files-with-tag,debug)) \
+$(eval __release_sources := $(call get-src-files-without-tag,debug)) \
+$(call set-src-files-target-cflags, $(__debug_sources), $(TARGET_x86_64_debug_CFLAGS)) \
+$(call set-src-files-target-cflags, $(__release_sources),$(TARGET_x86_64_release_CFLAGS)) \
+
+# The ABI-specific sub-directory that the SDK tools recognize for
+# this toolchain's generated binaries
+TARGET_ABI_SUBDIR := x86_64
diff --git a/build/extract_manifest.py b/build/extract_manifest.py
new file mode 100644
index 0000000..82e379d
--- /dev/null
+++ b/build/extract_manifest.py
@@ -0,0 +1,106 @@
+#
+# 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.
+#
+"""Extracts values from the AndroidManifest.xml file."""
+import argparse
+import os.path
+import xml.etree.ElementTree
+
+
+def parse_args():
+    """Parse and return command line arguments."""
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument(
+        'property', metavar='PROPERTY',
+        choices=('minSdkVersion', 'debuggable'),
+        help='Property to extract from the manifest file.')
+
+    parser.add_argument(
+        'manifest_file', metavar='MANIFEST_FILE', type=os.path.abspath,
+        help='Path to the AndroidManifest.xml file.')
+
+    return parser.parse_args()
+
+
+def get_rpath_attribute(root, element_path, attribute, default=None):
+    """Returns the value of an attribute at an rpath.
+
+    If more than one element exists with the same name, only the first is
+    checked.
+
+    Args:
+        root: The XML element to search from.
+        path: The path to the element.
+        attribute: The name of the attribute to fetch.
+
+    Returns:
+        The attribute's value as a string if found, else the value of
+        `default`.
+    """
+    ns_url = 'http://schemas.android.com/apk/res/android'
+    ns = {
+        'android': ns_url,
+    }
+
+    elem = root.find(element_path, ns)
+    if elem is None:
+        return ''
+    # ElementTree elements don't have the same helpful namespace parameter that
+    # the find family does :(
+    attrib_name = attribute.replace('android:', '{' + ns_url + '}')
+    return elem.get(attrib_name, default)
+
+
+def get_minsdkversion(root):
+    """Finds and returns the value of android:minSdkVersion in the manifest.
+
+    Returns:
+        String form of android:minSdkVersion if found, else the empty string.
+    """
+    return get_rpath_attribute(root, './uses-sdk', 'android:minSdkVersion', '')
+
+
+def get_debuggable(root):
+    """Finds and returns the value of android:debuggable in the manifest.
+
+    Returns:
+        String form of android:debuggable if found, else the empty string.
+    """
+    debuggable = get_rpath_attribute(
+        root, './application', 'android:debuggable', '')
+
+    # Though any such manifest would be invalid, the awk script rewrote bogus
+    # values to false. Missing attributes should also be false.
+    if debuggable != 'true':
+        debuggable = 'false'
+
+    return debuggable
+
+
+def main():
+    args = parse_args()
+
+    tree = xml.etree.ElementTree.parse(args.manifest_file)
+    if args.property == 'minSdkVersion':
+        print get_minsdkversion(tree.getroot())
+    elif args.property == 'debuggable':
+        print get_debuggable(tree.getroot())
+    else:
+        raise ValueError
+
+
+if __name__ == '__main__':
+    main()
diff --git a/build/extract_platform.py b/build/extract_platform.py
new file mode 100644
index 0000000..5332e66
--- /dev/null
+++ b/build/extract_platform.py
@@ -0,0 +1,71 @@
+#
+# 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.
+#
+"""Extracts the platform version from the project.properties file."""
+import argparse
+import os.path
+import re
+
+
+def parse_args():
+    """Parse and return command line arguments."""
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument(
+        'properties_file', metavar='PROPERTIES_FILE', type=os.path.abspath,
+        help='Path to the project.properties file.')
+
+    return parser.parse_args()
+
+
+def get_platform(properties_file):
+    """Finds and returns the platform version in the properties file.
+
+    Returns:
+        String form of the platform version if found, else "unknown".
+    """
+    android_regex = re.compile(r'(android-\w+)')
+    vendor_regex = re.compile(r':(\d+)\s*$')
+    for line in properties_file:
+        match = android_regex.search(line)
+        if match is not None:
+            return match.group(1)
+        match = vendor_regex.search(line)
+        if match is not None:
+            return 'android-{}'.format(match.group(1))
+    return 'unknown'
+
+
+def main():
+    args = parse_args()
+
+    # Following the comment in the old awk script, we're trying to match:
+    #
+    #    target=android-<api>
+    #    target=<vendor>:<name>:<api>
+    #
+    # There unfortunately aren't any examples of what the vendor target
+    # specification actually looks like or where it might be used, so we'll
+    # just have to mirror the simplistic match that was in the awk script.
+    #
+    # android- may be followed by either the numeric API level or the named
+    # platform. Note that while we can parse any name, ndk-build only support a
+    # small handful.
+    with open(args.properties_file) as properties_file:
+        print get_platform(properties_file)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/build/gen_cygpath.py b/build/gen_cygpath.py
new file mode 100644
index 0000000..54ffce4
--- /dev/null
+++ b/build/gen_cygpath.py
@@ -0,0 +1,100 @@
+#
+# 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.
+#
+"""Generates a make function approximating cygpath.
+
+We don't just call cygpath (unless directed by NDK_USE_CYGPATH=1) because we
+have to call this very often and doing so would be very slow. By doing this in
+make, we can be much faster.
+"""
+import posixpath
+import re
+import sys
+
+
+def get_mounts(mount_output):
+    """Parses the output of mount and returns a dict of mounts.
+
+    Args:
+        mount_output: The text output from mount(1).
+
+    Returns:
+        A list of tuples mapping cygwin paths to Windows paths.
+    """
+    mount_regex = re.compile(r'^(\S+) on (\S+) .*$')
+
+    # We use a list of tuples rather than a dict because we want to recurse on
+    # the list later anyway.
+    mounts = []
+    for line in mount_output.splitlines():
+        # Cygwin's mount doesn't use backslashes even in Windows paths, so no
+        # need to replace here.
+        match = mount_regex.search(line)
+        if match is not None:
+            win_path = match.group(1)
+            cyg_path = match.group(2)
+            if cyg_path == '/':
+                # Since we're going to be using patsubst on these, we need to
+                # make sure that the rule for / is applied last, otherwise
+                # we'll replace all other cygwin paths with that one.
+                mounts.insert(0, (cyg_path, win_path))
+            elif cyg_path.startswith('/cygdrive/'):
+                # We need both /cygdrive/c and /cygdrive/C to point to C:.
+                letter = posixpath.basename(cyg_path)
+                lower_path = posixpath.join('/cygdrive', letter.lower())
+                upper_path = posixpath.join('/cygdrive', letter.upper())
+                mounts.append((lower_path, win_path))
+                mounts.append((upper_path, win_path))
+            else:
+                mounts.append((cyg_path, win_path))
+
+    return mounts
+
+
+def make_cygpath_function(mounts):
+    """Creates a make function that can be used in place of cygpath.
+
+    Args:
+        mounts: A list of tuples decribing filesystem mounts.
+
+    Returns:
+        The body of a function implementing cygpath in make as a string.
+    """
+    # We're building a bunch of nested patsubst calls. Once we've written each
+    # of the calls, we pass the function input to the inner most call.
+    if len(mounts) == 0:
+        return '$1'
+
+    cyg_path, win_path = mounts[0]
+    if not cyg_path.endswith('/'):
+        cyg_path += '/'
+    if not win_path.endswith('/'):
+        win_path += '/'
+
+    other_mounts = mounts[1:]
+    return '$(patsubst {}%,{}%,\n{})'.format(
+        cyg_path, win_path, make_cygpath_function(other_mounts))
+
+
+def main():
+    # We're invoked from make and piped the output of `mount` so we can
+    # determine what mappings to make.
+    mount_output = sys.stdin.read()
+    mounts = get_mounts(mount_output)
+    print make_cygpath_function(mounts)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/build/gmsl/README b/build/gmsl/README
new file mode 100644
index 0000000..152ada6
--- /dev/null
+++ b/build/gmsl/README
@@ -0,0 +1,27 @@
+GNU Make Standard Library
+-------------------------
+
+1. Visit http://gmsl.sf.net for more details
+
+2. To use the GMSL in your Makefile make sure that you have the files
+
+   gmsl
+   __gmsl
+
+   Add 
+
+   include gmsl
+
+   to your Makefile(s).
+
+3. To run the GMSL test suite have 
+
+   gmsl
+   __gmsl
+   gmsl-tests
+
+   And then run
+
+   make -f gmsl-tests
+
+ 
\ No newline at end of file
diff --git a/build/gmsl/__gmsl b/build/gmsl/__gmsl
new file mode 100644
index 0000000..596ff19
--- /dev/null
+++ b/build/gmsl/__gmsl
@@ -0,0 +1,854 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL)
+#
+# A library of functions to be used with GNU Make's $(call) that
+# provides functionality not available in standard GNU Make.
+#
+# Copyright (c) 2005-2007 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 
+# Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# Neither the name of the John Graham-Cumming nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# ----------------------------------------------------------------------------
+
+# This is the GNU Make Standard Library version number as a list with
+# three items: major, minor, revision
+
+gmsl_version := 1 0 11
+
+# Used to output warnings and error from the library, it's possible to
+# disable any warnings or errors by overriding these definitions
+# manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS
+
+__gmsl_name := GNU Make Standard Library
+__gmsl_warning = $(warning $(__gmsl_name): $1)
+__gmsl_error = $(error $(__gmsl_name): $1)
+
+ifdef GMSL_NO_WARNINGS
+__gmsl_warning :=
+endif
+ifdef GMSL_NO_ERRORS
+__gmsl_error :=
+endif
+
+# If GMSL_TRACE is enabled then calls to the library functions are
+# traced to stdout using warning messages with their arguments
+
+ifdef GMSL_TRACE
+__gmsl_tr1 = $(warning $0('$1'))
+__gmsl_tr2 = $(warning $0('$1','$2'))
+__gmsl_tr3 = $(warning $0('$1','$2','$3'))
+else
+__gmsl_tr1 :=
+__gmsl_tr2 :=
+__gmsl_tr3 :=
+endif
+
+# Figure out whether we have $(eval) or not (GNU Make 3.80 and above)
+# if we do not then output a warning message, if we do then some
+# functions will be enabled.
+
+__gmsl_have_eval := $(false)
+__gmsl_ignore := $(eval __gmsl_have_eval := $(true))
+
+# If this is being run with Electric Cloud's emake then warn that
+# their $(eval) support is incomplete.
+
+ifdef ECLOUD_BUILD_ID
+$(warning You are using Electric Cloud's emake which has incomplete $$(eval) support)
+__gmsl_have_eval := $(false)
+endif
+
+# See if we have $(lastword) (GNU Make 3.81 and above)
+
+__gmsl_have_lastword := $(lastword $(false) $(true))
+
+# See if we have native or and and (GNU Make 3.81 and above)
+
+__gmsl_have_or := $(if $(filter-out undefined,  \
+    $(origin or)),$(call or,$(true),$(false)))
+__gmsl_have_and := $(if $(filter-out undefined, \
+    $(origin and)),$(call and,$(true),$(true)))
+
+ifneq ($(__gmsl_have_eval),$(true))
+$(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$$$(eval): some functions disabled)
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  gmsl_compatible
+# Arguments: List containing the desired library version number (maj min rev)
+# Returns:   $(true) if this version of the library is compatible
+#            with the requested version number, otherwise $(false)
+# ----------------------------------------------------------------------------
+gmsl_compatible = $(strip                                                 \
+    $(if $(call gt,$(word 1,$1),$(word 1,$(gmsl_version))),               \
+        $(false),                                                         \
+        $(if $(call lt,$(word 1,$1),$(word 1,$(gmsl_version))),           \
+            $(true),                                                      \
+            $(if $(call gt,$(word 2,$1),$(word 2,$(gmsl_version))),       \
+                $(false),                                                 \
+                $(if $(call lt,$(word 2,$1),$(word 2,$(gmsl_version))),   \
+                    $(true),                                              \
+                    $(call lte,$(word 3,$1),$(word 3,$(gmsl_version))))))))
+
+# ###########################################################################
+# LOGICAL OPERATORS
+# ###########################################################################
+
+# not is defined in gmsl
+
+# ----------------------------------------------------------------------------
+# Function:  and
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if both of the booleans are true
+# ----------------------------------------------------------------------------
+ifneq ($(__gmsl_have_and),$(true))
+and = $(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(false))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  or
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if either of the booleans is true
+# ----------------------------------------------------------------------------
+ifneq ($(__gmsl_have_or),$(true))
+or = $(__gmsl_tr2)$(if $1$2,$(true),$(false))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  xor
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if exactly one of the booleans is true
+# ----------------------------------------------------------------------------
+xor = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(if $2,$(true),$(false)))
+
+# ----------------------------------------------------------------------------
+# Function:  nand
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not and'
+# ----------------------------------------------------------------------------
+nand = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  nor
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not or'
+# ----------------------------------------------------------------------------
+nor = $(__gmsl_tr2)$(if $1$2,$(false),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  xnor
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not xor'
+# ----------------------------------------------------------------------------
+xnor =$(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(if $2,$(false),$(true)))
+
+# ###########################################################################
+# LIST MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  first (same as LISP's car, or head)
+# Arguments: 1: A list
+# Returns:   Returns the first element of a list
+# ----------------------------------------------------------------------------
+first = $(__gmsl_tr1)$(firstword $1)
+
+# ----------------------------------------------------------------------------
+# Function:  last
+# Arguments: 1: A list
+# Returns:   Returns the last element of a list
+# ----------------------------------------------------------------------------
+ifeq ($(__gmsl_have_lastword),$(true))
+last = $(__gmsl_tr1)$(lastword $1)
+else
+last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  rest (same as LISP's cdr, or tail)
+# Arguments: 1: A list
+# Returns:   Returns the list with the first element removed
+# ----------------------------------------------------------------------------
+rest = $(__gmsl_tr1)$(wordlist 2,$(words $1),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  chop
+# Arguments: 1: A list
+# Returns:   Returns the list with the last element removed
+# ----------------------------------------------------------------------------
+chop = $(__gmsl_tr1)$(wordlist 2,$(words $1),x $1)
+
+# ----------------------------------------------------------------------------
+# Function:  map
+# Arguments: 1: Name of function to $(call) for each element of list
+#            2: List to iterate over calling the function in 1
+# Returns:   The list after calling the function on each element
+# ----------------------------------------------------------------------------
+map = $(__gmsl_tr2)$(strip $(foreach a,$2,$(call $1,$a)))
+
+# ----------------------------------------------------------------------------
+# Function:  pairmap
+# Arguments: 1: Name of function to $(call) for each pair of elements
+#            2: List to iterate over calling the function in 1
+#            3: Second list to iterate over calling the function in 1
+# Returns:   The list after calling the function on each pair of elements
+# ----------------------------------------------------------------------------
+pairmap = $(strip $(__gmsl_tr3)\
+          $(if $2$3,$(call $1,$(call first,$2),$(call first,$3))     \
+                        $(call pairmap,$1,$(call rest,$2),$(call rest,$3))))
+
+# ----------------------------------------------------------------------------
+# Function:  leq
+# Arguments: 1: A list to compare against...
+#            2: ...this list
+# Returns:   Returns $(true) if the two lists are identical
+# ----------------------------------------------------------------------------
+leq = $(__gmsl_tr2)$(strip $(if $(call seq,$(words $1),$(words $2)),     \
+          $(call __gmsl_list_equal,$1,$2),$(false)))
+
+__gmsl_list_equal = $(if $(strip $1),                                       \
+                        $(if $(call seq,$(call first,$1),$(call first,$2)), \
+                            $(call __gmsl_list_equal,                       \
+                                $(call rest,$1),                            \
+                                $(call rest,$2)),                           \
+                            $(false)),                                      \
+                     $(true))
+
+# ----------------------------------------------------------------------------
+# Function:  lne
+# Arguments: 1: A list to compare against...
+#            2: ...this list
+# Returns:   Returns $(true) if the two lists are different
+# ----------------------------------------------------------------------------
+lne = $(__gmsl_tr2)$(call not,$(call leq,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  reverse
+# Arguments: 1: A list to reverse
+# Returns:   The list with its elements in reverse order
+# ----------------------------------------------------------------------------
+reverse =$(__gmsl_tr1)$(strip $(if $1,$(call reverse,$(call rest,$1)) \
+                        $(call first,$1)))
+
+# ----------------------------------------------------------------------------
+# Function:  uniq
+# Arguments: 1: A list from which to remove repeated elements
+# Returns:   The list with duplicate elements removed without reordering
+# ----------------------------------------------------------------------------
+uniq = $(strip $(__gmsl_tr1)$(if $1,$(call uniq,$(call chop,$1)) \
+            $(if $(filter $(call last,$1),$(call chop,$1)),,$(call last,$1))))
+
+# ----------------------------------------------------------------------------
+# Function:  length
+# Arguments: 1: A list
+# Returns:   The number of elements in the list
+# ----------------------------------------------------------------------------
+length = $(__gmsl_tr1)$(words $1)
+
+# ###########################################################################
+# STRING MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# Helper function that translates any GNU Make 'true' value (i.e. a
+# non-empty string) to our $(true)
+
+__gmsl_make_bool = $(if $(strip $1),$(true),$(false))
+
+# ----------------------------------------------------------------------------
+# Function:  seq
+# Arguments: 1: A string to compare against...
+#            2: ...this string
+# Returns:   Returns $(true) if the two strings are identical
+# ----------------------------------------------------------------------------
+seq = $(__gmsl_tr2)$(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),$(false),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  sne
+# Arguments: 1: A string to compare against...
+#            2: ...this string
+# Returns:   Returns $(true) if the two strings are not the same
+# ----------------------------------------------------------------------------
+sne = $(__gmsl_tr2)$(call not,$(call seq,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  split
+# Arguments: 1: The character to split on
+#            2: A string to split
+# Returns:   Splits a string into a list separated by spaces at the split
+#            character in the first argument
+# ----------------------------------------------------------------------------
+split = $(__gmsl_tr2)$(strip $(subst $1, ,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  merge
+# Arguments: 1: The character to put between fields
+#            2: A list to merge into a string
+# Returns:   Merges a list into a single string, list elements are separated
+#            by the character in the first argument
+# ----------------------------------------------------------------------------
+merge = $(__gmsl_tr2)$(strip $(if $2,                                     \
+            $(if $(call seq,1,$(words $2)),                               \
+                $2,$(call first,$2)$1$(call merge,$1,$(call rest,$2)))))
+
+ifdef __gmsl_have_eval
+# ----------------------------------------------------------------------------
+# Function:  tr
+# Arguments: 1: The list of characters to translate from 
+#            2: The list of characters to translate to
+#            3: The text to translate
+# Returns:   Returns the text after translating characters
+# ----------------------------------------------------------------------------
+tr = $(strip $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)              \
+     $(eval __gmsl_t := $3)                                               \
+     $(foreach c,                                                         \
+         $(join $(addsuffix :,$1),$2),                                    \
+         $(eval __gmsl_t :=                                               \
+             $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \
+                 $(__gmsl_t))))$(__gmsl_t))
+
+# Common character classes for use with the tr function.  Each of
+# these is actually a variable declaration and must be wrapped with
+# $() or ${} to be used.
+
+[A-Z] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z #
+[a-z] := a b c d e f g h i j k l m n o p q r s t u v w x y z #
+[0-9] := 0 1 2 3 4 5 6 7 8 9 #
+[A-F] := A B C D E F #
+
+# ----------------------------------------------------------------------------
+# Function:  uc
+# Arguments: 1: Text to upper case
+# Returns:   Returns the text in upper case
+# ----------------------------------------------------------------------------
+uc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([a-z]),$([A-Z]),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  lc
+# Arguments: 1: Text to lower case
+# Returns:   Returns the text in lower case
+# ----------------------------------------------------------------------------
+lc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([A-Z]),$([a-z]),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  strlen
+# Arguments: 1: A string
+# Returns:   Returns the length of the string
+# ----------------------------------------------------------------------------
+__gmsl_characters := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+__gmsl_characters += a b c d e f g h i j k l m n o p q r s t u v w x y z
+__gmsl_characters += 0 1 2 3 4 5 6 7 8 9
+__gmsl_characters += ` ~ ! @ \# $$ % ^ & * ( ) - _ = +
+__gmsl_characters += { } [ ] \ : ; ' " < > , . / ? |
+
+# Aside: if you read the above you might think that the lower-case
+# letter x is missing, and that that's an error.  It is missing, but
+# it's not an error.  __gmsl_characters is used by the strlen
+# function.  strlen works by transforming every character and space
+# into the letter x and then counting the x's.  Since there's no need
+# to transform x into x I omitted it.
+
+# This results in __gmsl_space containing just a space
+
+__gmsl_space := 
+__gmsl_space +=
+
+strlen = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(eval __temp := $(subst $(__gmsl_space),x,$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,x,$(__temp))))$(eval __temp := $(subst x,x ,$(__temp)))$(words $(__temp)))
+
+# This results in __gmsl_newline containing just a newline
+
+define __gmsl_newline
+
+
+endef
+
+# This results in __gmsl_tab containing a tab
+
+__gmsl_tab :=	#
+
+# ----------------------------------------------------------------------------
+# Function:  substr
+# Arguments: 1: A string
+# 	     2: Start position (first character is 1)
+#	     3: End position (inclusive)
+# Returns:   A substring.  
+# Note:      The string in $1 must not contain a §
+# ----------------------------------------------------------------------------
+
+substr = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(strip $(eval __temp := $$(subst $$(__gmsl_space),§ ,$$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,$$a$$(__gmsl_space),$(__temp))))$(eval __temp := $(wordlist $2,$3,$(__temp))))$(subst §,$(__gmsl_space),$(subst $(__gmsl_space),,$(__temp)))
+
+endif # __gmsl_have_eval
+
+# ###########################################################################
+# SET MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# Sets are represented by sorted, deduplicated lists.  To create a set
+# from a list use set_create, or start with the empty_set and
+# set_insert individual elements
+
+# This is the empty set
+empty_set := 
+
+# ----------------------------------------------------------------------------
+# Function:  set_create
+# Arguments: 1: A list of set elements
+# Returns:   Returns the newly created set
+# ----------------------------------------------------------------------------
+set_create = $(__gmsl_tr1)$(sort $1)
+
+# ----------------------------------------------------------------------------
+# Function:  set_insert
+# Arguments: 1: A single element to add to a set
+#            2: A set
+# Returns:   Returns the set with the element added
+# ----------------------------------------------------------------------------
+set_insert = $(__gmsl_tr2)$(sort $1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_remove
+# Arguments: 1: A single element to remove from a set
+#            2: A set
+# Returns:   Returns the set with the element removed
+# ----------------------------------------------------------------------------
+set_remove = $(__gmsl_tr2)$(filter-out $1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_is_member
+# Arguments: 1: A single element 
+#            2: A set
+# Returns:   Returns $(true) if the element is in the set
+# ----------------------------------------------------------------------------
+set_is_member = $(__gmsl_tr2)$(if $(filter $1,$2),$(true),$(false))
+
+# ----------------------------------------------------------------------------
+# Function:  set_union
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns the union of the two sets
+# ----------------------------------------------------------------------------
+set_union = $(__gmsl_tr2)$(sort $1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_intersection
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns the intersection of the two sets
+# ----------------------------------------------------------------------------
+set_intersection = $(__gmsl_tr2)$(filter $1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_is_subset
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns $(true) if the first set is a subset of the second
+# ----------------------------------------------------------------------------
+set_is_subset = $(__gmsl_tr2)$(call set_equal,$(call set_intersection,$1,$2),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  set_equal
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns $(true) if the two sets are identical
+# ----------------------------------------------------------------------------
+set_equal = $(__gmsl_tr2)$(call seq,$1,$2)
+
+# ###########################################################################
+# ARITHMETIC LIBRARY
+# ###########################################################################
+
+# Integers a represented by lists with the equivalent number of x's.
+# For example the number 4 is x x x x.  The maximum integer that the
+# library can handle as _input_ is __gmsl_input_int which is defined
+# here as 65536
+
+__gmsl_sixteen := x x x x x x x x x x x x x x x x
+__gmsl_input_int := $(foreach a,$(__gmsl_sixteen),         \
+                        $(foreach b,$(__gmsl_sixteen),     \
+                            $(foreach c,$(__gmsl_sixteen), \
+                                $(__gmsl_sixteen)))))
+
+# ----------------------------------------------------------------------------
+# Function:  int_decode
+# Arguments: 1: A number of x's representation
+# Returns:   Returns the integer for human consumption that is represented
+#            by the string of x's
+# ----------------------------------------------------------------------------
+int_decode = $(__gmsl_tr1)$(words $1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_encode
+# Arguments: 1: A number in human-readable integer form
+# Returns:   Returns the integer encoded as a string of x's
+# ----------------------------------------------------------------------------
+int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int))
+
+# The arithmetic library functions come in two forms: one form of each
+# function takes integers as arguments and the other form takes the
+# encoded form (x's created by a call to int_encode).  For example,
+# there are two plus functions:
+#
+# plus        Called with integer arguments and returns an integer
+# int_plus    Called with encoded arguments and returns an encoded result
+#
+# plus will be slower than int_plus because its arguments and result
+# have to be translated between the x's format and integers.  If doing
+# a complex calculation use the int_* forms with a single encoding of
+# inputs and single decoding of the output.  For simple calculations
+# the direct forms can be used.
+
+# Helper function used to wrap an int_* function into a function that
+# takes a pair of integers, perhaps a function and returns an integer
+# result
+__gmsl_int_wrap = $(call int_decode,$(call $1,$(call int_encode,$2),$(call int_encode,$3)))
+__gmsl_int_wrap1 = $(call int_decode,$(call $1,$(call int_encode,$2)))
+__gmsl_int_wrap2 = $(call $1,$(call int_encode,$2),$(call int_encode,$3))
+
+# ----------------------------------------------------------------------------
+# Function:  int_plus
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the sum of the two numbers in x's representation
+# ----------------------------------------------------------------------------
+int_plus = $(strip $(__gmsl_tr2)$1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  plus (wrapped version of int_plus)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the sum of the two integers
+# ----------------------------------------------------------------------------
+plus = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_plus,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_subtract
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the difference of the two numbers in x's representation,
+#            or outputs an error on a numeric underflow
+# ----------------------------------------------------------------------------
+int_subtract = $(strip $(__gmsl_tr2)$(if $(call int_gte,$1,$2), \
+                $(filter-out xx,$(join $1,$2)),                 \
+                $(call __gmsl_warning,Subtraction underflow)))
+
+# ----------------------------------------------------------------------------
+# Function:  subtract (wrapped version of int_subtract)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the difference of the two integers,
+#            or outputs an error on a numeric underflow
+# ----------------------------------------------------------------------------
+subtract = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_subtract,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_multiply
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the product of the two numbers in x's representation
+# ----------------------------------------------------------------------------
+int_multiply = $(strip $(__gmsl_tr2)$(foreach a,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  multiply (wrapped version of int_multiply)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the product of the two integers
+# ----------------------------------------------------------------------------
+multiply = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_multiply,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_divide
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the result of integer division of argument 1 divided
+#            by argument 2 in x's representation
+# ----------------------------------------------------------------------------
+int_divide = $(__gmsl_tr2)$(strip $(if $2,                                 \
+                 $(if $(call int_gte,$1,$2),                               \
+                     x $(call int_divide,$(call int_subtract,$1,$2),$2),), \
+                 $(call __gmsl_error,Division by zero)))
+
+# ----------------------------------------------------------------------------
+# Function:  divide (wrapped version of int_divide)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the integer division of the first argument by the second
+# ----------------------------------------------------------------------------
+divide = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_divide,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_max, int_min
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the maximum or minimum of its arguments in x's
+#            representation
+# ----------------------------------------------------------------------------
+int_max = $(__gmsl_tr2)$(subst xx,x,$(join $1,$2))
+int_min = $(__gmsl_tr2)$(subst xx,x,$(filter xx,$(join $1,$2)))
+
+# ----------------------------------------------------------------------------
+# Function:  max, min
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the maximum or minimum of its integer arguments
+# ----------------------------------------------------------------------------
+max = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_max,$1,$2)
+min = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_min,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function: int_gt, int_gte, int_lt, int_lte, int_eq, int_ne
+# Arguments: Two x's representation numbers to be compared
+# Returns:   $(true) or $(false)
+#
+# int_gt    First argument greater than second argument
+# int_gte   First argument greater than or equal to second argument
+# int_lt    First argument less than second argument 
+# int_lte   First argument less than or equal to second argument
+# int_eq    First argument is numerically equal to the second argument
+# int_ne    First argument is not numerically equal to the second argument
+# ----------------------------------------------------------------------------
+int_gt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $2), \
+                              $(words $(call int_max,$1,$2))))
+int_gte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
+                           $(call int_gt,$1,$2)$(call int_eq,$1,$2))
+int_lt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $1), \
+                              $(words $(call int_max,$1,$2))))
+int_lte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
+                           $(call int_lt,$1,$2)$(call int_eq,$1,$2))
+int_eq = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter $(words $1),$(words $2)))
+int_ne = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $1),$(words $2)))
+
+# ----------------------------------------------------------------------------
+# Function: gt, gte, lt, lte, eq, ne
+# Arguments: Two integers to be compared
+# Returns:   $(true) or $(false)
+#
+# gt    First argument greater than second argument
+# gte   First argument greater than or equal to second argument
+# lt    First argument less than second argument 
+# lte   First argument less than or equal to second argument
+# eq    First argument is numerically equal to the second argument
+# ne    First argument is not numerically equal to the second argument
+# ----------------------------------------------------------------------------
+gt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gt,$1,$2)
+gte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gte,$1,$2)
+lt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lt,$1,$2)
+lte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lte,$1,$2)
+eq = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_eq,$1,$2)
+ne = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_ne,$1,$2)
+
+# increment adds 1 to its argument, decrement subtracts 1.  Note that
+# decrement does not range check and hence will not underflow, but
+# will incorrectly say that 0 - 1 = 0
+
+# ----------------------------------------------------------------------------
+# Function:  int_inc
+# Arguments: 1: A number in x's representation
+# Returns:   The number incremented by 1 in x's representation
+# ----------------------------------------------------------------------------
+int_inc = $(strip $(__gmsl_tr1)$1 x)
+
+# ----------------------------------------------------------------------------
+# Function:  inc
+# Arguments: 1: An integer
+# Returns:   The argument incremented by 1
+# ----------------------------------------------------------------------------
+inc = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_inc,$1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_dec
+# Arguments: 1: A number in x's representation
+# Returns:   The number decremented by 1 in x's representation
+# ----------------------------------------------------------------------------
+int_dec = $(__gmsl_tr1)$(strip $(if $(call sne,0,$(words $1)), \
+              $(wordlist 2,$(words $1),$1),                    \
+              $(call __gmsl_warning,Decrement underflow)))
+
+# ----------------------------------------------------------------------------
+# Function:  dec
+# Arguments: 1: An integer
+# Returns:   The argument decremented by 1
+# ----------------------------------------------------------------------------
+dec = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_dec,$1)
+
+# double doubles its argument, and halve halves it
+
+# ----------------------------------------------------------------------------
+# Function:  int_double
+# Arguments: 1: A number in x's representation
+# Returns:   The number doubled (i.e. * 2) and returned in x's representation
+# ----------------------------------------------------------------------------
+int_double = $(strip $(__gmsl_tr1)$1 $1)
+
+# ----------------------------------------------------------------------------
+# Function:  double
+# Arguments: 1: An integer
+# Returns:   The integer times 2
+# ----------------------------------------------------------------------------
+double = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_double,$1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_halve
+# Arguments: 1: A number in x's representation
+# Returns:   The number halved (i.e. / 2) and returned in x's representation
+# ----------------------------------------------------------------------------
+int_halve = $(__gmsl_tr1)$(strip $(subst xx,x,$(filter-out xy x y, \
+                             $(join $1,$(foreach a,$1,y x)))))
+
+# ----------------------------------------------------------------------------
+# Function:  halve
+# Arguments: 1: An integer
+# Returns:   The integer divided by 2
+# ----------------------------------------------------------------------------
+halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1)
+
+ifdef __gmsl_have_eval
+# ###########################################################################
+# ASSOCIATIVE ARRAYS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  set
+# Arguments: 1: Name of associative array
+#            2: The key value to associate
+#            3: The value associated with the key
+# Returns:   None
+# ----------------------------------------------------------------------------
+set = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(eval __gmsl_aa_$1_$2 = $3)
+
+# ----------------------------------------------------------------------------
+# Function:  get
+# Arguments: 1: Name of associative array
+#            2: The key to retrieve
+# Returns:   The value stored in the array for that key
+# ----------------------------------------------------------------------------
+get = $(strip $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(if $(filter-out undefined,$(origin __gmsl_aa_$1_$2)), \
+    $(__gmsl_aa_$1_$2)))
+
+# ----------------------------------------------------------------------------
+# Function:  keys
+# Arguments: 1: Name of associative array
+# Returns:   Returns a list of all defined keys in the array
+# ----------------------------------------------------------------------------
+keys = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(sort $(patsubst __gmsl_aa_$1_%,%, \
+                  $(filter __gmsl_aa_$1_%,$(.VARIABLES))))
+
+# ----------------------------------------------------------------------------
+# Function:  defined
+# Arguments: 1: Name of associative array
+#            2: The key to test
+# Returns:   Returns true if the key is defined (i.e. not empty)
+# ----------------------------------------------------------------------------
+defined = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(call sne,$(call get,$1,$2),)
+
+endif # __gmsl_have_eval
+
+ifdef __gmsl_have_eval
+# ###########################################################################
+# NAMED STACKS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  push
+# Arguments: 1: Name of stack
+#            2: Value to push onto the top of the stack (must not contain
+#               a space)
+# Returns:   None
+# ----------------------------------------------------------------------------
+push = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(eval __gmsl_stack_$1 := $2 $(if $(filter-out undefined,\
+    $(origin __gmsl_stack_$1)),$(__gmsl_stack_$1)))
+
+# ----------------------------------------------------------------------------
+# Function:  pop
+# Arguments: 1: Name of stack
+# Returns:   Top element from the stack after removing it
+# ----------------------------------------------------------------------------
+pop = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(if $(filter-out undefined,$(origin __gmsl_stack_$1)), \
+    $(call first,$(__gmsl_stack_$1))                                       \
+    $(eval __gmsl_stack_$1 := $(call rest,$(__gmsl_stack_$1)))))
+
+# ----------------------------------------------------------------------------
+# Function:  peek
+# Arguments: 1: Name of stack
+# Returns:   Top element from the stack without removing it
+# ----------------------------------------------------------------------------
+peek = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call first,$(__gmsl_stack_$1))
+
+# ----------------------------------------------------------------------------
+# Function:  depth
+# Arguments: 1: Name of stack
+# Returns:   Number of items on the stack
+# ----------------------------------------------------------------------------
+depth = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(words $(__gmsl_stack_$1))
+
+endif # __gmsl_have_eval
+
+# ###########################################################################
+# DEBUGGING FACILITIES
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Target:    gmsl-print-%
+# Arguments: The % should be replaced by the name of a variable that you
+#            wish to print out.
+# Action:    Echos the name of the variable that matches the % and its value.
+#            For example, 'make gmsl-print-SHELL' will output the value of
+#            the SHELL variable
+# ----------------------------------------------------------------------------
+gmsl-print-%: ; @echo $* = $($*)
+
+# ----------------------------------------------------------------------------
+# Function:  assert
+# Arguments: 1: A boolean that must be true or the assertion will fail
+#            2: The message to print with the assertion
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert = $(if $1,,$(call __gmsl_error,Assertion failure: $2))
+
+# ----------------------------------------------------------------------------
+# Function:  assert_exists
+# Arguments: 1: Name of file that must exist, if it is missing an assertion
+#               will be generated
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert_exists = $(call assert,$(wildcard $1),file '$1' missing)
+
+# ----------------------------------------------------------------------------
+# Function:  assert_no_dollar
+# Arguments: 1: Name of a function being executd
+#            2: Arguments to check
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert_no_dollar = $(call assert,$(call not,$(findstring $$,$2)),$1 called with a dollar sign in argument)
diff --git a/build/gmsl/gmsl b/build/gmsl/gmsl
new file mode 100644
index 0000000..2ff2897
--- /dev/null
+++ b/build/gmsl/gmsl
@@ -0,0 +1,89 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL)
+#
+# A library of functions to be used with GNU Make's $(call) that
+# provides functionality not available in standard GNU Make.
+#
+# Copyright (c) 2005-2008 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 
+# Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# Neither the name of the John Graham-Cumming nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# ----------------------------------------------------------------------------
+
+# Determine if the library has already been included and if so don't
+# bother including it again
+
+ifndef __gmsl_included
+
+# Standard definitions for true and false.  true is any non-empty
+# string, false is an empty string. These are intended for use with
+# $(if).
+
+true  := T
+false :=
+
+# ----------------------------------------------------------------------------
+# Function:  not
+# Arguments: 1: A boolean value
+# Returns:   Returns the opposite of the arg. (true -> false, false -> true)
+# ----------------------------------------------------------------------------
+not = $(if $1,$(false),$(true))
+
+# Prevent reinclusion of the library
+
+__gmsl_included := $(true)
+
+# Try to determine where this file is located.  If the caller did
+# include /foo/gmsl then extract the /foo/ so that __gmsl gets
+# included transparently
+
+ifneq ($(MAKEFILE_LIST),)
+__gmsl_root := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
+
+# If there are any spaces in the path in __gmsl_root then give up
+
+ifeq (1,$(words $(__gmsl_root)))
+__gmsl_root := $(patsubst %gmsl,%,$(__gmsl_root))
+else
+__gmsl_root :=
+endif
+
+include $(__gmsl_root)__gmsl
+
+else
+
+include __gmsl
+
+endif
+
+endif # __gmsl_included
+
diff --git a/build/gmsl/gmsl-tests b/build/gmsl/gmsl-tests
new file mode 100644
index 0000000..b205be6
--- /dev/null
+++ b/build/gmsl/gmsl-tests
@@ -0,0 +1,647 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL) Test Suite
+#
+# Test suite for the GMSL
+#
+# Copyright (c) 2005-2007 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 
+# Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# Neither the name of the John Graham-Cumming nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# ----------------------------------------------------------------------------
+
+.PHONY: all
+all:
+	@echo
+	@echo Test Summary
+	@echo ------------
+	@echo "$(call int_decode,$(passed)) tests passed; $(call int_decode,$(failed)) tests failed"
+
+include gmsl
+
+passed :=
+failed :=
+
+ECHO := /bin/echo
+
+start_test = $(shell $(ECHO) -n "Testing '$1': " >&2)$(eval current_test := OK)
+stop_test  = $(shell $(ECHO) " $(current_test)" >&2)
+test_pass = .$(eval passed := $(call int_inc,$(passed)))
+test_fail = X$(eval failed := $(call int_inc,$(failed)))$(eval current_test := ERROR '$1' != '$2')
+test_assert = $(if $(filter undefined,$(origin 2)),$(eval 2 :=))$(shell $(ECHO) -n $(if $(call seq,$1,$2),$(call test_pass,$1,$2),$(call test_fail,$1,$2)) >&2)
+
+$(call start_test,not)
+$(call test_assert,$(call not,$(true)),$(false))
+$(call test_assert,$(call not,$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,or)
+$(call test_assert,$(call or,$(true),$(true)),$(true))
+$(call test_assert,$(call or,$(true),$(false)),$(true))
+$(call test_assert,$(call or,$(false),$(true)),$(true))
+$(call test_assert,$(call or,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,and)
+$(call test_assert,$(call and,$(true),$(true)),$(true))
+$(call test_assert,$(call and,$(true),$(false)),$(false))
+$(call test_assert,$(call and,$(false),$(true)),$(false))
+$(call test_assert,$(call and,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,xor)
+$(call test_assert,$(call xor,$(true),$(true)),$(false))
+$(call test_assert,$(call xor,$(true),$(false)),$(true))
+$(call test_assert,$(call xor,$(false),$(true)),$(true))
+$(call test_assert,$(call xor,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,nand)
+$(call test_assert,$(call nand,$(true),$(true)),$(false))
+$(call test_assert,$(call nand,$(true),$(false)),$(true))
+$(call test_assert,$(call nand,$(false),$(true)),$(true))
+$(call test_assert,$(call nand,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,nor)
+$(call test_assert,$(call nor,$(true),$(true)),$(false))
+$(call test_assert,$(call nor,$(true),$(false)),$(false))
+$(call test_assert,$(call nor,$(false),$(true)),$(false))
+$(call test_assert,$(call nor,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,xnor)
+$(call test_assert,$(call xnor,$(true),$(true)),$(true))
+$(call test_assert,$(call xnor,$(true),$(false)),$(false))
+$(call test_assert,$(call xnor,$(false),$(true)),$(false))
+$(call test_assert,$(call xnor,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,first)
+$(call test_assert,$(call first,1 2 3),1)
+$(call test_assert,$(call first,1),1)
+$(call test_assert,$(call first,),)
+$(call stop_test)
+
+$(call start_test,last)
+$(call test_assert,$(call last,1 2 3),3)
+$(call test_assert,$(call last,1),1)
+$(call test_assert,$(call last,),)
+$(call stop_test)
+
+$(call start_test,rest)
+$(call test_assert,$(call rest,1 2 3),2 3)
+$(call test_assert,$(call rest,1),)
+$(call test_assert,$(call rest,),)
+$(call stop_test)
+
+$(call start_test,chop)
+$(call test_assert,$(call chop,1 2 3),1 2)
+$(call test_assert,$(call chop,1 2 3 4),1 2 3)
+$(call test_assert,$(call chop,1),)
+$(call test_assert,$(call chop,),)
+$(call stop_test)
+
+$(call start_test,length)
+$(call test_assert,$(call length,1 2 3),3)
+$(call test_assert,$(call length,1 2 3 4),4)
+$(call test_assert,$(call length,1),1)
+$(call test_assert,$(call length,),0)
+$(call stop_test)
+
+$(call start_test,map)
+$(call test_assert,$(call map,origin,__undefined map MAKE),undefined file default)
+$(call test_assert,$(call map,origin,),)
+$(call stop_test)
+
+joinem = $1$2
+$(call start_test,pairmap)
+$(call test_assert,$(call pairmap,addsuffix,2 1 3,a b c),a2 b1 c3)
+$(call test_assert,$(call pairmap,addprefix,2 1 3,a b c d),2a 1b 3c d)
+$(call test_assert,$(call pairmap,addprefix,2 1 3 4,a b c),2a 1b 3c)
+$(call test_assert,$(call pairmap,joinem,2 1 3 4,a b c),2a 1b 3c 4)
+$(call stop_test)
+
+$(call start_test,seq)
+$(call test_assert,$(call seq,abc,abc),T)
+$(call test_assert,$(call seq,x,),)
+$(call test_assert,$(call seq,,x),)
+$(call test_assert,$(call seq,x,x),T)
+$(call test_assert,$(call seq,a%c,abc),)
+$(call test_assert,$(call seq,abc,a%c),)
+$(call test_assert,$(call seq,abc,ABC),)
+$(call test_assert,$(call seq,abc,),)
+$(call test_assert,$(call seq,,),T)
+$(call test_assert,$(call seq,a b c,a b c),T)
+$(call test_assert,$(call seq,aa% bb% cc,aa% bb% cc),T)
+$(call test_assert,$(call seq,aa% bb% cc,aa% bb cc),)
+$(call test_assert,$(call seq,aa% bb% cc,xx yy zz),)
+$(call stop_test)
+
+$(call start_test,sne)
+$(call test_assert,$(call sne,abc,abc),)
+$(call test_assert,$(call sne,x,),T)
+$(call test_assert,$(call sne,,x),T)
+$(call test_assert,$(call sne,x,x),)
+$(call test_assert,$(call sne,abc,ABC),T)
+$(call test_assert,$(call sne,abc,),T)
+$(call test_assert,$(call sne,,),)
+$(call test_assert,$(call sne,a b c,a b c),)
+$(call test_assert,$(call sne,aa% bb% cc,aa% bb% cc),)
+$(call test_assert,$(call sne,aa% bb% cc,aa% bb cc),T)
+$(call stop_test)
+
+$(call start_test,strlen)
+$(call test_assert,$(call strlen,),0)
+$(call test_assert,$(call strlen,a),1)
+$(call test_assert,$(call strlen,a b),3)
+$(call test_assert,$(call strlen,a ),2)
+$(call test_assert,$(call strlen, a),2)
+$(call test_assert,$(call strlen,  ),2)
+$(call test_assert,$(call strlen,   ),3)
+$(call test_assert,$(call strlen,    ),4)
+$(call stop_test)
+
+$(call start_test,substr)
+$(call test_assert,$(call substr,xyz,1,1),x)
+$(call test_assert,$(call substr,xyz,1,2),xy)
+$(call test_assert,$(call substr,xyz,2,3),yz)
+$(call test_assert,$(call substr,some string,1,1),s)
+$(call test_assert,$(call substr,some string,1,2),so)
+$(call test_assert,$(call substr,some string,1,3),som)
+$(call test_assert,$(call substr,some string,1,4),some)
+$(call test_assert,$(call substr,some string,1,5),some )
+$(call test_assert,$(call substr,some string,1,6),some s)
+$(call test_assert,$(call substr,some string,5,5), )
+$(call test_assert,$(call substr,some string,5,6), s)
+$(call test_assert,$(call substr,some string,5,7), st)
+$(call test_assert,$(call substr,some string,5,8), str)
+$(call test_assert,$(call substr,some string,1,100),some string)
+$(call stop_test)
+
+$(call start_test,lc)
+$(call test_assert,$(call lc,The Quick Brown Fox),the quick brown fox)
+$(call test_assert,$(call lc,the1 quick2 brown3 fox4),the1 quick2 brown3 fox4)
+$(call test_assert,$(call lc,The_),the_)
+$(call test_assert,$(call lc,),)
+$(call stop_test)
+
+$(call start_test,uc)
+$(call test_assert,$(call uc,The Quick Brown Fox),THE QUICK BROWN FOX)
+$(call test_assert,$(call uc,the1 quick2 brown3 fox4),THE1 QUICK2 BROWN3 FOX4)
+$(call test_assert,$(call uc,The_),THE_)
+$(call test_assert,$(call uc,),)
+$(call stop_test)
+
+$(call start_test,tr)
+$(call test_assert,$(call tr,A B C,1 2 3,CAPITAL),31PIT1L)
+$(call test_assert,$(call tr,a b c,1 2 3,CAPITAL),CAPITAL)
+$(call test_assert,$(call tr,E L I,3 1 1,I AM ELITE),1 AM 311T3)
+$(call stop_test)
+
+$(call start_test,leq)
+$(call test_assert,$(call leq,1 2 3,1 2 3),T)
+$(call test_assert,$(call leq,1 2 3,1 2 3 4),)
+$(call test_assert,$(call leq,1 2 3 4,1 2 3),)
+$(call test_assert,$(call leq,1,1),T)
+$(call test_assert,$(call leq,,),T)
+$(call stop_test)
+
+$(call start_test,lne)
+$(call test_assert,$(call lne,1 2 3,1 2 3),)
+$(call test_assert,$(call lne,1 2 3,1 2 3 4),T)
+$(call test_assert,$(call lne,1 2 3 4,1 2 3),T)
+$(call test_assert,$(call lne,1,1),)
+$(call test_assert,$(call lne,,),)
+$(call stop_test)
+
+$(call start_test,empty_set)
+$(call test_assert,$(empty_set),)
+$(call test_assert,$(empty_set),$(call set_create,))
+$(call stop_test)
+
+$(call start_test,set_create)
+$(call test_assert,$(call set_create,),)
+$(call test_assert,$(call set_create,1 2 2 3),1 2 3)
+$(call test_assert,$(call set_create,2 1 1 2 2 3),1 2 3)
+$(call test_assert,$(call set_create,1),1)
+$(call stop_test)
+
+$(call start_test,set_insert)
+$(call test_assert,$(call set_insert,1,$(empty_set)),1)
+$(call test_assert,$(call set_insert,1,$(call set_create,1)),1)
+$(call test_assert,$(call set_insert,1,$(call set_create,1 2)),1 2)
+$(call test_assert,$(call set_insert,0,$(call set_create,1 2)),0 1 2)
+$(call stop_test)
+
+$(call start_test,set_remove)
+$(call test_assert,$(call set_remove,1,$(empty_set)),$(empty_set))
+$(call test_assert,$(call set_remove,1,$(call set_create,1 2)),2)
+$(call test_assert,$(call set_remove,1,$(call set_create,1 11 2)),11 2)
+$(call test_assert,$(call set_remove,0,$(call set_create,1 2)),1 2)
+$(call stop_test)
+
+$(call start_test,set_is_member)
+$(call test_assert,$(call set_is_member,1,$(empty_set)),)
+$(call test_assert,$(call set_is_member,1,$(call set_create,2 3)),)
+$(call test_assert,$(call set_is_member,1,$(call set_create,1 2 3)),T)
+$(call test_assert,$(call set_is_member,1,$(call set_create,1)),T)
+$(call stop_test)
+
+$(call start_test,set_union)
+$(call test_assert,$(call set_union,,),)
+$(call test_assert,$(call set_union,1 2,),1 2)
+$(call test_assert,$(call set_union,,3 4),3 4)
+$(call test_assert,$(call set_union,1 2,3 4),1 2 3 4)
+$(call test_assert,$(call set_union,1 2 3,3 4 5),1 2 3 4 5)
+$(call stop_test)
+
+$(call start_test,set_intersection)
+$(call test_assert,$(call set_intersection,,),)
+$(call test_assert,$(call set_intersection,1 2,),)
+$(call test_assert,$(call set_intersection,,3 4),)
+$(call test_assert,$(call set_intersection,1 2,3 4),)
+$(call test_assert,$(call set_intersection,1 2 3 4,3 4 5),3 4)
+$(call stop_test)
+
+$(call start_test,set_is_subset)
+$(call test_assert,$(call set_is_subset,,),T)
+$(call test_assert,$(call set_is_subset,1 2,),)
+$(call test_assert,$(call set_is_subset,,3 4),T)
+$(call test_assert,$(call set_is_subset,1 2,3 4),)
+$(call test_assert,$(call set_is_subset,1 2,1 2 3 4 5),T)
+$(call test_assert,$(call set_is_subset,1 2,1 2),T)
+$(call test_assert,$(call set_is_subset,1 2,1 3 4 5),)
+$(call stop_test)
+
+$(call start_test,set_equal)
+$(call test_assert,$(call set_equal,,),T)
+$(call test_assert,$(call set_equal,1,),)
+$(call test_assert,$(call set_equal,,1),)
+$(call test_assert,$(call set_equal,1,1),T)
+$(call test_assert,$(call set_equal,1 2,),)
+$(call test_assert,$(call set_equal,,1 2),)
+$(call test_assert,$(call set_equal,1 2,1 2 3),)
+$(call stop_test)
+
+$(call start_test,int_encode)
+$(call test_assert,$(call int_encode,0),)
+$(call test_assert,$(call int_encode,1),x)
+$(call test_assert,$(call int_encode,2),x x)
+$(call test_assert,$(call int_encode,10),x x x x x x x x x x)
+$(call stop_test)
+
+$(call start_test,int_decode)
+$(call test_assert,$(call int_decode,),0)
+$(call test_assert,$(call int_decode,x),1)
+$(call test_assert,$(call int_decode,x x),2)
+$(call test_assert,$(call int_decode,x x x x x x x x x x),10)
+$(call stop_test)
+
+$(call start_test,int_plus)
+$(call test_assert,$(call int_plus,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,7))
+$(call test_assert,$(call int_plus,$(call int_encode,0),$(call int_encode,4)),$(call int_encode,4))
+$(call test_assert,$(call int_plus,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,3))
+$(call test_assert,$(call int_plus,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_plus,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,1))
+$(call stop_test)
+
+$(call start_test,plus)
+$(call test_assert,$(call plus,3,4),7)
+$(call test_assert,$(call plus,4,3),7)
+$(call test_assert,$(call plus,0,4),4)
+$(call test_assert,$(call plus,3,0),3)
+$(call test_assert,$(call plus,0,0),0)
+$(call stop_test)
+
+__gmsl_warning = $1
+$(call start_test,int_subtract)
+$(call test_assert,$(call int_subtract,$(call int_encode,3),$(call int_encode,4)),Subtraction underflow)
+$(call test_assert,$(call int_subtract,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1))
+$(call test_assert,$(call int_subtract,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,3))
+$(call test_assert,$(call int_subtract,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_subtract,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,1))
+$(call stop_test)
+
+__gmsl_warning = x x x x x x x x x x
+$(call start_test,subtract)
+$(call test_assert,$(call subtract,3,4),10)
+$(call test_assert,$(call subtract,4,3),1)
+$(call test_assert,$(call subtract,3,0),3)
+$(call test_assert,$(call subtract,0,0),0)
+$(call stop_test)
+
+$(call start_test,int_multiply)
+$(call test_assert,$(call int_multiply,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,12))
+$(call test_assert,$(call int_multiply,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,12))
+$(call test_assert,$(call int_multiply,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_multiply,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_multiply,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,multiply)
+$(call test_assert,$(call multiply,3,4),12)
+$(call test_assert,$(call multiply,4,3),12)
+$(call test_assert,$(call multiply,3,0),0)
+$(call test_assert,$(call multiply,0,3),0)
+$(call test_assert,$(call multiply,0,0),0)
+$(call stop_test)
+
+__gmsl_error = $1
+$(call start_test,int_divide)
+$(call test_assert,$(call int_divide,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,0))
+$(call test_assert,$(call int_divide,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1))
+$(call test_assert,$(call int_divide,$(call int_encode,31),$(call int_encode,3)),$(call int_encode,10))
+$(call test_assert,$(call int_divide,$(call int_encode,30),$(call int_encode,3)),$(call int_encode,10))
+$(call test_assert,$(call int_divide,$(call int_encode,29),$(call int_encode,3)),$(call int_encode,9))
+$(call test_assert,$(call int_divide,$(call int_encode,0),$(call int_encode,1)),$(call int_encode,0))
+$(call test_assert,$(call int_divide,$(call int_encode,1),$(call int_encode,0)),Division by zero)
+$(call stop_test)
+
+__gmsl_error = x x x x x x x x x x
+$(call start_test,divide)
+$(call test_assert,$(call divide,3,4),0)
+$(call test_assert,$(call divide,4,3),1)
+$(call test_assert,$(call divide,21,2),10)
+$(call test_assert,$(call divide,20,2),10)
+$(call test_assert,$(call divide,19,2),9)
+$(call test_assert,$(call divide,1,0),10)
+$(call stop_test)
+
+$(call start_test,associative array)
+$(call test_assert,$(call get,myarray,key1),)
+$(call set,myarray,key1,value1)
+$(call test_assert,$(call get,myarray,key1),value1)
+$(call test_assert,$(call get,myarray,key2),)
+$(call test_assert,$(call get,myarray1,key1),)
+$(call test_assert,$(call defined,myarray,key1),T)
+$(call test_assert,$(call defined,myarray,key2),)
+$(call test_assert,$(call defined,myarray1,key1),)
+$(call set,myarray,key2,value2)
+$(call test_assert,$(call keys,myarray),key1 key2)
+$(call test_assert,$(call keys,myarray1),)
+$(call stop_test)
+
+$(call start_test,named stack)
+$(call test_assert,$(call pop,mystack),)
+$(call test_assert,$(call push,mystack,e2))
+$(call push,mystack,e1)
+$(call test_assert,$(call pop,mystack),e1)
+$(call test_assert,$(call pop,mystack),e2)
+$(call push,mystack,f3)
+$(call push,mystack,f1)
+$(call test_assert,$(call pop,mystack),f1)
+$(call push,mystack,f2)
+$(call test_assert,$(call peek,mystack),f2)
+$(call test_assert,$(call depth,mystack),2)
+$(call test_assert,$(call pop,mystack),f2)
+$(call test_assert,$(call depth,mystack),1)
+$(call test_assert,$(call pop,myotherstack),)
+$(call stop_test)
+
+$(call start_test,reverse)
+$(call test_assert,$(call reverse,),)
+$(call test_assert,$(call reverse,1),1)
+$(call test_assert,$(call reverse,1 2),2 1)
+$(call test_assert,$(call reverse,1 2 3),3 2 1)
+$(call stop_test)
+
+$(call start_test,uniq)
+$(call test_assert,$(call uniq,),)
+$(call test_assert,$(call uniq,a),a)
+$(call test_assert,$(call uniq,a a),a)
+$(call test_assert,$(call uniq,a aa),a aa)
+$(call test_assert,$(call uniq,a aa a),a aa)
+$(call test_assert,$(call uniq,a b ba ab b a a ba a),a b ba ab)
+$(call stop_test)
+
+c:=,
+$(call start_test,split)
+$(call test_assert,$(call split,$c,comma$cseparated$cstring),comma separated string)
+$(call test_assert,$(call split,*,star*field*record),star field record)
+$(call test_assert,$(call split,*,star*),star)
+$(call test_assert,$(call split,*,star*field),star field)
+$(call test_assert,$(call split,*,star****field),star field)
+$(call test_assert,$(call split,*,),)
+$(call stop_test)
+
+$(call start_test,merge)
+$(call test_assert,$(call merge,$c,list of things),list$cof$cthings)
+$(call test_assert,$(call merge,*,list of things),list*of*things)
+$(call test_assert,$(call merge,*,list),list)
+$(call test_assert,$(call merge,*,),)
+$(call stop_test)
+
+$(call start_test,int_max)
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,1),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,0)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,0),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,max)
+$(call test_assert,$(call max,2,1),2)
+$(call test_assert,$(call max,1,2),2)
+$(call test_assert,$(call max,2,0),2)
+$(call test_assert,$(call max,0,2),2)
+$(call test_assert,$(call max,2,2),2)
+$(call test_assert,$(call max,0,0),0)
+$(call stop_test)
+
+$(call start_test,int_min)
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,1)),$(call int_encode,1))
+$(call test_assert,$(call int_min,$(call int_encode,1),$(call int_encode,2)),$(call int_encode,1))
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_min,$(call int_encode,0),$(call int_encode,2)),$(call int_encode,0))
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_min,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,min)
+$(call test_assert,$(call min,2,1),1)
+$(call test_assert,$(call min,1,2),1)
+$(call test_assert,$(call min,2,0),0)
+$(call test_assert,$(call min,0,2),0)
+$(call test_assert,$(call min,2,2),2)
+$(call test_assert,$(call min,0,0),0)
+$(call stop_test)
+
+__gmsl_error = $1
+$(call start_test,assert functions)
+$(call test_assert,$(call assert,$(true),ignore),)
+$(call test_assert,$(call assert,$(false),failed),Assertion failure: failed)
+$(call test_assert,$(call assert_exists,gmsl-tests),)
+$(call test_assert,$(call assert_exists,MISSING-gmsl-tests),Assertion failure: file 'MISSING-gmsl-tests' missing)
+$(call stop_test)
+
+$(call start_test,int_inc)
+$(call test_assert,$(call int_inc,$(call int_encode,0)),$(call int_encode,1))
+$(call test_assert,$(call int_inc,$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_inc,$(call int_encode,4)),$(call int_encode,5))
+$(call test_assert,$(call int_inc,$(call int_encode,10)),$(call int_encode,11))
+$(call stop_test)
+
+$(call start_test,inc)
+$(call test_assert,$(call inc,0),1)
+$(call test_assert,$(call inc,1),2)
+$(call test_assert,$(call inc,4),5)
+$(call test_assert,$(call inc,10),11)
+$(call stop_test)
+
+__gmsl_warning = $1
+$(call start_test,int_dec)
+$(call test_assert,$(call int_dec,$(call int_encode,0)),Decrement underflow)
+$(call test_assert,$(call int_dec,$(call int_encode,1)),$(call int_encode,0))
+$(call test_assert,$(call int_dec,$(call int_encode,4)),$(call int_encode,3))
+$(call test_assert,$(call int_dec,$(call int_encode,10)),$(call int_encode,9))
+$(call stop_test)
+
+__gmsl_warning = x x x x x x x x x x
+$(call start_test,dec)
+$(call test_assert,$(call dec,0),10)
+$(call test_assert,$(call dec,1),0)
+$(call test_assert,$(call dec,4),3)
+$(call test_assert,$(call dec,10),9)
+$(call stop_test)
+
+$(call start_test,int_double)
+$(call test_assert,$(call int_double,$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_double,$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_double,$(call int_encode,4)),$(call int_encode,8))
+$(call stop_test)
+
+$(call start_test,double)
+$(call test_assert,$(call double,0),0)
+$(call test_assert,$(call double,1),2)
+$(call test_assert,$(call double,4),8)
+$(call stop_test)
+
+$(call start_test,int_halve)
+$(call test_assert,$(call int_halve,$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_halve,$(call int_encode,2)),$(call int_encode,1))
+$(call test_assert,$(call int_halve,$(call int_encode,8)),$(call int_encode,4))
+$(call test_assert,$(call int_halve,$(call int_encode,7)),$(call int_encode,3))
+$(call stop_test)
+
+$(call start_test,halve)
+$(call test_assert,$(call halve,0),0)
+$(call test_assert,$(call halve,2),1)
+$(call test_assert,$(call halve,8),4)
+$(call test_assert,$(call halve,7),3)
+$(call stop_test) 
+
+$(call start_test,gt)
+$(call test_assert,$(call gt,2,3),)
+$(call test_assert,$(call gt,3,2),$(true))
+$(call test_assert,$(call gt,2,2),)
+$(call stop_test)
+
+$(call start_test,gte)
+$(call test_assert,$(call gte,2,3),)
+$(call test_assert,$(call gte,3,2),$(true))
+$(call test_assert,$(call gte,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,lt)
+$(call test_assert,$(call lt,2,3),$(true))
+$(call test_assert,$(call lt,3,2),)
+$(call test_assert,$(call lt,2,2),)
+$(call stop_test)
+
+$(call start_test,lte)
+$(call test_assert,$(call lte,2,3),$(true))
+$(call test_assert,$(call lte,3,2),)
+$(call test_assert,$(call lte,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,eq)
+$(call test_assert,$(call eq,2,3),)
+$(call test_assert,$(call eq,3,2),)
+$(call test_assert,$(call eq,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,ne)
+$(call test_assert,$(call ne,2,3),$(true))
+$(call test_assert,$(call ne,3,2),$(true))
+$(call test_assert,$(call ne,2,2),)
+$(call stop_test)
+
+$(call start_test,int_gt)
+$(call test_assert,$(call int_gt,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_gt,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_gt,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,int_gte)
+$(call test_assert,$(call int_gte,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_gte,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_gte,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_lt)
+$(call test_assert,$(call int_lt,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_lt,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_lt,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,int_lte)
+$(call test_assert,$(call int_lte,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_lte,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_lte,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_eq)
+$(call test_assert,$(call int_eq,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_eq,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_eq,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_ne)
+$(call test_assert,$(call int_ne,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_ne,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_ne,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,gmsl_compatible)
+$(call test_assert,$(call gmsl_compatible,$(gmsl_version)),$(true))
+$(call test_assert,$(call gmsl_compatible,0 9 0),$(true))
+$(call test_assert,$(call gmsl_compatible,0 0 1),$(true))
+$(call test_assert,$(call gmsl_compatible,0 0 0),$(true))
+$(call test_assert,$(call gmsl_compatible,2 0 0),)
+$(call test_assert,$(call gmsl_compatible,1 1 0),)
+$(call test_assert,$(call gmsl_compatible,1 0 8),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 8),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 10),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 11),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 12),)
+$(call stop_test)
diff --git a/build/gmsl/index.html b/build/gmsl/index.html
new file mode 100644
index 0000000..8cc93ae
--- /dev/null
+++ b/build/gmsl/index.html
@@ -0,0 +1,687 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
+  <title>GNU Make Standard Library</title></head>
+
+<body>
+<h1>GNU Make Standard Library</h1>
+The GNU Make Standard Library (GMSL) is a collection of functions
+implemented using native GNU Make functionality that provide list and
+string manipulation, integer arithmetic, associative arrays, stacks,
+and debugging facilities.&nbsp; The GMSL is released under the BSD License.<br>
+<br>
+<a href="http://sourceforge.net/projects/gmsl/">[Project Page]</a> <a href="http://sourceforge.net/project/showfiles.php?group_id=129887">[Download]</a>
+<a href="http://sourceforge.net/forum/forum.php?forum_id=443916">[Discussion
+Forum]</a><br>
+<h2>Using GMSL</h2>
+The two files needed are <span style="font-family: monospace;">gmsl</span>
+and <span style="font-family: monospace;">__gmsl</span>.&nbsp; To
+include the GMSL in your Makefile do<br>
+<pre style="margin-left: 40px;">include gmsl</pre>
+<span style="font-family: monospace;">gmsl</span> automatically includes<span style="font-family: monospace;"> __gmsl</span>.&nbsp; To check that
+you have the right version of <span style="font-family: monospace;">gmsl</span>
+use the <span style="font-family: monospace;">gmsl_compatible</span>
+function (see
+below). The current version is <span style="font-family: monospace;">1
+0 11</span>.<br>
+<br>
+The GMSL package also includes a test suite for GMSL.&nbsp; Just run <span style="font-family: monospace;">make -f gmsl-tests</span>.<br>
+<h2>Logical Operators</h2>GMSL has boolean $(true) (a non-empty string)
+and $(false) (an empty string).&nbsp; The following operators can be
+used with those variables.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><span style="font-weight: bold;">not</span><br>
+
+<br>
+
+<span style="font-family: monospace;">Arguments: A boolean value</span><br style="font-family: monospace;">
+
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if the boolean is $(false) and vice versa</span><br style="font-family: monospace;">
+
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;"></span><span style="font-weight: bold;">and</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if both of the booleans are true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">or</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if either of the booleans is true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xor</span><br style="font-weight: bold;">
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if exactly one of the booleans is true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nand</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not and'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nor</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not or'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xnor</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not xor'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;">
+<h2>List Manipulation Functions</h2>
+&nbsp;A list is a string of characters; the list separator is a space.<br>
+
+<br>
+<hr style="width: 100%; height: 2px;"><b>first</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the first element of a list<br>
+</span>
+<hr><b>last</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the last element of a list<br>
+</span>
+<hr><b>rest</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the list with the first element
+removed<br>
+</span>
+<hr><b>chop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the list with the last element removed<br>
+</span>
+<hr><b>map</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of function to
+$(call) for each element of list<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: List to
+iterate over calling the function in 1<br>
+Returns:&nbsp;&nbsp;&nbsp;The list after calling the function on each
+element<br>
+</span>
+<hr><b>pairmap</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of function to
+$(call) for each pair of elements<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: List to
+iterate over calling the function in 1<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: Second
+list to iterate over calling the function in 1<br>
+Returns:&nbsp;&nbsp;&nbsp;The list after calling the function on each
+pair of elements<br>
+</span>
+<hr><b>leq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two lists are identical<br>
+</span>
+<hr><b>lne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two lists are different<br>
+</span>
+<hr><b>reverse</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to reverse<br>
+Returns:&nbsp;&nbsp;&nbsp;The list with its elements in reverse order<br>
+</span>
+<hr><b>uniq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to deduplicate<br>
+Returns:&nbsp;&nbsp;&nbsp;The list with elements in order without duplicates<br>
+</span>
+<hr><b>length</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;The number of elements in the list<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>String Manipulation Functions</h2>
+A string is any sequence of characters.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>seq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two strings are
+identical<br>
+</span>
+<hr><b>sne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two strings are not
+the same<br>
+</span>
+<hr><b>strlen</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the length of the string<br>
+</span>
+<hr><b>substr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Start offset (first character is 1)<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: Ending offset (inclusive)<br>Returns:&nbsp;&nbsp;&nbsp;Returns a substring<br>
+</span>
+<hr><b>split</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+split on<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: A
+string to split<br>
+Returns:&nbsp;&nbsp;&nbsp;Splits a string into a list separated by
+spaces at the split<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; character
+in the first argument<br>
+</span>
+<hr><b>merge</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+put between fields<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: A list
+to merge into a string<br>
+Returns:&nbsp;&nbsp;&nbsp;Merges a list into a single string, list
+elements are separated<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by the
+character in the first argument<br>
+</span>
+<hr><b>tr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The list of
+characters to translate from <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The
+list of characters to translate to<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: The
+text to translate<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text after translating characters<br>
+</span>
+<hr><b>uc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Text to upper case<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text in upper case<br>
+</span>
+<hr><b>lc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Text to lower case<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text in lower case<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Set Manipulation Functions</h2>
+Sets are represented by sorted, deduplicated lists.  To create a set
+from a list use <span style="font-family:
+monospace;">set_create</span>, or start with the <span
+style="font-family: monospace;">empty_set</span> and <span
+style="font-family: monospace;">set_insert</span> individual elements.
+The empty set is defined as <span style="font-family:
+monospace;">empty_set</span>.<p>
+
+<hr><b>set_create</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list of set elements<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the newly created set<br>
+</span>
+
+<hr><b>set_insert</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element to add to a set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the set with the element added<br>
+</span>
+
+<hr><b>set_remove</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element to remove from a set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the set with the element removed<br>
+</span>
+
+<hr><b>set_is_member</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the element is in the set<br>
+</span>
+
+<hr><b>set_union</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the union of the two sets<br>
+</span>
+
+<hr><b>set_intersection</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the intersection of the two sets<br>
+</span>
+
+<hr><b>set_is_subset</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the first set is a subset of the second<br>
+</span>
+
+<hr><b>set_equal</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two sets are identical<br>
+</span>
+
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Integer Arithmetic Functions</h2>
+Integers are represented by lists with the equivalent number of
+x's.&nbsp; For example the number 4 is x x x x.&nbsp; The maximum
+integer that the library can handle as <span style="font-style: italic;">input</span> (i.e. as the argument to a
+call to <span style="font-family: monospace;">int_encode</span>) is
+65536. There is no limit on integer size for internal computations or
+output.<br>
+<br>
+The arithmetic library functions come in two forms: one form of each
+function takes integers as arguments and the other form takes the
+encoded form (x's created by a call to <span style="font-family: monospace;">int_encode</span>).&nbsp; For example,
+there are two plus functions: <span style="font-family: monospace;">plus</span>
+(called with integer arguments and returns an integer) and <span style="font-family: monospace;">int_plus</span> (called with encoded
+arguments and returns an encoded result).<br>
+<br>
+<span style="font-family: monospace;">plus</span> will be slower than <span style="font-family: monospace;">int_plus</span> because its arguments
+and result have to be translated between the x's format and
+integers.&nbsp; If doing a complex calculation use the <span style="font-family: monospace;">int_*</span> forms with a single
+encoding of inputs and single decoding of the output.&nbsp; For simple
+calculations the direct forms can be used.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>int_decode</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number of x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer for human consumption
+that is represented<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by the
+string of x's<br>
+</span>
+<hr><b>int_encode</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in
+human-readable integer form<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer encoded as a string of x's<br>
+</span>
+<hr><b>int_plus</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the sum of the two numbers in x's
+representation<br>
+</span>
+<hr><b>plus (wrapped version of int_plus)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the sum of the two integers<br>
+</span>
+<hr><b>int_subtract</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the difference of the two numbers in
+x's representation,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or outputs
+an error on a numeric underflow<br>
+</span>
+<hr><b>subtract (wrapped version of int_subtract)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the difference of the two integers,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or outputs
+an error on a numeric underflow<br>
+</span>
+<hr><b>int_multiply</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the product of the two numbers in x's
+representation<br>
+</span>
+<hr><b>multiply (wrapped version of int_multiply)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the product of the two integers<br>
+</span>
+<hr><b>int_divide</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the result of integer division of
+argument 1 divided<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by
+argument 2 in x's representation<br>
+</span>
+<hr><b>divide (wrapped version of int_divide)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer division of the first
+argument by the second<br>
+</span>
+<hr><b>int_max, int_min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the maximum or minimum of its
+arguments in x's<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+representation<br>
+</span>
+<hr><b>max, min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the maximum or minimum of its integer
+arguments<br>
+</span>
+<hr><b>int_gt, int_gte, int_lt, int_lte, int_eq, int_ne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two x's representation
+numbers to be compared<br>
+Returns:&nbsp;&nbsp;&nbsp;$(true) or $(false)<br>
+<br>
+int_gt First argument greater than second argument<br>
+int_gte First argument greater than or equal to second argument<br>
+int_lt First argument less than second argument <br>
+int_lte First argument less than or equal to second argument<br>
+int_eq First argument is numerically equal to the second argument<br>
+int_ne First argument is not numerically equal to the second argument<br>
+</span>
+<hr><b>gt, gte, lt, lte, eq, ne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two integers to be
+compared<br>
+Returns:&nbsp;&nbsp;&nbsp;$(true) or $(false)<br>
+<br>
+gt First argument greater than second argument<br>
+gte First argument greater than or equal to second argument<br>
+lt First argument less than second argument <br>
+lte First argument less than or equal to second argument<br>
+eq First argument is numerically equal to the second argument<br>
+ne First argument is not numerically equal to the second argument<br>
+</span>
+increment adds 1 to its argument, decrement subtracts 1. Note that<br>
+decrement does not range check and hence will not underflow, but<br>
+will incorrectly say that 0 - 1 = 0<br>
+<hr><b>int_inc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number incremented by 1 in x's
+representation<br>
+</span>
+<hr><b>inc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The argument incremented by 1<br>
+</span>
+<hr><b>int_dec</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number decremented by 1 in x's
+representation<br>
+</span>
+<hr><b>dec</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The argument decremented by 1<br>
+</span>
+<hr><b>int_double</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number doubled (i.e. * 2) and returned in
+x's representation<br>
+</span>
+<hr><b>double</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The integer times 2<br>
+</span>
+<hr><b>int_halve</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number halved (i.e. / 2) and returned in
+x's representation<br>
+</span>
+<hr><b>halve</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The integer divided by 2<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Associative Arrays</h2>
+An associate array maps a key value (a string with no spaces in it) to
+a single value (any string).&nbsp;&nbsp;&nbsp; <br>
+<b><br>
+</b>
+<hr style="width: 100%; height: 2px;"><b>set</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+value to associate<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: The
+value associated with the key<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>get</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+to retrieve<br>
+Returns:&nbsp;&nbsp;&nbsp;The value stored in the array for that key<br>
+</span>
+<hr><b>keys</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns a list of all defined keys in the
+array<br>
+</span>
+<hr><b>defined</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+to test<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns true if the key is defined (i.e. not
+empty)<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Named Stacks</h2>
+A stack is an ordered list of strings (with no spaces in them).<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>push</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Value
+to push onto the top of the stack (must not contain<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a space)<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>pop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Top element from the stack after removing it<br>
+</span>
+<hr><b>peek</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Top element from the stack without removing it<br>
+</span>
+<hr><b>depth</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Number of items on the stack<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Miscellaneous and Debugging Facilities</h2>
+GMSL defines the following constants; all are accessed as normal GNU
+Make variables by wrapping them in <span style="font-family: monospace;">$()</span> or <span style="font-family: monospace;">${}</span>.<br>
+<br>
+<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td><span style="font-style: italic;">Constant</span><br>
+      </td>
+      <td><span style="font-style: italic;">Value</span><br>
+      </td>
+      <td><span style="font-style: italic;">Purpose</span><br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">true</span><br>
+      </td>
+      <td><span style="font-family: monospace;">T</span><br>
+      </td>
+      <td>Boolean for <span style="font-family: monospace;">$(if)</span>
+and return from&nbsp; GMSL functions<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">false</span><br>
+      </td>
+      <td><br>
+      </td>
+      <td>Boolean for <span style="font-family: monospace;">$(if)</span>
+and return from GMSL functions<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">gmsl_version</span><br>
+      </td>
+      <td><span style="font-family: monospace;">1 0 0</span><br>
+      </td>
+      <td>GMSL version number as list: major minor revision<br>
+      </td>
+    </tr>
+  </tbody>
+</table>
+<span style="font-weight: bold;"><br>
+gmsl_compatible</span><span style="font-family: monospace;"><br>
+<br>
+Arguments: List containing the desired library version number (maj min
+rev)<br>
+</span><span style="font-family: monospace;">Returns:&nbsp;&nbsp;
+$(true) if this version of the library is compatible<br>
+</span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+with the requested version number, otherwise $(false)</span>
+<hr><b>gmsl-print-% (target not a function)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: The % should be
+replaced by the name of a variable that you<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wish to
+print out.<br>
+Action:&nbsp;&nbsp;&nbsp; Echos the name of the variable that matches
+the % and its value.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For
+example, 'make gmsl-print-SHELL' will output the value of<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the SHELL
+variable<br>
+</span>
+<hr><b>assert</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A boolean that must
+be true or the assertion will fail<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The
+message to print with the assertion<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>assert_exists</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of file that
+must exist, if it is missing an assertion<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; will be
+generated<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr style="width: 100%; height: 2px;"><br>
+GMSL has a number of environment variables (or command-line overrides)
+that control various bits of functionality:<br>
+<br>
+<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td><span style="font-style: italic;">Variable</span><br>
+      </td>
+      <td><span style="font-style: italic;">Purpose</span><br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_NO_WARNINGS</span><br>
+      </td>
+      <td>If set prevents GMSL from outputting warning messages:
+artithmetic functions generate underflow warnings.<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_NO_ERRORS</span><br>
+      </td>
+      <td>If set prevents GMSL from generating fatal errors: division
+by zero or failed assertions are fatal.<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_TRACE</span><br>
+      </td>
+      <td>Enables function tracing.&nbsp; Calls to GMSL functions will
+result in name and arguments being traced.<br>
+      </td>
+    </tr>
+  </tbody>
+</table>
+<span style="font-family: monospace;"></span><br>
+<hr>
+Copyright (c) 2005-2006 <a href="http://www.jgc.org/">John Graham-Cumming</a>.<br>
+<hr style="width: 100%; height: 2px;">
+<table style="width: 100%; text-align: left;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="width: 50%;">John Graham-Cumming's work on this
+project was sponsored by <a href="http://www.electric-cloud.com/">Electric
+Cloud, Inc</a>.<br>
+      <a href="http://www.electric-cloud.com/"><img alt="" src="http://gmsl.sf.net/ec_logo.gif" style="border: 0px solid ; width: 223px; height: 47px;"></a><br>
+      </td>
+      <td align="right">
+      <p><a href="http://sourceforge.net/"><img src="http://sourceforge.net/sflogo.php?group_id=129887&amp;type=1" alt="SourceForge.net Logo" border="0" height="31" width="88"></a></p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+</body></html>
diff --git a/build/import_abi_metadata.py b/build/import_abi_metadata.py
new file mode 100644
index 0000000..8abc2f9
--- /dev/null
+++ b/build/import_abi_metadata.py
@@ -0,0 +1,88 @@
+#!/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.
+#
+"""Generates Make-importable code from meta/abis.json."""
+import argparse
+import json
+import os
+
+
+NEWLINE = '%NEWLINE%'
+
+
+def parse_args():
+    parser = argparse.ArgumentParser()
+
+    parser.add_argument(
+        'abis_file', metavar='ABIS_FILE', type=os.path.abspath,
+        help='Path to the abis.json file.')
+
+    return parser.parse_args()
+
+
+def generate_make_vars(abi_vars):
+    lines = []
+    for var, value in abi_vars.items():
+        lines.append('{} := {}'.format(var, value))
+    # https://www.gnu.org/software/make/manual/html_node/Shell-Function.html
+    # Make's $(shell) function replaces real newlines with spaces. Use
+    # something we can easily identify that's unlikely to appear in a variable
+    # so we can replace it in make.
+    return NEWLINE.join(lines)
+
+
+def metadata_to_make_vars(meta):
+    default_abis = []
+    deprecated_abis = []
+    lp32_abis = []
+    lp64_abis = []
+    for abi, abi_data in meta.items():
+        bitness = abi_data['bitness']
+        if bitness == 32:
+            lp32_abis.append(abi)
+        elif bitness == 64:
+            lp64_abis.append(abi)
+        else:
+            raise ValueError('{} bitness is unsupported value: {}'.format(
+                abi, bitness))
+
+        if abi_data['default']:
+            default_abis.append(abi)
+
+        if abi_data['deprecated']:
+            deprecated_abis.append(abi)
+
+    abi_vars = {
+        'NDK_DEFAULT_ABIS': ' '.join(sorted(default_abis)),
+        'NDK_DEPRECATED_ABIS': ' '.join(sorted(deprecated_abis)),
+        'NDK_KNOWN_DEVICE_ABI32S': ' '.join(sorted(lp32_abis)),
+        'NDK_KNOWN_DEVICE_ABI64S': ' '.join(sorted(lp64_abis)),
+    }
+
+    return abi_vars
+
+
+def main():
+    args = parse_args()
+    with open(args.abis_file) as abis_file:
+        abis = json.load(abis_file)
+
+    abi_vars = metadata_to_make_vars(abis)
+    print generate_make_vars(abi_vars)
+
+
+if __name__ == '__main__':
+    main()
diff --git a/build/ldflags_to_sanitizers.py b/build/ldflags_to_sanitizers.py
new file mode 100644
index 0000000..4a161aa
--- /dev/null
+++ b/build/ldflags_to_sanitizers.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 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.
+#
+"""Determines which sanitizers should be linked based on ldflags."""
+from __future__ import print_function
+
+import sys
+
+
+def sanitizers_from_args(args):
+    """Returns the sanitizers enabled by a given set of ldflags."""
+    sanitizers = set()
+    for arg in args:
+        if arg.startswith('-fsanitize='):
+            sanitizer_list = arg.partition('=')[2]
+            sanitizers |= set(sanitizer_list.split(','))
+        elif arg.startswith('-fno-sanitize='):
+            sanitizer_list = arg.partition('=')[2]
+            sanitizers -= set(sanitizer_list.split(','))
+    return sorted(list(sanitizers))
+
+
+def argv_to_module_arg_lists(args):
+    """Converts module ldflags from argv format to per-module lists.
+
+    Flags are passed to us in the following format:
+        ['global flag', '--module', 'flag1', 'flag2', '--module', 'flag 3']
+
+    These should be returned as a list for the global flags and a list of
+    per-module lists, i.e.:
+        ['global flag'], [['flag1', 'flag2'], ['flag1', 'flag3']]
+    """
+    modules = [[]]
+    for arg in args:
+        if arg == '--module':
+            modules.append([])
+        else:
+            modules[-1].append(arg)
+    return modules[0], modules[1:]
+
+
+def main(argv, stream=sys.stdout):
+    """Program entry point."""
+    # The only args we're guaranteed to see are the program name and at least
+    # one --module. GLOBAL_FLAGS might be empty, as might any of the
+    # MODULE_FLAGS sections.
+    if len(argv) < 2:
+        sys.exit(
+            'usage: ldflags_to_sanitizers.py [GLOBAL_FLAGS] '
+            '--module [MODULE_FLAGS] [--module [MODULE_FLAGS]...]')
+
+    global_flags, modules_flags = argv_to_module_arg_lists(argv[1:])
+    all_sanitizers = list(sanitizers_from_args(global_flags))
+    for module_flags in modules_flags:
+        all_sanitizers.extend(sanitizers_from_args(module_flags))
+    print(' '.join(sorted(set(all_sanitizers))), file=stream)
+
+
+if __name__ == '__main__':
+    main(sys.argv)
diff --git a/build/lib/__init__.py b/build/lib/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/build/lib/__init__.py
diff --git a/build/lib/build_support.py b/build/lib/build_support.py
new file mode 100644
index 0000000..7029f77
--- /dev/null
+++ b/build/lib/build_support.py
@@ -0,0 +1,178 @@
+#
+# Copyright (C) 2015 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 argparse
+import multiprocessing
+import os
+import shutil
+import site
+import subprocess
+import sys
+import tempfile
+import zipfile
+
+
+# "build" is not a valid package name for setuptools. This package will be
+# silently removed from the source distribution because setuptools thinks it's
+# the build directory rather than a python package named build. Pieces of this
+# package are being moved into the ndk package where they belong, but will
+# continue to be exported from here until we can chase down all the other
+# users.
+THIS_DIR = os.path.realpath(os.path.dirname(__file__))
+site.addsitedir(os.path.join(THIS_DIR, '../..'))
+
+# pylint: disable=wrong-import-position,unused-import
+from ndk.abis import (
+    ALL_ABIS,
+    ALL_ARCHITECTURES,
+    ALL_TOOLCHAINS,
+    ALL_TRIPLES,
+    LP32_ABIS,
+    LP64_ABIS,
+    arch_to_abis,
+    arch_to_toolchain,
+    arch_to_triple,
+    toolchain_to_arch,
+)
+
+from ndk.builds import make_repo_prop
+from ndk.hosts import get_default_host, host_to_tag
+from ndk.paths import (
+    android_path,
+    get_dist_dir,
+    get_out_dir,
+    ndk_path,
+    sysroot_path,
+    toolchain_path,
+)
+# pylint: enable=wrong-import-position,unused-import
+
+
+def minimum_platform_level(abi):
+    import ndk.abis
+    return ndk.abis.min_api_for_abi(abi)
+
+
+def jobs_arg():
+    return '-j{}'.format(multiprocessing.cpu_count() * 2)
+
+
+def build(cmd, args, intermediate_package=False):
+    package_dir = args.out_dir if intermediate_package else args.dist_dir
+    common_args = [
+        '--verbose',
+        '--package-dir={}'.format(package_dir),
+    ]
+
+    build_env = dict(os.environ)
+    build_env['NDK_BUILDTOOLS_PATH'] = android_path('ndk/build/tools')
+    build_env['ANDROID_NDK_ROOT'] = ndk_path()
+    subprocess.check_call(cmd + common_args, env=build_env)
+
+
+def make_package(name, directory, out_dir):
+    """Pacakges an NDK module for release.
+
+    Makes a zipfile of the single NDK module that can be released in the SDK
+    manager. This will handle the details of creating the repo.prop file for
+    the package.
+
+    Args:
+        name: Name of the final package, excluding extension.
+        directory: Directory to be packaged.
+        out_dir: Directory to place package.
+    """
+    if not os.path.isdir(directory):
+        raise ValueError('directory must be a directory: ' + directory)
+
+    path = os.path.join(out_dir, name + '.zip')
+    if os.path.exists(path):
+        os.unlink(path)
+
+    cwd = os.getcwd()
+    os.chdir(os.path.dirname(directory))
+    basename = os.path.basename(directory)
+    try:
+        # repo.prop files are excluded because in the event that we have a
+        # repo.prop in the root of the directory we're packaging, the repo.prop
+        # file we add later in this function will create a second entry (the
+        # zip format allows multiple files with the same path).
+        #
+        # The one we create here will point back to the tree that was used to
+        # build the package, and the original repo.prop can be reached from
+        # there, so no information is lost.
+        subprocess.check_call(
+            ['zip', '-x', '*.pyc', '-x', '*.pyo', '-x', '*.swp',
+             '-x', '*.git*', '-x', os.path.join(basename, 'repo.prop'), '-0qr',
+             path, basename])
+    finally:
+        os.chdir(cwd)
+
+    with zipfile.ZipFile(path, 'a', zipfile.ZIP_DEFLATED) as zip_file:
+        tmpdir = tempfile.mkdtemp()
+        try:
+            make_repo_prop(tmpdir)
+            arcname = os.path.join(basename, 'repo.prop')
+            zip_file.write(os.path.join(tmpdir, 'repo.prop'), arcname)
+        finally:
+            shutil.rmtree(tmpdir)
+
+
+def merge_license_files(output_path, files):
+    licenses = []
+    for license_path in files:
+        with open(license_path) as license_file:
+            licenses.append(license_file.read())
+
+    with open(output_path, 'w') as output_file:
+        output_file.write('\n'.join(licenses))
+
+
+class ArgParser(argparse.ArgumentParser):
+    def __init__(self):
+        super(ArgParser, self).__init__()
+
+        self.add_argument(
+            '--host', choices=('darwin', 'linux', 'windows', 'windows64'),
+            default=get_default_host(),
+            help='Build binaries for given OS (e.g. linux).')
+
+        self.add_argument(
+            '--out-dir', help='Directory to place temporary build files.',
+            type=os.path.realpath, default=get_out_dir())
+
+        # The default for --dist-dir has to be handled after parsing all
+        # arguments because the default is derived from --out-dir. This is
+        # handled in run().
+        self.add_argument(
+            '--dist-dir', help='Directory to place the packaged artifact.',
+            type=os.path.realpath)
+
+
+def run(main_func, arg_parser=ArgParser):
+    if 'ANDROID_BUILD_TOP' not in os.environ:
+        top = os.path.join(os.path.dirname(__file__), '../../..')
+        os.environ['ANDROID_BUILD_TOP'] = os.path.realpath(top)
+
+    args = arg_parser().parse_args()
+
+    if args.dist_dir is None:
+        args.dist_dir = get_dist_dir(args.out_dir)
+
+    # We want any paths to be relative to the invoked build script.
+    main_filename = os.path.realpath(sys.modules['__main__'].__file__)
+    os.chdir(os.path.dirname(main_filename))
+
+    main_func(args)
diff --git a/build/ndk-build b/build/ndk-build
new file mode 100755
index 0000000..a4c23e3
--- /dev/null
+++ b/build/ndk-build
@@ -0,0 +1,296 @@
+#!/bin/bash
+#
+# Copyright (C) 2010 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.
+#
+#  This shell script is a wrapper to launch the NDK build from the
+#  command-line inside an application project path.
+#
+#  Typical usage is:
+#
+#     cd $PROJECT_PATH
+#     ndk-build
+#
+#  Assuming that the Android NDK root path is in your PATH. However,
+#  you can also invoke it directly as:
+#
+#     $NDK_ROOT/ndk-build
+#
+#  This really is a tiny wrapper around GNU Make.
+#
+
+# Ensure we get the full path of this script's directory
+# this is needed if the caller uses the -C <path> GNU Make
+# option, as in:
+#
+#    cd ndk
+#    ./ndk-build -C <project-path>
+#
+PROGDIR=`dirname $0`
+PROGDIR=`cd $PROGDIR && pwd -P`
+ANDROID_NDK_ROOT=$PROGDIR/..
+
+# Check if absolute NDK path contain space
+#
+case $PROGDIR in
+    *\ *) echo "ERROR: NDK path cannot contain space"
+          exit 1
+        ;;
+esac
+
+# If NDK_LOG is set to 1 or true in the environment, or the command-line
+# then enable log messages below
+if [ -z "$NDK_LOG" ]; then
+  NDK_LOG=0
+fi
+
+if [ -z "$NDK_ANALYZE" ]; then
+  NDK_ANALYZE=0
+fi
+
+PROJECT_PATH=
+PROJECT_PATH_NEXT=
+NDK_ANALYZER_OUT=
+for opt; do
+    if [ -z "$PROJECT_PATH" -a "$PROJECT_PATH_NEXT" = "yes" ] ; then
+        PROJECT_PATH=$opt
+        PROJECT_PATH_NEXT=
+    else
+        case $opt in
+          NDK_LOG=1|NDK_LOG=true)
+            NDK_LOG=1
+            ;;
+          NDK_LOG=*)
+            NDK_LOG=0
+            ;;
+          NDK_ANALYZE=1|NDK_ANALYZE=true)
+            NDK_ANALYZE=1
+            ;;
+          NDK_ANALYZE=*)
+            NDK_ANALYZE=0
+            ;;
+          NDK_ANALYZER_OUT=*)
+            NDK_ANALYZER_OUT=${opt#NDK_ANALYZER_OUT=}
+            ;;
+          NDK_TOOLCHAIN_VERSION=*)
+            NDK_TOOLCHAIN_VERSION=${opt#NDK_TOOLCHAIN_VERSION=}
+            ;;
+          APP_ABI=*)
+            APP_ABI=${opt#APP_ABI=}
+            ;;
+          -C)
+            PROJECT_PATH_NEXT="yes"
+            ;;
+        esac
+    fi
+done
+
+if [ "$NDK_LOG" = "true" ]; then
+  NDK_LOG=1
+fi
+
+if [ "$NDK_ANALYZE" = "true" ]; then
+  NDK_ANALYZE=1
+fi
+
+if [ "$NDK_LOG" = "1" ]; then
+  log () {
+    echo "$@"
+  }
+else
+  log () {
+    : # nothing
+  }
+fi
+
+# Detect host operating system and architecture
+# The 64-bit / 32-bit distinction gets tricky on Linux and Darwin because
+# uname -m returns the kernel's bit size, and it's possible to run with
+# a 64-bit kernel and a 32-bit userland.
+#
+HOST_OS=$(uname -s)
+case $HOST_OS in
+  Darwin) HOST_OS=darwin;;
+  Linux) HOST_OS=linux;;
+  FreeBsd) HOST_OS=freebsd;;
+  CYGWIN*|*_NT-*) HOST_OS=cygwin;;
+  *) echo "ERROR: Unknown host operating system: $HOST_OS"
+     exit 1
+esac
+log "HOST_OS=$HOST_OS"
+
+HOST_ARCH=$(uname -m)
+case $HOST_ARCH in
+    i?86) HOST_ARCH=x86;;
+    x86_64|amd64) HOST_ARCH=x86_64;;
+    *) echo "ERROR: Unknown host CPU architecture: $HOST_ARCH"
+       exit 1
+esac
+log "HOST_ARCH=$HOST_ARCH"
+
+# Detect 32-bit userland on 64-bit kernels
+HOST_TAG="$HOST_OS-$HOST_ARCH"
+case $HOST_TAG in
+  linux-x86_64|darwin-x86_64)
+    # we look for x86_64 or x86-64 in the output of 'file' for our shell
+    # the -L flag is used to dereference symlinks, just in case.
+    file -L "$SHELL" | grep -q "x86[_-]64"
+    if [ $? != 0 ]; then
+      HOST_ARCH=x86
+      log "HOST_ARCH=$HOST_ARCH (32-bit userland detected)"
+    fi
+    ;;
+esac
+
+# Check that we have 64-bit binaries on 64-bit system, otherwise fallback
+# on 32-bit ones. This gives us more freedom in packaging the NDK.
+LOG_MESSAGE=
+if [ $HOST_ARCH = x86_64 ]; then
+  if [ ! -d $ANDROID_NDK_ROOT/prebuilt/$HOST_TAG ]; then
+    HOST_ARCH=x86
+    LOG_MESSAGE="(no 64-bit prebuilt binaries detected)"
+  fi
+fi
+
+HOST_TAG=$HOST_OS-$HOST_ARCH
+# Special case windows-x86 -> windows
+if [ $HOST_TAG = windows-x86 ]; then
+  HOST_TAG=windows
+fi
+log "HOST_TAG=$HOST_TAG $LOG_MESSAGE"
+
+# If GNUMAKE is defined, check that it points to a valid file
+if [ -n "$GNUMAKE" ] ; then
+    ABS_GNUMAKE=`which $GNUMAKE 2> /dev/null`
+    if [ $? != 0 ] ; then
+        echo "ERROR: Your GNUMAKE variable is defined to an invalid name: $GNUMAKE"
+        echo "Please fix it to point to a valid make executable (e.g. /usr/bin/make)"
+        exit 1
+    fi
+    GNUMAKE="$ABS_GNUMAKE"
+    log "GNUMAKE=$GNUMAKE (from environment variable)"
+else
+    # Otherwise use the prebuilt version for our host tag, if it exists
+    # Note: we intentionally do not provide prebuilt make binaries for Cygwin
+    # or MSys.
+    GNUMAKE=$ANDROID_NDK_ROOT/prebuilt/$HOST_TAG/bin/make
+    if [ ! -f "$GNUMAKE" ]; then
+        # Otherwise, use 'make' and check that it is available
+        GNUMAKE=`which make 2> /dev/null`
+        if [ $? != 0 ] ; then
+            echo "ERROR: Cannot find 'make' program. Please install Cygwin make package"
+            echo "or define the GNUMAKE variable to point to it."
+            exit 1
+        fi
+        log "GNUMAKE=$GNUMAKE (system path)"
+    else
+        log "GNUMAKE=$GNUMAKE (NDK prebuilt)"
+    fi
+fi
+
+# On Windows, when running under cygwin, check that we are
+# invoking a cygwin-compatible GNU Make binary. It is unfortunately
+# common for app developers to have another non cygwin-compatible
+# 'make' program in their PATH.
+#
+if [ "$OSTYPE" = "cygwin" ] ; then
+    GNUMAKE=`cygpath -u $GNUMAKE`
+    PROGDIR_MIXED=`cygpath -m $PROGDIR`
+    CYGWIN_GNUMAKE=`$GNUMAKE -f "$PROGDIR_MIXED/core/check-cygwin-make.mk" 2>&1`
+    if [ $? != 0 ] ; then
+        echo "ERROR: You are using a non-Cygwin compatible Make program."
+        echo "Currently using: `cygpath -m $GNUMAKE`"
+        echo ""
+        echo "To solve the issue, follow these steps:"
+        echo ""
+        echo "1. Ensure that the Cygwin 'make' package is installed."
+        echo "   NOTE: You will need GNU Make 3.81 or later!"
+        echo ""
+        echo "2. Define the GNUMAKE environment variable to point to it, as in:"
+        echo ""
+        echo "     export GNUMAKE=/usr/bin/make"
+        echo ""
+        echo "3. Call 'ndk-build' again."
+        echo ""
+        exit 1
+    fi
+    log "Cygwin-compatible GNU make detected"
+fi
+
+if [ "$NDK_ANALYZE" = 1 ]; then
+    . $PROGDIR/tools/dev-defaults.sh  # for DEFAULT_LLVM_VERSION
+
+    # Return flags send in env. or command line which are enough to retrive APP_ABI and TOOLCHAIN_PREFIX later
+    gen_flags ()
+    {
+        local FLAGS=
+
+        if [ -n "$PROJECT_PATH" ] ; then
+            FLAGS=$FLAGS" -C $PROJECT_PATH"
+        fi
+        if [ -n "$APP_ABI" ] ; then
+            FLAGS=$FLAGS" APP_ABI=$APP_ABI"
+        fi
+        if [ -n "$NDK_TOOLCHAIN_VERSION" ] ; then
+            FLAGS=$FLAGS" NDK_TOOLCHAIN_VERSION=$NDK_TOOLCHAIN_VERSION"
+        fi
+        echo "$FLAGS"
+    }
+
+    get_build_var ()
+    {
+        local VAR=$1
+        local FLAGS=`gen_flags`
+        $GNUMAKE --no-print-dir -f $PROGDIR/core/build-local.mk $FLAGS DUMP_${VAR} | tail -1
+    }
+
+    get_build_var_for_abi ()
+    {
+        local VAR=$1
+        local ABI=$2
+        local FLAGS=`gen_flags`
+        $GNUMAKE --no-print-dir -f $PROGDIR/core/build-local.mk $FLAGS DUMP_${VAR} APP_ABI=${ABI} | tail -1
+    }
+
+    APP_ABIS=`get_build_var APP_ABI`
+    TOOLCHAIN=`get_build_var NDK_TOOLCHAIN_VERSION`
+    for ABI in $APP_ABIS; do
+        TOOLCHAIN_PREFIX=`get_build_var_for_abi TOOLCHAIN_PREFIX $ABI`
+        LLVM_PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/$HOST_TAG
+        ANALYZER_OUT=`get_build_var NDK_APP_ANALYZER_OUT`
+
+        if [ "$TOOLCHAIN" = "clang" ]; then
+            ANALYZER_CC=$LLVM_PATH/bin/clang
+            ANALYZER_CXX=$LLVM_PATH/bin/clang++
+        else
+            ANALYZER_CC=${TOOLCHAIN_PREFIX}gcc
+            ANALYZER_CXX=${TOOLCHAIN_PREFIX}g++
+        fi
+
+        ANALYZER_OUT_FLAG=
+        if [ -n "$NDK_ANALYZER_OUT" ]; then
+            ANALYZER_OUT_FLAG="-o $NDK_ANALYZER_OUT/$ABI"
+        fi
+
+        perl $LLVM_PATH/bin/scan-build \
+            --use-cc $ANALYZER_CC \
+            --use-c++ $ANALYZER_CXX \
+            --status-bugs \
+            $ANALYZER_OUT_FLAG \
+            $GNUMAKE -f $PROGDIR/core/build-local.mk "$@" APP_ABI=$ABI
+    done
+else
+    $GNUMAKE -f $PROGDIR/core/build-local.mk "$@"
+fi
+
diff --git a/build/ndk-build.cmd b/build/ndk-build.cmd
new file mode 100755
index 0000000..237ec64
--- /dev/null
+++ b/build/ndk-build.cmd
@@ -0,0 +1,7 @@
+@echo off
+set NDK_ROOT=%~dp0\..
+set PREBUILT_PATH=%NDK_ROOT%\prebuilt\windows-x86_64
+if exist %PREBUILT_PATH% goto FOUND
+set PREBUILT_PATH=%NDK_ROOT%\prebuilt\windows
+:FOUND
+"%PREBUILT_PATH%\bin\make.exe" -f "%NDK_ROOT%\build\core\build-local.mk" SHELL=cmd %*
diff --git a/build/repo.prop b/build/repo.prop
new file mode 100644
index 0000000..695d6f9
--- /dev/null
+++ b/build/repo.prop
@@ -0,0 +1,59 @@
+platform/bionic 0237218b90c81a6977be59971d52f20063c0793c
+platform/development b7732bd3281041709d40c6e07cd8e66c682cb943
+platform/external/googletest 220810a546aa9db3a3cfd39874663884dbbe8c59
+platform/external/libcxx a511ded040ac6c61325d8066599a3beb417ef83a
+platform/external/libcxxabi fa5a0a5055c2da528f4acd8f4ac5a62b2da7d133
+platform/external/libunwind_llvm fecc6f26cfdbfc9cf0ea2021629ac6e85b7c0113
+platform/external/llvm 79c7f5d7a2be0de081031e0ebcd481ab7905854b
+platform/external/shaderc/glslang 8f05973b2cb583fbc6f950c137396cc3e9fdc50f
+platform/external/shaderc/shaderc 6cd7a08592cf568d595069552d3bb6cf21addb66
+platform/external/shaderc/spirv-headers 07b132823683dfbd2ff06794fc056582427987f9
+platform/external/shaderc/spirv-tools 28bda583e8f8e09d8747cfee019cf38c7a8a91e9
+platform/external/vulkan-validation-layers e4dbf1abb9d08e1d05fd201ecb307bc7c38cb595
+platform/manifest 84e2d198c54099754062710cbfca859831cea689
+platform/ndk cab15e04503b983275e9bf9473e987640f9aec92
+platform/prebuilts/clang/host/darwin-x86 8ff3ad1ad95e9c4f20bf3734a26b002fb4100029
+platform/prebuilts/clang/host/linux-x86 585b7364a96a55546256e158a78a9ffb7a02c889
+platform/prebuilts/clang/host/windows-x86 c56e837ed056a5a2b49244f953cc4fe92b5f9847
+platform/prebuilts/clang/host/windows-x86_32 63ba9571a8f83ed2318bfb9b894009dd709b23df
+platform/prebuilts/cmake/darwin-x86 f3bfe547014d2d751b7547ad7847a51b0ea34dc8
+platform/prebuilts/cmake/linux-x86 da4b9cb08341185e002c8a8c5df73533cdb93b41
+platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9 52b2154bec58eccfab8218871571bfd88165b60f
+platform/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8 6d08ca9f45ff685648fd13c75bf5cac4b11c19bb
+platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9 f6f8888de381d21f6cfbd91319e584777db60f8d
+platform/prebuilts/gcc/darwin-x86/host/headers 4ac4f7cc41cf3c9e36fc3d6cf37fd1cfa9587a68
+platform/prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1 ec5aa66aaa4964c27564d0ec84dc1f18a2d72b7e
+platform/prebuilts/gcc/darwin-x86/mips/mips64el-linux-android-4.9 d942564c9331f07026a8f78502d8571206eb7be4
+platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9 a2aa0df7a6748bfc13d7e90c9fe41fb915164d30
+platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 3b7cd710b8c4e3dddd22979ff6148514b996293a
+platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8 26e93f6af47f7bd3a9beb5c102a5f45e19bfa38a
+platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9 c586b970aed16e970f23e0fb4197920f6b221c7f
+platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8 bf0dafede3fafd5bf28c631489cd15fd222c139d
+platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8 2ccb38af8c940f1feef62ff5986f4bbc5d899e66
+platform/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8 e76a9a506d7ad132f107eb2f7c27b6a8ccb68b91
+platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9 388fdc4995d374d76a0c4b292afabac91638e134
+platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9 a448493cc447864f1838d4d220eadd901e36787a
+platform/prebuilts/ndk 47939c56adb55b4563e20e2460b42d13978338b2
+platform/prebuilts/ninja/darwin-x86 00f798346dedb4a7a6a6dcc9ad32ff09d66ee0db
+platform/prebuilts/ninja/linux-x86 6369b19fc3fbe765636af75d394627e2b92599ed
+platform/prebuilts/python/darwin-x86/2.7.5 0c5958b1636c47ed7c284f859c8e805fd06a0e63
+platform/prebuilts/python/linux-x86/2.7.5 47abe498f32ff1721f5177ad5a51ee0e35d969ed
+platform/prebuilts/renderscript/host/darwin-x86 a0ede5664b4741348c0b6c8d5da06d483dcf2876
+platform/prebuilts/renderscript/host/linux-x86 68a0a1ddacb81c97d718f46ad464a3851d0b67af
+platform/prebuilts/renderscript/host/windows-x86 5df9f20565e63906167c82f6120c78e969b3b467
+platform/prebuilts/simpleperf 29b5005620701923580c5000f6b215f664c68931
+toolchain/binutils 6fa214b61c53685d846a18d1001aa437c8338821
+toolchain/build 58be6006bb71abb97d7cdff7be3e73d55bbc22b8
+toolchain/cloog 604793eab97d360aef729f064674569ee6dbf3e1
+toolchain/expat 40172a0ae9d40a068f1e1a48ffcf6a1ccf765ed5
+toolchain/gcc 430f43829fa42b459ccbb53b44843c54c8ba4550
+toolchain/gdb 3b4e21d2318bc1b6547e45f3393514e7b0be7df2
+toolchain/gmp b2acd5dbf47868ac5b5bc844e16d2cadcbd4c810
+toolchain/isl 0ccf95726af8ce58ad61ff474addbce3a31ba99c
+toolchain/mpc 835d16e92eed875638a8b5d552034c3b1aae045b
+toolchain/mpfr de979fc377db766591e7feaf052f0de59be46e76
+toolchain/ppl 979062d362bc5a1c00804237b408b19b4618fb24
+toolchain/python 2f9d862430f8b1d838f0ba1adac0bdc2b7142a3e
+toolchain/sed 45df23d6dc8b51ea5cd903d023c10fd7d72415b9
+toolchain/xz a0eb1f5763e7b4a3daf4fd7d1ac9504058cc1082
+toolchain/yasm 89fed6578607187830790c96d7310cf5fc635ffd
diff --git a/build/test_extract_manifest.py b/build/test_extract_manifest.py
new file mode 100644
index 0000000..698e19e
--- /dev/null
+++ b/build/test_extract_manifest.py
@@ -0,0 +1,174 @@
+#
+# 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 textwrap
+import unittest
+import xml.etree.ElementPath
+
+import build.extract_manifest
+
+
+class ExtractMinSdkVersionTest(unittest.TestCase):
+    def testMinSdkVersion(self):
+        xml_str = textwrap.dedent("""\
+            <?xml version="1.0" encoding="utf-8"?>
+            <manifest
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                package="com.test"
+                android:versionCode="1"
+                android:versionName="1.0">
+              <application
+                android:label="@string/app_name"
+                android:debuggable="true">
+                <activity
+                  android:name=".Test"
+                  android:label="@string/app_name">
+                </activity>
+              </application>
+              <uses-sdk android:minSdkVersion="9"/>
+            </manifest>
+            """)
+        root = xml.etree.ElementTree.fromstring(xml_str)
+
+        self.assertEqual(
+            '9', build.extract_manifest.get_minsdkversion(root))
+
+    def testUsesSdkMissingMinSdkVersion(self):
+        xml_str = textwrap.dedent("""\
+            <?xml version="1.0" encoding="utf-8"?>
+            <manifest
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                package="com.test"
+                android:versionCode="1"
+                android:versionName="1.0">
+              <application
+                android:label="@string/app_name"
+                android:debuggable="true">
+                <activity
+                  android:name=".Test"
+                  android:label="@string/app_name">
+                </activity>
+              </application>
+              <uses-sdk android:maxSdkVersion="21"/>
+            </manifest>
+            """)
+        root = xml.etree.ElementTree.fromstring(xml_str)
+
+        self.assertEqual(
+            '', build.extract_manifest.get_minsdkversion(root))
+
+    def testNoUsesSdk(self):
+        xml_str = textwrap.dedent("""\
+            <?xml version="1.0" encoding="utf-8"?>
+            <manifest
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                package="com.test"
+                android:versionCode="1"
+                android:versionName="1.0">
+              <application
+                android:label="@string/app_name"
+                android:debuggable="true">
+                <activity
+                  android:name=".Test"
+                  android:label="@string/app_name">
+                </activity>
+              </application>
+            </manifest>
+            """)
+        root = xml.etree.ElementTree.fromstring(xml_str)
+
+        self.assertEqual(
+            '', build.extract_manifest.get_minsdkversion(root))
+
+
+class ExtractMinSdkVersionTest(unittest.TestCase):
+    def testIsDebuggable(self):
+        xml_str = textwrap.dedent("""\
+            <?xml version="1.0" encoding="utf-8"?>
+            <manifest
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                package="com.test"
+                android:versionCode="1"
+                android:versionName="1.0">
+              <application
+                android:label="@string/app_name"
+                android:debuggable="true">
+              </application>
+            </manifest>
+            """)
+        root = xml.etree.ElementTree.fromstring(xml_str)
+
+        self.assertEqual(
+            'true', build.extract_manifest.get_debuggable(root))
+
+    def testIsNotDebuggable(self):
+        xml_str = textwrap.dedent("""\
+            <?xml version="1.0" encoding="utf-8"?>
+            <manifest
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                package="com.test"
+                android:versionCode="1"
+                android:versionName="1.0">
+              <application
+                android:label="@string/app_name"
+                android:debuggable="false">
+              </application>
+            </manifest>
+            """)
+        root = xml.etree.ElementTree.fromstring(xml_str)
+
+        self.assertEqual(
+            'false', build.extract_manifest.get_debuggable(root))
+
+    def testBogusValue(self):
+        xml_str = textwrap.dedent("""\
+            <?xml version="1.0" encoding="utf-8"?>
+            <manifest
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                package="com.test"
+                android:versionCode="1"
+                android:versionName="1.0">
+              <application
+                android:label="@string/app_name"
+                android:debuggable="bogus">
+              </application>
+            </manifest>
+            """)
+        root = xml.etree.ElementTree.fromstring(xml_str)
+
+        self.assertEqual(
+            'false', build.extract_manifest.get_debuggable(root))
+
+    def testNotSet(self):
+        xml_str = textwrap.dedent("""\
+            <?xml version="1.0" encoding="utf-8"?>
+            <manifest
+                xmlns:android="http://schemas.android.com/apk/res/android"
+                package="com.test"
+                android:versionCode="1"
+                android:versionName="1.0">
+              <application android:label="@string/app_name">
+                <activity
+                  android:name=".Test"
+                  android:label="@string/app_name">
+                </activity>
+              </application>
+              <uses-sdk android:maxSdkVersion="21"/>
+            </manifest>
+            """)
+        root = xml.etree.ElementTree.fromstring(xml_str)
+
+        self.assertEqual(
+            'false', build.extract_manifest.get_debuggable(root))
diff --git a/build/test_extract_platform.py b/build/test_extract_platform.py
new file mode 100644
index 0000000..d4619fb
--- /dev/null
+++ b/build/test_extract_platform.py
@@ -0,0 +1,60 @@
+#
+# 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 textwrap
+import unittest
+
+import build.extract_platform
+
+
+class ExtractPlatformTest(unittest.TestCase):
+    def testNumericVersion(self):
+        props_file = textwrap.dedent("""\
+            some
+            # other
+            junk
+            target=android-9
+            foo
+            """).splitlines()
+
+        self.assertEqual(
+            'android-9', build.extract_platform.get_platform(props_file))
+
+    def testNamedVersion(self):
+        props_file = textwrap.dedent("""\
+            some
+            # other
+            junk
+            target=android-nougat
+            foo
+            """).splitlines()
+
+        self.assertEqual(
+            'android-nougat', build.extract_platform.get_platform(props_file))
+
+    def testVendorVersion(self):
+        props_file = textwrap.dedent("""\
+            some
+            # other
+            junk
+            target=vendor:something:21
+            foo
+            """).splitlines()
+
+        self.assertEqual(
+            'android-21', build.extract_platform.get_platform(props_file))
+
+    def testNoVersion(self):
+        self.assertEqual('unknown', build.extract_platform.get_platform([]))
diff --git a/build/test_gen_cygpath.py b/build/test_gen_cygpath.py
new file mode 100644
index 0000000..bb95b56
--- /dev/null
+++ b/build/test_gen_cygpath.py
@@ -0,0 +1,91 @@
+#
+# 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 textwrap
+import unittest
+
+import build.gen_cygpath
+
+
+class GetMountsTest(unittest.TestCase):
+    def testSingleMount(self):
+        mount_output = 'C:/cygwin on / type ntfs (binary,auto)'
+        self.assertEqual(
+            [('/', 'C:/cygwin')], build.gen_cygpath.get_mounts(mount_output))
+
+    def testCaseInsensitiveMount(self):
+        mount_output = 'C: on /cygdrive/c type ntfs'
+        expected_output = [
+            ('/cygdrive/c', 'C:'),
+            ('/cygdrive/C', 'C:'),
+        ]
+
+        self.assertEqual(
+            expected_output, build.gen_cygpath.get_mounts(mount_output))
+
+    def testManyMounts(self):
+        mount_output = textwrap.dedent("""\
+            C:/cygwin/bin on /usr/bin type ntfs (binary,auto)
+            C:/cygwin/lib on /usr/lib type ntfs (binary,auto)
+            C:/cygwin on / type ntfs (binary,auto)
+            C: on /cygdrive/c type ntfs (binary,posix=0,user,noumount,auto)
+            D: on /cygdrive/d type udf (binary,posix=0,user,noumount,auto)
+            """)
+
+        expected_output = [
+            ('/', 'C:/cygwin'),
+            ('/usr/bin', 'C:/cygwin/bin'),
+            ('/usr/lib', 'C:/cygwin/lib'),
+            ('/cygdrive/c', 'C:'),
+            ('/cygdrive/C', 'C:'),
+            ('/cygdrive/d', 'D:'),
+            ('/cygdrive/D', 'D:'),
+        ]
+
+        self.assertEqual(
+            expected_output, build.gen_cygpath.get_mounts(mount_output))
+
+
+class MakeCygpathFunctionTest(unittest.TestCase):
+    def testSingleMount(self):
+        mounts = [('/', 'C:/cygwin')]
+        expected_output = '$(patsubst /%,C:/cygwin/%,\n$1)'
+
+        self.assertEqual(
+            expected_output, build.gen_cygpath.make_cygpath_function(mounts))
+
+    def testManyMounts(self):
+        mounts = [
+            ('/', 'C:/cygwin'),
+            ('/usr/bin', 'C:/cygwin/bin'),
+            ('/usr/lib', 'C:/cygwin/lib'),
+            ('/cygdrive/c', 'C:'),
+            ('/cygdrive/C', 'C:'),
+            ('/cygdrive/d', 'D:'),
+            ('/cygdrive/D', 'D:'),
+        ]
+
+        expected_output = textwrap.dedent("""\
+            $(patsubst /%,C:/cygwin/%,
+            $(patsubst /usr/bin/%,C:/cygwin/bin/%,
+            $(patsubst /usr/lib/%,C:/cygwin/lib/%,
+            $(patsubst /cygdrive/c/%,C:/%,
+            $(patsubst /cygdrive/C/%,C:/%,
+            $(patsubst /cygdrive/d/%,D:/%,
+            $(patsubst /cygdrive/D/%,D:/%,
+            $1)))))))""")
+
+        self.assertEqual(
+            expected_output, build.gen_cygpath.make_cygpath_function(mounts))
diff --git a/build/test_import_abi_metadata.py b/build/test_import_abi_metadata.py
new file mode 100644
index 0000000..ebf86cd
--- /dev/null
+++ b/build/test_import_abi_metadata.py
@@ -0,0 +1,79 @@
+#!/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.
+#
+"""Tests for import_abi_metadata.py."""
+import unittest
+
+import build.import_abi_metadata
+
+
+class ImportAbiMetadataTest(unittest.TestCase):
+    def test_generate_make_vars(self):
+        self.assertEqual(
+            'foo := bar',
+            build.import_abi_metadata.generate_make_vars(
+                {'foo': 'bar'}))
+        self.assertEqual(
+            build.import_abi_metadata.NEWLINE.join(
+                ['foo := bar', 'baz := qux']),
+            build.import_abi_metadata.generate_make_vars(
+                {'foo': 'bar', 'baz': 'qux'}))
+
+    def test_metadata_to_make_vars(self):
+        make_vars = build.import_abi_metadata.metadata_to_make_vars({
+            'armeabi': {
+                'bitness': 32,
+                'default': False,
+                'deprecated': True,
+            },
+            'armeabi-v7a': {
+                'bitness': 32,
+                'default': True,
+                'deprecated': False,
+            },
+            'arm64-v8a': {
+                'bitness': 64,
+                'default': True,
+                'deprecated': False,
+            },
+            'mips': {
+                'bitness': 32,
+                'default': False,
+                'deprecated': False,
+            },
+            'mips64': {
+                'bitness': 64,
+                'default': False,
+                'deprecated': False,
+            },
+            'x86': {
+                'bitness': 32,
+                'default': True,
+                'deprecated': False,
+            },
+            'x86_64': {
+                'bitness': 64,
+                'default': True,
+                'deprecated': False,
+            },
+        })
+
+        self.assertDictEqual({
+            'NDK_DEFAULT_ABIS': 'arm64-v8a armeabi-v7a x86 x86_64',
+            'NDK_DEPRECATED_ABIS': 'armeabi',
+            'NDK_KNOWN_DEVICE_ABI32S': 'armeabi armeabi-v7a mips x86',
+            'NDK_KNOWN_DEVICE_ABI64S': 'arm64-v8a mips64 x86_64',
+        }, make_vars)
diff --git a/build/test_ldflags_to_sanitizers.py b/build/test_ldflags_to_sanitizers.py
new file mode 100644
index 0000000..db195ea
--- /dev/null
+++ b/build/test_ldflags_to_sanitizers.py
@@ -0,0 +1,104 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2018 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.
+#
+"""Does test_ldflags_to_sanitizers stuff."""
+from __future__ import absolute_import
+import unittest
+
+try:
+    from StringIO import StringIO
+except ImportError:
+    from io import StringIO
+
+from build.ldflags_to_sanitizers import argv_to_module_arg_lists
+from build.ldflags_to_sanitizers import main as ldflags_main
+from build.ldflags_to_sanitizers import sanitizers_from_args
+
+
+class LdflagsToSanitizersTest(unittest.TestCase):
+    def test_sanitizers_from_args_no_sanitize_args(self):
+        """Tests that we don't identify sanitizers when there are none."""
+        self.assertListEqual([], sanitizers_from_args([]))
+        self.assertListEqual([], sanitizers_from_args(['foo', 'bar']))
+
+    def test_sanitizers_from_args_enabled_sanitizers(self):
+        """Tests that we find enabled sanitizers."""
+        self.assertListEqual(
+            ['address'], sanitizers_from_args(['-fsanitize=address']))
+        self.assertListEqual(
+            ['address'], sanitizers_from_args(['-fsanitize=address', 'foo']))
+        self.assertListEqual(
+            ['address', 'undefined'],
+            sanitizers_from_args(
+                ['-fsanitize=address', '-fsanitize=undefined']))
+        self.assertListEqual(
+            ['address', 'undefined'],
+            sanitizers_from_args(['-fsanitize=address,undefined']))
+        self.assertListEqual(
+            ['address', 'undefined'],
+            sanitizers_from_args(['-fsanitize=address,undefined', 'foo']))
+
+    def test_sanitizers_from_args_disabled_sanitizers(self):
+        """Tests that we don't find disabled sanitizers."""
+        self.assertListEqual([], sanitizers_from_args(
+            ['-fno-sanitize=address']))
+        self.assertListEqual([], sanitizers_from_args(
+            ['-fno-sanitize=address', 'foo']))
+        self.assertListEqual([], sanitizers_from_args(
+            ['-fno-sanitize=address', '-fno-sanitize=undefined']))
+        self.assertListEqual([], sanitizers_from_args(
+            ['-fno-sanitize=address,undefined']))
+        self.assertListEqual([], sanitizers_from_args(
+            ['-fno-sanitize=address,undefined', 'foo']))
+
+    def test_sanitizers_from_args_enabled_disabled_sanitizers(self):
+        """Tests that we correctly identify only enabled sanitizers."""
+        self.assertListEqual([], sanitizers_from_args(
+            ['-fsanitize=address', '-fno-sanitize=address']))
+        self.assertListEqual(['address'], sanitizers_from_args(
+            ['-fsanitize=address', '-fno-sanitize=address',
+             '-fsanitize=address']))
+        self.assertListEqual([], sanitizers_from_args(
+            ['-fsanitize=address', '-fno-sanitize=address',
+             '-fsanitize=address', '-fno-sanitize=address']))
+        self.assertListEqual(['undefined'], sanitizers_from_args(
+            ['-fsanitize=address,undefined', '-fno-sanitize=address']))
+        self.assertListEqual(['undefined'], sanitizers_from_args(
+            ['-fsanitize=address', '-fsanitize=undefined',
+             '-fno-sanitize=address']))
+
+    def test_argv_to_module_arg_lists(self):
+        """Tests that modules' arguments are properly identified."""
+        self.assertTupleEqual(([], []), argv_to_module_arg_lists([]))
+        self.assertTupleEqual((['foo'], []), argv_to_module_arg_lists(['foo']))
+
+        self.assertTupleEqual(
+            ([], [['foo', 'bar'], ['baz']]),
+            argv_to_module_arg_lists(
+                ['--module', 'foo', 'bar', '--module', 'baz']))
+
+        self.assertTupleEqual(
+            (['foo', 'bar'], [['baz']]),
+            argv_to_module_arg_lists(['foo', 'bar', '--module', 'baz']))
+
+    def test_main(self):
+        """Test that the program itself works."""
+        sio = StringIO()
+        ldflags_main(
+            ['ldflags_to_sanitizers.py', '-fsanitize=undefined', '--module',
+             '-fsanitize=address,thread', '-fno-sanitize=thread',
+             '--module', '-fsanitize=undefined'], sio)
+        self.assertEqual('address undefined', sio.getvalue().strip())
diff --git a/build/tools/build-cxx-stl.sh b/build/tools/build-cxx-stl.sh
new file mode 100755
index 0000000..ef7a507
--- /dev/null
+++ b/build/tools/build-cxx-stl.sh
@@ -0,0 +1,529 @@
+#!/bin/bash
+#
+# Copyright (C) 2013 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.
+#
+#  This shell script is used to rebuild one of the NDK C++ STL
+#  implementations from sources. To use it:
+#
+#   - Define CXX_STL to one of 'stlport' or 'libc++'
+#   - Run it.
+#
+
+# include common function and variable definitions
+. `dirname $0`/prebuilt-common.sh
+. `dirname $0`/builder-funcs.sh
+
+CXX_STL_LIST="stlport libc++"
+
+PROGRAM_PARAMETERS=""
+
+PROGRAM_DESCRIPTION=\
+"Rebuild one of the following NDK C++ runtimes: $CXX_STL_LIST.
+
+This script is called when pacakging a new NDK release. It will simply
+rebuild the static and shared libraries of a given C++ runtime from
+sources.
+
+Use the --stl=<name> option to specify which runtime you want to rebuild.
+
+This requires a temporary NDK installation containing platforms and
+toolchain binaries for all target architectures.
+
+By default, this will try with the current NDK directory, unless
+you use the --ndk-dir=<path> option.
+
+If you want to use clang to rebuild the binaries, please use
+--llvm-version=<ver> option.
+
+The output will be placed in appropriate sub-directories of
+<ndk>/sources/cxx-stl/$CXX_STL_SUBDIR, but you can override this with
+the --out-dir=<path> option.
+"
+
+CXX_STL=
+register_var_option "--stl=<name>" CXX_STL "Select C++ runtime to rebuild."
+
+PACKAGE_DIR=
+register_var_option "--package-dir=<path>" PACKAGE_DIR "Put prebuilt tarballs into <path>."
+
+NDK_DIR=
+register_var_option "--ndk-dir=<path>" NDK_DIR "Specify NDK root path for the build."
+
+BUILD_DIR=
+register_var_option "--build-dir=<path>" BUILD_DIR "Specify temporary build dir."
+
+OUT_DIR=
+register_var_option "--out-dir=<path>" OUT_DIR "Specify output directory directly."
+
+ABIS="$PREBUILT_ABIS"
+register_var_option "--abis=<list>" ABIS "Specify list of target ABIs."
+
+NO_MAKEFILE=
+register_var_option "--no-makefile" NO_MAKEFILE "Do not use makefile to speed-up build"
+
+VISIBLE_STATIC=
+register_var_option "--visible-static" VISIBLE_STATIC "Do not use hidden visibility for the static library"
+
+WITH_DEBUG_INFO=
+register_var_option "--with-debug-info" WITH_DEBUG_INFO "Build with -g.  STL is still built with optimization but with debug info"
+
+GCC_VERSION=
+register_var_option "--gcc-version=<ver>" GCC_VERSION "Specify GCC version"
+
+LLVM_VERSION=
+register_var_option "--llvm-version=<ver>" LLVM_VERSION "Specify LLVM version"
+
+register_jobs_option
+
+register_try64_option
+
+extract_parameters "$@"
+
+if [ -n "${LLVM_VERSION}" -a -n "${GCC_VERSION}" ]; then
+    panic "Cannot set both LLVM_VERSION and GCC_VERSION. Make up your mind!"
+fi
+
+ABIS=$(commas_to_spaces $ABIS)
+
+# Handle NDK_DIR
+if [ -z "$NDK_DIR" ] ; then
+    NDK_DIR=$ANDROID_NDK_ROOT
+    log "Auto-config: --ndk-dir=$NDK_DIR"
+else
+  if [ ! -d "$NDK_DIR" ]; then
+    panic "NDK directory does not exist: $NDK_DIR"
+  fi
+fi
+
+# Handle OUT_DIR
+if [ -z "$OUT_DIR" ] ; then
+  OUT_DIR=$ANDROID_NDK_ROOT
+  log "Auto-config: --out-dir=$OUT_DIR"
+else
+  mkdir -p "$OUT_DIR"
+  fail_panic "Could not create directory: $OUT_DIR"
+fi
+
+# Check that --stl=<name> is used with one of the supported runtime names.
+if [ -z "$CXX_STL" ]; then
+  panic "Please use --stl=<name> to select a C++ runtime to rebuild."
+fi
+
+# Derive runtime, and normalize CXX_STL
+CXX_SUPPORT_LIB=gabi++
+case $CXX_STL in
+  stlport)
+    ;;
+  libc++)
+    CXX_SUPPORT_LIB=gabi++  # libc++abi
+    ;;
+  libc++-libc++abi)
+    CXX_SUPPORT_LIB=libc++abi
+    CXX_STL=libc++
+    ;;
+  libc++-gabi++)
+    CXX_SUPPORT_LIB=gabi++
+    CXX_STL=libc++
+    ;;
+  *)
+    panic "Invalid --stl value ('$CXX_STL'), please use one of: $CXX_STL_LIST."
+    ;;
+esac
+
+rm -rf "$BUILD_DIR"
+mkdir -p "$BUILD_DIR"
+fail_panic "Could not create build directory: $BUILD_DIR"
+
+# Location of the various C++ runtime source trees.  Use symlink from
+# $BUILD_DIR instead of $NDK which may contain full path of builder's working dir
+
+rm -f $BUILD_DIR/ndk
+ln -sf $ANDROID_NDK_ROOT $BUILD_DIR/ndk
+
+GABIXX_SRCDIR=$BUILD_DIR/ndk/$GABIXX_SUBDIR
+STLPORT_SRCDIR=$BUILD_DIR/ndk/$STLPORT_SUBDIR
+LIBCXX_SRCDIR=$BUILD_DIR/ndk/$LIBCXX_SUBDIR
+LIBCXXABI_SRCDIR=$BUILD_DIR/ndk/$LIBCXXABI_SUBDIR
+
+LIBCXX_INCLUDES="-I$LIBCXX_SRCDIR/libcxx/include -I$ANDROID_NDK_ROOT/sources/android/support/include -I$LIBCXXABI_SRCDIR/include"
+
+COMMON_C_CXX_FLAGS="-fPIC -O2 -ffunction-sections -fdata-sections"
+COMMON_CXXFLAGS="-fexceptions -frtti -fuse-cxa-atexit"
+
+if [ "$WITH_DEBUG_INFO" ]; then
+    COMMON_C_CXX_FLAGS="$COMMON_C_CXX_FLAGS -g"
+fi
+
+if [ "$CXX_STL" = "libc++" ]; then
+    # Use clang to build libc++ by default.
+    if [ -z "$LLVM_VERSION" -a -z "$GCC_VERSION" ]; then
+        LLVM_VERSION=$DEFAULT_LLVM_VERSION
+    fi
+fi
+
+# Determine GAbi++ build parameters. Note that GAbi++ is also built as part
+# of STLport and Libc++, in slightly different ways.
+if [ "$CXX_SUPPORT_LIB" = "gabi++" ]; then
+    if [ "$CXX_STL" = "libc++" ]; then
+        GABIXX_INCLUDES="$LIBCXX_INCLUDES"
+        GABIXX_CXXFLAGS="$GABIXX_CXXFLAGS -DLIBCXXABI=1"
+    else
+        GABIXX_INCLUDES="-I$GABIXX_SRCDIR/include"
+    fi
+    GABIXX_CFLAGS="$COMMON_C_CXX_FLAGS $GABIXX_INCLUDES"
+    GABIXX_CXXFLAGS="$GABIXX_CXXFLAGS $GABIXX_CFLAGS $COMMON_CXXFLAGS"
+    GABIXX_SOURCES=$(cd $ANDROID_NDK_ROOT/$GABIXX_SUBDIR && ls src/*.cc)
+    GABIXX_LDFLAGS="-ldl"
+fi
+
+# Determine STLport build parameters
+STLPORT_CFLAGS="$COMMON_C_CXX_FLAGS -DGNU_SOURCE -I$STLPORT_SRCDIR/stlport $GABIXX_INCLUDES"
+STLPORT_CXXFLAGS="$STLPORT_CFLAGS $COMMON_CXXFLAGS"
+STLPORT_SOURCES=\
+"src/dll_main.cpp \
+src/fstream.cpp \
+src/strstream.cpp \
+src/sstream.cpp \
+src/ios.cpp \
+src/stdio_streambuf.cpp \
+src/istream.cpp \
+src/ostream.cpp \
+src/iostream.cpp \
+src/codecvt.cpp \
+src/collate.cpp \
+src/ctype.cpp \
+src/monetary.cpp \
+src/num_get.cpp \
+src/num_put.cpp \
+src/num_get_float.cpp \
+src/num_put_float.cpp \
+src/numpunct.cpp \
+src/time_facets.cpp \
+src/messages.cpp \
+src/locale.cpp \
+src/locale_impl.cpp \
+src/locale_catalog.cpp \
+src/facets_byname.cpp \
+src/complex.cpp \
+src/complex_io.cpp \
+src/complex_trig.cpp \
+src/string.cpp \
+src/bitset.cpp \
+src/allocators.cpp \
+src/c_locale.c \
+src/cxa.c"
+
+# Determine Libc++ build parameters
+LIBCXX_LINKER_SCRIPT=export_symbols.txt
+LIBCXX_CFLAGS="$COMMON_C_CXX_FLAGS $LIBCXX_INCLUDES -Drestrict=__restrict__"
+LIBCXX_CXXFLAGS="$LIBCXX_CFLAGS -DLIBCXXABI=1 -std=c++11 -D__STDC_FORMAT_MACROS"
+if [ -f "$_BUILD_SRCDIR/$LIBCXX_LINKER_SCRIPT" ]; then
+    LIBCXX_LDFLAGS="-Wl,--version-script,\$_BUILD_SRCDIR/$LIBCXX_LINKER_SCRIPT"
+fi
+LIBCXX_SOURCES=\
+"libcxx/src/algorithm.cpp \
+libcxx/src/bind.cpp \
+libcxx/src/chrono.cpp \
+libcxx/src/condition_variable.cpp \
+libcxx/src/debug.cpp \
+libcxx/src/exception.cpp \
+libcxx/src/future.cpp \
+libcxx/src/hash.cpp \
+libcxx/src/ios.cpp \
+libcxx/src/iostream.cpp \
+libcxx/src/locale.cpp \
+libcxx/src/memory.cpp \
+libcxx/src/mutex.cpp \
+libcxx/src/new.cpp \
+libcxx/src/optional.cpp \
+libcxx/src/random.cpp \
+libcxx/src/regex.cpp \
+libcxx/src/shared_mutex.cpp \
+libcxx/src/stdexcept.cpp \
+libcxx/src/string.cpp \
+libcxx/src/strstream.cpp \
+libcxx/src/system_error.cpp \
+libcxx/src/thread.cpp \
+libcxx/src/typeinfo.cpp \
+libcxx/src/utility.cpp \
+libcxx/src/valarray.cpp \
+libcxx/src/support/android/locale_android.cpp \
+"
+
+LIBCXXABI_SOURCES=\
+"../llvm-libc++abi/libcxxabi/src/abort_message.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_aux_runtime.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_default_handlers.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_demangle.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_exception.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_exception_storage.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_guard.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_handlers.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_new_delete.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_personality.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_thread_atexit.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_unexpected.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_vector.cpp \
+../llvm-libc++abi/libcxxabi/src/cxa_virtual.cpp \
+../llvm-libc++abi/libcxxabi/src/exception.cpp \
+../llvm-libc++abi/libcxxabi/src/private_typeinfo.cpp \
+../llvm-libc++abi/libcxxabi/src/stdexcept.cpp \
+../llvm-libc++abi/libcxxabi/src/typeinfo.cpp
+"
+
+LIBCXXABI_UNWIND_SOURCES=\
+"../llvm-libc++abi/libcxxabi/src/Unwind/libunwind.cpp \
+../llvm-libc++abi/libcxxabi/src/Unwind/Unwind-EHABI.cpp \
+../llvm-libc++abi/libcxxabi/src/Unwind/Unwind-sjlj.c \
+../llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1.c \
+../llvm-libc++abi/libcxxabi/src/Unwind/UnwindLevel1-gcc-ext.c \
+../llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersRestore.S \
+../llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersSave.S \
+"
+
+# If the --no-makefile flag is not used, we're going to put all build
+# commands in a temporary Makefile that we will be able to invoke with
+# -j$NUM_JOBS to build stuff in parallel.
+#
+if [ -z "$NO_MAKEFILE" ]; then
+    MAKEFILE=$BUILD_DIR/Makefile
+else
+    MAKEFILE=
+fi
+
+# Define a few common variables based on parameters.
+case $CXX_STL in
+  stlport)
+    CXX_STL_LIB=libstlport
+    CXX_STL_SUBDIR=$STLPORT_SUBDIR
+    CXX_STL_SRCDIR=$STLPORT_SRCDIR
+    CXX_STL_CFLAGS=$STLPORT_CFLAGS
+    CXX_STL_CXXFLAGS=$STLPORT_CXXFLAGS
+    CXX_STL_LDFLAGS=$STLPORT_LDFLAGS
+    CXX_STL_SOURCES=$STLPORT_SOURCES
+    CXX_STL_PACKAGE=stlport
+    ;;
+  libc++)
+    CXX_STL_LIB=libc++
+    CXX_STL_SUBDIR=$LIBCXX_SUBDIR
+    CXX_STL_SRCDIR=$LIBCXX_SRCDIR
+    CXX_STL_CFLAGS=$LIBCXX_CFLAGS
+    CXX_STL_CXXFLAGS=$LIBCXX_CXXFLAGS
+    CXX_STL_LDFLAGS=$LIBCXX_LDFLAGS
+    CXX_STL_SOURCES=$LIBCXX_SOURCES
+    CXX_STL_PACKAGE=libcxx
+    ;;
+  *)
+    panic "Internal error: Unknown STL name '$CXX_STL'"
+    ;;
+esac
+
+HIDDEN_VISIBILITY_FLAGS="-fvisibility=hidden -fvisibility-inlines-hidden"
+
+# By default, all static libraries include hidden ELF symbols, except
+# if one uses the --visible-static option.
+if [ -z "$VISIBLE_STATIC" ]; then
+    STATIC_CONLYFLAGS="$HIDDEN_VISIBILITY_FLAGS"
+    STATIC_CXXFLAGS="$HIDDEN_VISIBILITY_FLAGS"
+else
+    STATIC_CONLYFLAGS=
+    STATIC_CXXFLAGS=
+fi
+SHARED_CONLYFLAGS="$HIDDEN_VISIBILITY_FLAGS"
+SHARED_CXXFLAGS=
+
+
+# build_stl_libs_for_abi
+# $1: ABI
+# $2: build directory
+# $3: build type: "static" or "shared"
+# $4: installation directory
+# $5: (optional) thumb
+build_stl_libs_for_abi ()
+{
+    local ARCH BINPREFIX SYSROOT
+    local ABI=$1
+    local BUILDDIR="$2"
+    local TYPE="$3"
+    local DSTDIR="$4"
+    local DEFAULT_CFLAGS DEFAULT_CXXFLAGS
+    local SRC OBJ OBJECTS EXTRA_CFLAGS EXTRA_CXXFLAGS EXTRA_LDFLAGS LIB_SUFFIX GCCVER
+
+    EXTRA_CFLAGS=""
+    EXTRA_CXXFLAGS=""
+    EXTRA_LDFLAGS="-Wl,--build-id"
+
+    case $ABI in
+        arm64-v8a)
+            EXTRA_CFLAGS="-mfix-cortex-a53-835769"
+            EXTRA_CXXFLAGS="-mfix-cortex-a53-835769"
+            ;;
+        x86|x86_64)
+            # ToDo: remove the following once all x86-based device call JNI function with
+            #       stack aligned to 16-byte
+            EXTRA_CFLAGS="-mstackrealign"
+            EXTRA_CXXFLAGS="-mstackrealign"
+            ;;
+        mips)
+            EXTRA_CFLAGS="-mips32"
+            EXTRA_CXXFLAGS="-mips32"
+            EXTRA_LDFLAGS="-mips32"
+            ;;
+        mips32r6)
+            EXTRA_CFLAGS="-mips32r6"
+            EXTRA_CXXFLAGS="-mips32r6"
+            EXTRA_LDFLAGS="-mips32r6"
+            ;;
+        mips64)
+            EXTRA_CFLAGS="-mips64r6"
+            EXTRA_CXXFLAGS=$EXTRA_CFLAGS
+            ;;
+    esac
+
+    USE_LLVM_UNWIND=
+    case $ABI in
+        armeabi*)
+            EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -DLIBCXXABI_USE_LLVM_UNWINDER=1"
+            USE_LLVM_UNWIND=true
+            ;;
+        *)
+            EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -DLIBCXXABI_USE_LLVM_UNWINDER=0"
+            ;;
+    esac
+
+    if [ "$ABI" != "${ABI%%arm*}" -a "$ABI" = "${ABI%%64*}" ] ; then
+        EXTRA_CFLAGS="$EXTRA_CFLAGS -mthumb"
+        EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS -mthumb"
+    fi
+
+    if [ "$TYPE" = "static" ]; then
+        EXTRA_CFLAGS="$EXTRA_CFLAGS $STATIC_CONLYFLAGS"
+        EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $STATIC_CXXFLAGS"
+    else
+        EXTRA_CFLAGS="$EXTRA_CFLAGS $SHARED_CONLYFLAGS"
+        EXTRA_CXXFLAGS="$EXTRA_CXXFLAGS $SHARED_CXXFLAGS"
+    fi
+
+    DSTDIR=$DSTDIR/$CXX_STL_SUBDIR/libs/$ABI
+    LIB_SUFFIX="$(get_lib_suffix_for_abi $ABI)"
+
+    mkdir -p "$BUILDDIR"
+    mkdir -p "$DSTDIR"
+
+    if [ -n "$GCC_VERSION" ]; then
+        GCCVER=$GCC_VERSION
+        EXTRA_CFLAGS="$EXTRA_CFLAGS -std=c99"
+    else
+        ARCH=$(convert_abi_to_arch $ABI)
+        GCCVER=$(get_default_gcc_version_for_arch $ARCH)
+    fi
+
+    # libc++ built with clang (for ABI armeabi-only) produces
+    # libc++_shared.so and libc++_static.a with undefined __atomic_fetch_add_4
+    # Add -latomic.
+    if [ -n "$LLVM_VERSION" -a "$CXX_STL_LIB" = "libc++" ]; then
+        # clang3.5+ use integrated-as as default, which has trouble compiling
+        # llvm-libc++abi/libcxxabi/src/Unwind/UnwindRegistersRestore.S
+        EXTRA_CFLAGS="${EXTRA_CFLAGS} -no-integrated-as"
+        EXTRA_CXXFLAGS="${EXTRA_CXXFLAGS} -no-integrated-as"
+        if [ "$ABI" = "armeabi" ]; then
+            EXTRA_LDFLAGS="$EXTRA_LDFLAGS -latomic"
+        fi
+    fi
+
+    builder_begin_android $ABI "$BUILDDIR" "$GCCVER" "$LLVM_VERSION" "$MAKEFILE"
+
+    builder_set_dstdir "$DSTDIR"
+    builder_reset_cflags DEFAULT_CFLAGS
+    builder_reset_cxxflags DEFAULT_CXXFLAGS
+
+    if [ "$CXX_SUPPORT_LIB" = "gabi++" ]; then
+        builder_set_srcdir "$GABIXX_SRCDIR"
+        builder_cflags "$DEFAULT_CFLAGS $GABIXX_CFLAGS $EXTRA_CFLAGS"
+        builder_cxxflags "$DEFAULT_CXXFLAGS $GABIXX_CXXFLAGS $EXTRA_CXXFLAGS"
+        builder_ldflags "$GABIXX_LDFLAGS $EXTRA_LDFLAGS"
+        builder_sources $GABIXX_SOURCES
+    fi
+
+    # Build the runtime sources, except if we're only building GAbi++
+    if [ "$CXX_STL" != "gabi++" ]; then
+      builder_set_srcdir "$CXX_STL_SRCDIR"
+      builder_reset_cflags
+      builder_cflags "$DEFAULT_CFLAGS $CXX_STL_CFLAGS $EXTRA_CFLAGS"
+      builder_reset_cxxflags
+      builder_cxxflags "$DEFAULT_CXXFLAGS $CXX_STL_CXXFLAGS $EXTRA_CXXFLAGS"
+      builder_ldflags "$CXX_STL_LDFLAGS $EXTRA_LDFLAGS"
+      builder_sources $CXX_STL_SOURCES
+      if [ "$CXX_SUPPORT_LIB" = "libc++abi" ]; then
+          if [ "$USE_LLVM_UNWIND" = "true" ]; then
+              builder_sources $LIBCXXABI_SOURCES $LIBCXXABI_UNWIND_SOURCES
+          else
+              builder_sources $LIBCXXABI_SOURCES
+          fi
+          builder_ldflags "-ldl"
+      fi
+      if [ "$CXX_STL" = "libc++" ]; then
+        if [ "$ABI" = "${ABI%%64*}" ]; then
+          if [ "$ABI" = "x86" ]; then
+            builder_sources $SUPPORT32_SOURCES $SUPPORT32_SOURCES_x86
+          else
+            builder_sources $SUPPORT32_SOURCES
+	  fi
+        else
+          builder_sources $SUPPORT64_SOURCES
+        fi
+      fi
+    fi
+
+    if [ "$TYPE" = "static" ]; then
+        log "Building $DSTDIR/${CXX_STL_LIB}_static.a"
+        builder_static_library ${CXX_STL_LIB}_static
+    else
+        log "Building $DSTDIR/${CXX_STL_LIB}_shared${LIB_SUFFIX}"
+        builder_shared_library ${CXX_STL_LIB}_shared $LIB_SUFFIX
+    fi
+
+    builder_end
+}
+
+for ABI in $ABIS; do
+    build_stl_libs_for_abi $ABI "$BUILD_DIR/$ABI/static" "static" "$OUT_DIR"
+    build_stl_libs_for_abi $ABI "$BUILD_DIR/$ABI/shared" "shared" "$OUT_DIR"
+done
+
+if [ -n "$PACKAGE_DIR" ] ; then
+    if [ "$CXX_STL" = "libc++" ]; then
+        STL_DIR="llvm-libc++"
+    elif [ "$CXX_STL" = "stlport" ]; then
+        STL_DIR="stlport"
+    else
+        panic "Unknown STL: $CXX_STL"
+    fi
+
+    make_repo_prop "$OUT_DIR/$CXX_STL_SUBDIR"
+    PACKAGE="$PACKAGE_DIR/${CXX_STL_PACKAGE}.zip"
+    log "Packaging: $PACKAGE"
+    pack_archive "$PACKAGE" "$OUT_DIR/sources/cxx-stl" "$STL_DIR"
+    fail_panic "Could not package $CXX_STL binaries!"
+fi
+
+if [ -z "$OPTION_BUILD_DIR" ]; then
+    log "Cleaning up..."
+    rm -rf $BUILD_DIR
+else
+    log "Don't forget to cleanup: $BUILD_DIR"
+fi
+
+log "Done!"
diff --git a/build/tools/build-gdb-stub.sh b/build/tools/build-gdb-stub.sh
new file mode 100755
index 0000000..2dfd643
--- /dev/null
+++ b/build/tools/build-gdb-stub.sh
@@ -0,0 +1,81 @@
+#!/bin/bash
+
+NDK_BUILDTOOLS_PATH="$(dirname $0)"
+. "$NDK_BUILDTOOLS_PATH/prebuilt-common.sh"
+. "$NDK_BUILDTOOLS_PATH/common-build-host-funcs.sh"
+
+PROGRAM_PARAMETERS=""
+PROGRAM_DESCRIPTION="\
+This program is used to build the gdb stub for Windows and replace a
+gdb executable with it. Because of the replacing nature of this, I
+check to see if there's a gdb-orig.exe there already and if so, 'undo'
+the process first by putting it back. Sample usage:
+
+$0 --gdb-executable-path=\$NDK/toolchains/arm-linux-androideabi-4.8/prebuilt/bin/arm-linux-androideabi-gdb.exe \\
+   --python-prefix-dir=\$NDK/prebuilt/windows \\
+   --mingw-w64-gcc-path=\$HOME/i686-w64-mingw32/bin/i686-w64-mingw32-gcc
+"
+
+NDK_DIR=$ANDROID_NDK_ROOT
+
+PYTHON_PREFIX_DIR=
+register_var_option "--python-prefix-dir=<path>" PYTHON_PREFIX_DIR "Python prefix directory."
+
+GDB_EXECUTABLE_PATH=
+register_var_option "--gdb-executable-path=<path>" GDB_EXECUTABLE_PATH "GDB executable file to stubify."
+
+MINGW_W64_GCC=
+register_var_option "--mingw-w64-gcc=<program>" MINGW_W64_GCC "MinGW-w64 gcc program to use."
+
+DEBUG_STUB=
+register_var_option "--debug" DEBUG_STUB "Build stub in debug mode."
+
+extract_parameters "$@"
+
+if [ -n "$DEBUG_STUB" ]; then
+    STUB_CFLAGS="-O0 -g -D_DEBUG"
+else
+    STUB_CFLAGS="-O2 -s -DNDEBUG"
+fi
+
+if [ ! -f "$GDB_EXECUTABLE_PATH" ]; then
+    panic "GDB executable $GDB_EXECUTABLE_PATH doesn't exist!"
+fi
+
+if [ ! -d "$PYTHON_PREFIX_DIR" ]; then
+    panic "Python prefix dir $PYTHON_PREFIX_DIR doesn't exist!"
+fi
+
+if [ -z "$MINGW_W64_GCC" ]; then
+    panic "Please specify an existing MinGW-w64 cross compiler with --mingw-w64-gcc=<program>"
+fi
+
+GDB_BIN_DIR=$(cd $(dirname "$GDB_EXECUTABLE_PATH"); pwd)
+PYTHON_PREFIX_DIR=$(cd "$PYTHON_PREFIX_DIR"; pwd)
+PYTHON_BIN_DIR=${PYTHON_PREFIX_DIR}/bin
+
+# Sed is used to get doubled up Windows style dir separators.
+GDB_TO_PYTHON_REL_DIR=$(relpath "$GDB_BIN_DIR" "$PYTHON_BIN_DIR" | sed -e s./.\\\\\\\\.g)
+PYTHONHOME_REL_DIR=$(relpath "$GDB_BIN_DIR" "$PYTHON_PREFIX_DIR" | sed -e s./.\\\\\\\\.g)
+dump "GDB_TO_PYTHON_REL_DIR=$GDB_TO_PYTHON_REL_DIR"
+dump "PYTHONHOME_REL_DIR=$PYTHONHOME_REL_DIR"
+
+GDB_EXECUTABLE_ORIG=$(dirname "$GDB_EXECUTABLE_PATH")/$(basename "$GDB_EXECUTABLE_PATH" ".exe")-orig.exe
+if [ -f "$GDB_EXECUTABLE_ORIG" ] ; then
+    echo "Warning : Found an existing gdb-stub called $GDB_EXECUTABLE_ORIG so will un-do a previous run of this script."
+    cp "$GDB_EXECUTABLE_ORIG" "$GDB_EXECUTABLE_PATH"
+fi
+cp "$GDB_EXECUTABLE_PATH" "$GDB_EXECUTABLE_ORIG"
+
+GDB_EXECUTABLE_ORIG_FILENAME=$(basename "$GDB_EXECUTABLE_ORIG")
+
+# Build the stub in-place of the real gdb.
+run $MINGW_W64_GCC $STUB_CFLAGS "$NDK_DIR/sources/host-tools/gdb-stub/gdb-stub.c" \
+                    -o "$GDB_EXECUTABLE_PATH" \
+                    -DGDB_TO_PYTHON_REL_DIR=\"$GDB_TO_PYTHON_REL_DIR\" \
+                    -DPYTHONHOME_REL_DIR=\"$PYTHONHOME_REL_DIR\" \
+                    -DGDB_EXECUTABLE_ORIG_FILENAME=\"$GDB_EXECUTABLE_ORIG_FILENAME\"
+
+fail_panic "Can't build gdb stub!"
+
+dump "GDB Stub done!"
diff --git a/build/tools/build-gdbserver.py b/build/tools/build-gdbserver.py
new file mode 100755
index 0000000..b579110
--- /dev/null
+++ b/build/tools/build-gdbserver.py
@@ -0,0 +1,66 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2015 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.
+#
+"""Builds gdbserver for Android."""
+from __future__ import print_function
+
+import os
+import site
+
+site.addsitedir(os.path.join(os.path.dirname(__file__), '../lib'))
+
+import build_support  # pylint: disable=import-error
+
+GDBSERVER_TARGETS = (
+    'arm-eabi-linux',
+    'aarch64-eabi-linux',
+    'i686-linux-android',
+    'x86_64-linux-android',
+)
+
+
+class ArgParser(build_support.ArgParser):
+    def __init__(self):  # pylint: disable=super-on-old-class
+        super(ArgParser, self).__init__()
+
+        # pylint: disable=no-member
+        self.add_argument(
+            '--arch', choices=build_support.ALL_ARCHITECTURES,
+            help='Architectures to build. Builds all if not present.')
+        # pylint: enable=no-member
+
+
+def main(args):
+    arches = build_support.ALL_ARCHITECTURES
+    if args.arch is not None:
+        arches = [args.arch]
+
+    print('Building gdbservers: {}'.format(' '.join(arches)))
+    for arch in arches:
+        build_dir = os.path.join(args.out_dir, 'gdbserver', arch)
+        target_triple = dict(zip(
+            build_support.ALL_ARCHITECTURES, GDBSERVER_TARGETS))[arch]
+        build_cmd = [
+            'bash', 'build-gdbserver.sh', arch, target_triple,
+            build_support.toolchain_path(), build_support.ndk_path(),
+            '--build-out={}'.format(build_dir), build_support.jobs_arg(),
+        ]
+
+        build_support.build(build_cmd, args)
+
+
+if __name__ == '__main__':
+    build_support.run(main, ArgParser)
diff --git a/build/tools/build-gdbserver.sh b/build/tools/build-gdbserver.sh
new file mode 100755
index 0000000..6d81a69
--- /dev/null
+++ b/build/tools/build-gdbserver.sh
@@ -0,0 +1,282 @@
+#!/bin/bash
+#
+# Copyright (C) 2010 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.
+#
+#  This shell script is used to rebuild the gdbserver binary from
+#  the Android NDK's prebuilt binaries.
+#
+
+# include common function and variable definitions
+. `dirname $0`/prebuilt-common.sh
+
+PROGRAM_PARAMETERS="<arch> <target-triple> <src-dir> <ndk-dir>"
+
+PROGRAM_DESCRIPTION=\
+"Rebuild the gdbserver prebuilt binary for the Android NDK toolchain.
+
+Where <src-dir> is the location of the gdbserver sources,
+<ndk-dir> is the top-level NDK installation path and <toolchain>
+is the name of the toolchain to use (e.g. arm-linux-androideabi-4.8).
+
+The final binary is placed under:
+
+    <build-out>/gdbserver
+
+NOTE: The --platform option is ignored if --sysroot is used."
+
+VERBOSE=no
+
+BUILD_OUT=
+register_var_option "--build-out=<path>" BUILD_OUT "Set temporary build directory"
+
+SYSROOT=
+register_var_option "--sysroot=<path>" SYSROOT "Specify sysroot directory directly"
+
+NOTHREADS=no
+register_var_option "--disable-threads" NOTHREADS "Disable threads support"
+
+GDB_VERSION=
+register_var_option "--gdb-version=<name>" GDB_VERSION "Use specific gdb version."
+
+PACKAGE_DIR=
+register_var_option "--package-dir=<path>" PACKAGE_DIR "Archive binary into specific directory"
+
+register_jobs_option
+
+register_try64_option
+
+extract_parameters "$@"
+
+if [ -z "$BUILD_OUT" ]; then
+  echo "ERROR: --build-out is required"
+  exit 1
+fi
+
+INSTALL_DIR=$BUILD_OUT/install
+BUILD_OUT=$BUILD_OUT/build
+
+set_parameters ()
+{
+    ARCH="$1"
+    GDBSERVER_HOST="$2"
+    SRC_DIR="$3"
+    NDK_DIR="$4"
+    GDBVER=
+
+    # Check architecture
+    #
+    if [ -z "$ARCH" ] ; then
+        echo "ERROR: Missing target architecture. See --help for details."
+        exit 1
+    fi
+
+    log "Targetting CPU: $ARCH"
+
+    # Check host value
+    #
+    if [ -z "$GDBSERVER_HOST" ] ; then
+        echo "ERROR: Missing target triple. See --help for details."
+        exit 1
+    fi
+
+    log "GDB target triple: $GDBSERVER_HOST"
+
+    # Check source directory
+    #
+    if [ -z "$SRC_DIR" ] ; then
+        echo "ERROR: Missing source directory parameter. See --help for details."
+        exit 1
+    fi
+
+    if [ -n "$GDB_VERSION" ]; then
+        GDBVER=$GDB_VERSION
+    else
+        GDBVER=$(get_default_gdbserver_version)
+    fi
+
+    SRC_DIR2="$SRC_DIR/gdb/gdb-$GDBVER/gdb/gdbserver"
+    if [ -d "$SRC_DIR2" ] ; then
+        SRC_DIR="$SRC_DIR2"
+        log "Found gdbserver source directory: $SRC_DIR"
+    fi
+
+    if [ ! -f "$SRC_DIR/gdbreplay.c" ] ; then
+        echo "ERROR: Source directory does not contain gdbserver sources: $SRC_DIR"
+        exit 1
+    fi
+
+    log "Using source directory: $SRC_DIR"
+
+    # Check NDK installation directory
+    #
+    if [ -z "$NDK_DIR" ] ; then
+        echo "ERROR: Missing NDK directory parameter. See --help for details."
+        exit 1
+    fi
+
+    if [ ! -d "$NDK_DIR" ] ; then
+        echo "ERROR: NDK directory does not exist: $NDK_DIR"
+        exit 1
+    fi
+
+    log "Using NDK directory: $NDK_DIR"
+}
+
+set_parameters $PARAMETERS
+
+if [ "$PACKAGE_DIR" ]; then
+    mkdir -p "$PACKAGE_DIR"
+    fail_panic "Could not create package directory: $PACKAGE_DIR"
+fi
+
+prepare_target_build
+
+GCC_VERSION=$(get_default_gcc_version_for_arch $ARCH)
+log "Using GCC version: $GCC_VERSION"
+TOOLCHAIN_PREFIX=$ANDROID_BUILD_TOP/prebuilts/ndk/current/
+TOOLCHAIN_PREFIX+=$(get_toolchain_binprefix_for_arch $ARCH $GCC_VERSION)
+
+# Determine cflags when building gdbserver
+GDBSERVER_CFLAGS=
+case "$ARCH" in
+arm*)
+    GDBSERVER_CFLAGS+="-fno-short-enums"
+    ;;
+esac
+
+case "$ARCH" in
+*64)
+    GDBSERVER_CFLAGS+=" -DUAPI_HEADERS"
+    ;;
+esac
+
+
+PLATFORM="android-$LATEST_API_LEVEL"
+
+# Check build directory
+#
+fix_sysroot "$SYSROOT"
+log "Using sysroot: $SYSROOT"
+
+log "Using build directory: $BUILD_OUT"
+run rm -rf "$BUILD_OUT"
+run mkdir -p "$BUILD_OUT"
+
+# Copy the sysroot to a temporary build directory
+BUILD_SYSROOT="$BUILD_OUT/sysroot"
+run mkdir -p "$BUILD_SYSROOT"
+run cp -RHL "$SYSROOT"/* "$BUILD_SYSROOT"
+
+# Make sure multilib toolchains have lib64
+if [ ! -d "$BUILD_SYSROOT/usr/lib64" ] ; then
+    mkdir "$BUILD_SYSROOT/usr/lib64"
+fi
+
+# Make sure multilib toolchains know their target
+TARGET_FLAG=
+if [ "$ARCH" = "mips" ] ; then
+    TARGET_FLAG=-mips32
+fi
+
+LIBDIR=$(get_default_libdir_for_arch $ARCH)
+
+# Remove libthread_db to ensure we use exactly the one we want.
+rm -f $BUILD_SYSROOT/usr/$LIBDIR/libthread_db*
+rm -f $BUILD_SYSROOT/usr/include/thread_db.h
+
+if [ "$NOTHREADS" != "yes" ] ; then
+    # We're going to rebuild libthread_db.o from its source
+    # that is under sources/android/libthread_db and place its header
+    # and object file into the build sysroot.
+    LIBTHREAD_DB_DIR=$ANDROID_NDK_ROOT/sources/android/libthread_db
+    if [ ! -d "$LIBTHREAD_DB_DIR" ] ; then
+        dump "ERROR: Missing directory: $LIBTHREAD_DB_DIR"
+        exit 1
+    fi
+
+    run cp $LIBTHREAD_DB_DIR/thread_db.h $BUILD_SYSROOT/usr/include/
+    run ${TOOLCHAIN_PREFIX}gcc --sysroot=$BUILD_SYSROOT $TARGET_FLAG -o $BUILD_SYSROOT/usr/$LIBDIR/libthread_db.o -c $LIBTHREAD_DB_DIR/libthread_db.c
+    run ${TOOLCHAIN_PREFIX}ar -rD $BUILD_SYSROOT/usr/$LIBDIR/libthread_db.a $BUILD_SYSROOT/usr/$LIBDIR/libthread_db.o
+    if [ $? != 0 ] ; then
+        dump "ERROR: Could not compile libthread_db.c!"
+        exit 1
+    fi
+fi
+
+log "Using build sysroot: $BUILD_SYSROOT"
+
+# configure the gdbserver build now
+dump "Configure: $ARCH gdbserver-$GDBVER build with $PLATFORM"
+
+# This flag is required to link libthread_db statically to our
+# gdbserver binary. Otherwise, the program will try to dlopen()
+# the threads binary, which is not possible since we build a
+# static executable.
+CONFIGURE_FLAGS="--with-libthread-db=$BUILD_SYSROOT/usr/$LIBDIR/libthread_db.a"
+# Disable libinproctrace.so which needs crtbegin_so.o and crtbend_so.o instead of
+# CRTBEGIN/END above.  Clean it up and re-enable it in the future.
+CONFIGURE_FLAGS=$CONFIGURE_FLAGS" --disable-inprocess-agent"
+# gdb 7.7 builds with -Werror by default, but they redefine constants such as
+# HWCAP_VFPv3 in a way that's compatible with glibc's headers but not our
+# kernel uapi headers. We should send a patch upstream to add the missing
+# #ifndefs, but for now just build gdbserver without -Werror.
+CONFIGURE_FLAGS=$CONFIGURE_FLAGS" --enable-werror=no"
+
+cd $BUILD_OUT &&
+export CC="${TOOLCHAIN_PREFIX}gcc --sysroot=$BUILD_SYSROOT $TARGET_FLAG" &&
+export AR="${TOOLCHAIN_PREFIX}ar" &&
+export RANLIB="${TOOLCHAIN_PREFIX}ranlib" &&
+export CFLAGS="-O2 $GDBSERVER_CFLAGS"  &&
+export LDFLAGS="-static -Wl,-z,nocopyreloc -Wl,--no-undefined" &&
+run $SRC_DIR/configure \
+--build=x86_64-linux-gnu \
+--host=$GDBSERVER_HOST \
+$CONFIGURE_FLAGS
+if [ $? != 0 ] ; then
+    dump "Could not configure gdbserver build."
+    exit 1
+fi
+
+# build gdbserver
+dump "Building : $ARCH gdbserver."
+cd $BUILD_OUT &&
+run make -j$NUM_JOBS
+if [ $? != 0 ] ; then
+    dump "Could not build $ARCH gdbserver. Use --verbose to see why."
+    exit 1
+fi
+
+# install gdbserver
+#
+# note that we install it in the toolchain bin directory
+# not in $SYSROOT/usr/bin
+#
+if [ "$NOTHREADS" = "yes" ] ; then
+    DSTFILE="gdbserver-nothreads"
+else
+    DSTFILE="gdbserver"
+fi
+
+dump "Install  : $ARCH $DSTFILE."
+mkdir -p $INSTALL_DIR &&
+run ${TOOLCHAIN_PREFIX}objcopy --strip-unneeded \
+  $BUILD_OUT/gdbserver $INSTALL_DIR/$DSTFILE
+fail_panic "Could not install $DSTFILE."
+
+make_repo_prop "$INSTALL_DIR"
+cp "$SRC_DIR/../../COPYING" "$INSTALL_DIR/NOTICE"
+fail_panic "Could not copy license file!"
+
+dump "Done."
diff --git a/build/tools/build-renderscript.py b/build/tools/build-renderscript.py
new file mode 100755
index 0000000..981fed7
--- /dev/null
+++ b/build/tools/build-renderscript.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 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.
+#
+"""Packages the platform's RenderScript for the NDK."""
+import os
+import shutil
+import site
+import subprocess
+import sys
+
+site.addsitedir(os.path.join(os.path.dirname(__file__), '../lib'))
+
+import build_support  # pylint: disable=import-error
+
+
+def get_rs_prebuilt_path(host):
+    rel_prebuilt_path = 'prebuilts/renderscript/host/{}'.format(host)
+    prebuilt_path = os.path.join(build_support.android_path(),
+                                 rel_prebuilt_path)
+    if not os.path.isdir(prebuilt_path):
+        sys.exit('Could not find prebuilt RenderScript at {}'.format(prebuilt_path))
+    return prebuilt_path
+
+
+def main(args):
+    RS_VERSION = 'current'
+
+    host = args.host
+    out_dir = args.out_dir;
+    package_dir = args.dist_dir
+
+    os_name = host
+    if os_name == 'windows64':
+        os_name = 'windows'
+    prebuilt_path = get_rs_prebuilt_path(os_name + '-x86')
+    print('prebuilt path: ' + prebuilt_path)
+    if host == 'darwin':
+        host = 'darwin-x86_64'
+    elif host == 'linux':
+        host = 'linux-x86_64'
+    elif host == 'windows':
+        host = 'windows'
+    elif host == 'windows64':
+        host = 'windows-x86_64'
+
+    package_name = 'renderscript-toolchain-{}'.format(host)
+    built_path = os.path.join(prebuilt_path, RS_VERSION)
+    build_support.make_package(package_name, built_path, package_dir)
+
+if __name__ == '__main__':
+    build_support.run(main)
diff --git a/build/tools/build-shader-tools.py b/build/tools/build-shader-tools.py
new file mode 100755
index 0000000..76ed46f
--- /dev/null
+++ b/build/tools/build-shader-tools.py
@@ -0,0 +1,156 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 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.
+
+"""Builds the glslc, spirv-as, spirv-dis, and spirv-val host executables."""
+
+from __future__ import print_function
+
+import os
+import site
+import shutil
+import subprocess
+
+site.addsitedir(os.path.join(os.path.dirname(__file__), '../lib'))
+
+import build_support
+from build_support import ArgParser
+
+
+def main(args):
+    host_tag = build_support.host_to_tag(args.host)
+    build_host_tag = build_support.get_default_host() + "-x86"
+
+    package_dir = args.dist_dir
+
+    # TODO(danalbert): use ndk/sources/third_party/googletest/googletest
+    # after it has been updated to a version with CMakeLists
+    gtest_cmd = ('-DSHADERC_GOOGLE_TEST_DIR=' +
+                 os.path.join(build_support.android_path(),
+                              'external', 'googletest'))
+
+    obj_out = os.path.join(args.out_dir, 'shader_tools/obj')
+    install_dir = os.path.join(args.out_dir, 'shader_tools/install')
+
+    package_src = '-'.join([os.path.join(args.out_dir,
+                                         'shader_tools/shader-tools'),
+                            host_tag])
+    package_name = '-'.join(['shader-tools', host_tag])
+
+    source_root = os.path.join(build_support.android_path(), 'external',
+                               'shaderc')
+    shaderc_shaderc_dir = os.path.join(source_root, 'shaderc')
+    spirv_headers_dir = os.path.join(source_root, 'spirv-headers')
+
+    cmake = os.path.join(build_support.android_path(),
+                         'prebuilts', 'cmake', build_host_tag, 'bin', 'cmake')
+    ctest = os.path.join(build_support.android_path(),
+                         'prebuilts', 'cmake', build_host_tag, 'bin', 'ctest')
+    ninja = os.path.join(build_support.android_path(),
+                         'prebuilts', 'ninja', build_host_tag, 'ninja')
+    file_extension = ''
+
+    additional_args = []
+    if args.host.startswith("windows"):
+        gtest_cmd = ''
+        mingw_root = os.path.join(build_support.android_path(),
+                                  'prebuilts', 'gcc', build_host_tag, 'host',
+                                  'x86_64-w64-mingw32-4.8')
+        mingw_compilers = os.path.join(mingw_root, 'bin', 'x86_64-w64-mingw32')
+        mingw_toolchain = os.path.join(source_root, 'shaderc',
+                                       'cmake', 'linux-mingw-toolchain.cmake')
+        gtest_root = os.path.join(build_support.android_path(), 'external',
+                                  'googletest')
+        additional_args = ['-DCMAKE_TOOLCHAIN_FILE=' + mingw_toolchain,
+                           '-DMINGW_SYSROOT=' + mingw_root,
+                           '-DMINGW_COMPILER_PREFIX=' + mingw_compilers,
+                           '-DSHADERC_GOOGLE_TEST_DIR=' + gtest_root]
+        file_extension = '.exe'
+        if args.host == "windows64":
+            additional_args.extend(
+                ['-DCMAKE_CXX_FLAGS=-fno-rtti -fno-exceptions'])
+        else:
+            additional_args.extend(
+                ['-DCMAKE_CXX_FLAGS=-m32 -fno-rtti -fno-exceptions',
+                 '-DCMAKE_C_FLAGS=-m32'])
+
+    for d in [package_src, obj_out, install_dir]:
+        try:
+            os.makedirs(d)
+        except:
+            pass
+
+    # Create the NOTICE file.
+    license_files = [
+        os.path.join(shaderc_shaderc_dir, 'LICENSE'),
+        os.path.join(shaderc_shaderc_dir,
+                     'third_party',
+                     'LICENSE.spirv-tools'),
+        os.path.join(shaderc_shaderc_dir,
+                     'third_party',
+                     'LICENSE.glslang'),
+    ]
+    # The SPIRV-Headers might not have landed just yet.  Use its
+    # license file if it exists.
+    spirv_headers_license = os.path.join(spirv_headers_dir, 'LICENSE')
+    if os.path.exists(spirv_headers_license):
+        license_files.append(spirv_headers_license)
+
+    build_support.merge_license_files(os.path.join(package_src, 'NOTICE'),
+                                      license_files)
+
+    cmake_command = [cmake, '-GNinja', '-DCMAKE_MAKE_PROGRAM=' + ninja,
+                     '-DCMAKE_BUILD_TYPE=Release',
+                     '-DCMAKE_INSTALL_PREFIX=' + install_dir,
+                     '-DSHADERC_THIRD_PARTY_ROOT_DIR=' + source_root,
+                     '-DSPIRV-Headers_SOURCE_DIR=' + spirv_headers_dir,
+                     gtest_cmd,
+                     shaderc_shaderc_dir]
+
+    cmake_command.extend(additional_args)
+
+    subprocess.check_call(cmake_command, cwd=obj_out)
+    subprocess.check_call([cmake, '--build', obj_out, '--', '-v'])
+    subprocess.check_call([cmake, '--build', obj_out,
+                           '--target', 'install/strip'])
+
+    files_to_copy = ['glslc' + file_extension,
+                     'spirv-as' + file_extension,
+                     'spirv-dis' + file_extension,
+                     'spirv-val' + file_extension,
+                     'spirv-cfg' + file_extension,
+                     'spirv-opt' + file_extension]
+    scripts_to_copy = ['spirv-lesspipe.sh',]
+    files_to_copy.extend(scripts_to_copy)
+
+    # Test, except on windows.
+    if (not args.host.startswith('windows')):
+        subprocess.check_call([ctest, '--verbose'], cwd=obj_out)
+
+    # Copy to install tree.
+    for src in files_to_copy:
+        shutil.copy2(os.path.join(install_dir, 'bin', src),
+                     os.path.join(package_src, src))
+    if args.host.startswith('windows'):
+        for src in scripts_to_copy:
+            # Convert line endings on scripts.
+            # Do it in place to preserve executable permissions.
+            subprocess.check_call(['unix2dos', '-o',
+                                   os.path.join(package_src, src)])
+
+    build_support.make_package(package_name, package_src, package_dir)
+
+if __name__ == '__main__':
+    build_support.run(main, ArgParser)
diff --git a/build/tools/builder-funcs.sh b/build/tools/builder-funcs.sh
new file mode 100644
index 0000000..0797824
--- /dev/null
+++ b/build/tools/builder-funcs.sh
@@ -0,0 +1,655 @@
+#
+# Copyright (C) 2011 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.
+#
+#  This file contains various shell function definitions that can be
+#  used to either build a static and shared libraries from sources, or
+#  generate a Makefile to do it in parallel.
+#
+
+_BUILD_TAB=$(echo " " | tr ' ' '\t')
+
+builder_command ()
+{
+    if [ -z "$_BUILD_MK" ]; then
+        echo "$@"
+        "$@"
+    else
+        echo "${_BUILD_TAB}$@" >> $_BUILD_MK
+    fi
+}
+
+
+builder_log ()
+{
+    if [ "$_BUILD_MK" ]; then
+        echo "${_BUILD_TAB}echo $@" >> $_BUILD_MK
+    else
+        log "$@"
+    fi
+}
+
+# $1: Build directory
+# $2: Optional Makefile name
+builder_begin ()
+{
+    _BUILD_DIR_NEW=
+    _BUILD_DIR=$1
+    if [ ! -d "$_BUILD_DIR" ]; then
+        mkdir -p "$_BUILD_DIR"
+        fail_panic "Can't create build directory: $_BUILD_DIR"
+        _BUILD_DIR_NEW=true
+    else
+        rm -rf "$_BUILD_DIR/*"
+        fail_panic "Can't cleanup build directory: $_BUILD_DIR"
+    fi
+    _BUILD_TARGETS=
+    _BUILD_PREFIX=
+    _BUILD_MK=$2
+    if [ -n "$_BUILD_MK" ]; then
+        log "Creating temporary build Makefile: $_BUILD_MK"
+        rm -f $_BUILD_MK &&
+        echo "# Auto-generated by $0 - do not edit!" > $_BUILD_MK
+        echo ".PHONY: all" >> $_BUILD_MK
+        echo "all:" >> $_BUILD_MK
+    fi
+
+    builder_begin_module
+}
+
+# $1: Variable name
+# out: Variable value
+_builder_varval ()
+{
+    eval echo "\$$1"
+}
+
+_builder_varadd ()
+{
+    local _varname="$1"
+    local _varval="$(_builder_varval $_varname)"
+    shift
+    if [ -z "$_varval" ]; then
+        eval $_varname=\"$@\"
+    else
+        eval $_varname=\$$_varname\" $@\"
+    fi
+}
+
+
+builder_set_prefix ()
+{
+    _BUILD_PREFIX="$@"
+}
+
+builder_begin_module ()
+{
+    _BUILD_CC=
+    _BUILD_CXX=
+    _BUILD_AR=
+    _BUILD_C_INCLUDES=
+    _BUILD_CFLAGS=
+    _BUILD_CXXFLAGS=
+    _BUILD_LDFLAGS_BEGIN_SO=
+    _BUILD_LDFLAGS_END_SO=
+    _BUILD_LDFLAGS_BEGIN_EXE=
+    _BUILD_LDFLAGS_END_EXE=
+    _BUILD_LDFLAGS=
+    _BUILD_BINPREFIX=
+    _BUILD_DSTDIR=
+    _BUILD_SRCDIR=.
+    _BUILD_OBJECTS=
+    _BUILD_STATIC_LIBRARIES=
+    _BUILD_SHARED_LIBRARIES=
+    _BUILD_COMPILER_RUNTIME_LDFLAGS=-lgcc
+}
+
+builder_set_binprefix ()
+{
+    _BUILD_BINPREFIX=$1
+    _BUILD_CC=${1}gcc
+    _BUILD_CXX=${1}g++
+    _BUILD_AR=${1}ar
+}
+
+builder_set_binprefix_llvm ()
+{
+    _BUILD_BINPREFIX=$1
+    _BUILD_CC=${1}/clang
+    _BUILD_CXX=${1}/clang++
+    _BUILD_AR=${2}ar
+}
+
+builder_set_builddir ()
+{
+    _BUILD_DIR=$1
+}
+
+builder_set_srcdir ()
+{
+    _BUILD_SRCDIR=$1
+}
+
+builder_set_dstdir ()
+{
+    _BUILD_DSTDIR=$1
+}
+
+builder_ldflags ()
+{
+    _builder_varadd _BUILD_LDFLAGS "$@"
+}
+
+builder_ldflags_exe ()
+{
+    _builder_varadd _BUILD_LDFLAGS_EXE "$@"
+}
+
+builder_cflags ()
+{
+    _builder_varadd _BUILD_CFLAGS "$@"
+}
+
+builder_cxxflags ()
+{
+    _builder_varadd _BUILD_CXXFLAGS "$@"
+}
+
+builder_c_includes ()
+{
+    _builder_varadd _BUILD_C_INCLUDES "$@"
+}
+
+# $1: optional var to hold the original cflags before reset
+builder_reset_cflags ()
+{
+    local _varname="$1"
+    if [ -n "$_varname" ] ; then
+        eval $_varname=\"$_BUILD_CFLAGS\"
+    fi
+    _BUILD_CFLAGS=
+}
+
+# $1: optional var to hold the original cxxflags before reset
+builder_reset_cxxflags ()
+{
+    local _varname="$1"
+    if [ -n "$_varname" ] ; then
+        eval $_varname=\"$_BUILD_CXXFLAGS\"
+    fi
+    _BUILD_CXXFLAGS=
+}
+
+# $1: optional var to hold the original c_includes before reset
+builder_reset_c_includes ()
+{
+    local _varname="$1"
+    if [ -n "$_varname" ] ; then
+        eval $_varname=\"$_BUILD_C_INCLUDES\"
+    fi
+    _BUILD_C_INCLUDES=
+}
+
+builder_compiler_runtime_ldflags ()
+{
+    _BUILD_COMPILER_RUNTIME_LDFLAGS=$1
+}
+
+builder_link_with ()
+{
+    local LIB
+    for LIB; do
+        case $LIB in
+            *.a)
+                _builder_varadd _BUILD_STATIC_LIBRARIES $LIB
+                ;;
+            *.so)
+                _builder_varadd _BUILD_SHARED_LIBRARIES $LIB
+                ;;
+            *)
+                echo "ERROR: Unknown link library extension: $LIB"
+                exit 1
+        esac
+    done
+}
+
+builder_sources ()
+{
+    local src srcfull obj cc cflags text
+    if [ -z "$_BUILD_DIR" ]; then
+        panic "Build directory not set!"
+    fi
+    if [ -z "$_BUILD_CC" ]; then
+        _BUILD_CC=${CC:-gcc}
+    fi
+    if [ -z "$_BUILD_CXX" ]; then
+        _BUILD_CXX=${CXX:-g++}
+    fi
+    for src in "$@"; do
+        srcfull=$_BUILD_SRCDIR/$src
+        if [ ! -f "$srcfull" ]; then
+            echo "ERROR: Missing source file: $srcfull"
+            exit 1
+        fi
+        obj=$src
+        cflags=""
+        for inc in $_BUILD_C_INCLUDES; do
+            cflags=$cflags" -I$inc"
+        done
+        cflags=$cflags" -I$_BUILD_SRCDIR"
+        case $obj in
+            *.c)
+                obj=${obj%%.c}
+                text="C"
+                cc=$_BUILD_CC
+                cflags="$cflags $_BUILD_CFLAGS"
+                ;;
+            *.cpp)
+                obj=${obj%%.cpp}
+                text="C++"
+                cc=$_BUILD_CXX
+                cflags="$cflags $_BUILD_CXXFLAGS"
+                ;;
+            *.cc)
+                obj=${obj%%.cc}
+                text="C++"
+                cc=$_BUILD_CXX
+                cflags="$cflags $_BUILD_CXXFLAGS"
+                ;;
+            *.S|*.s)
+                obj=${obj%%.$obj}
+                text="ASM"
+                cc=$_BUILD_CC
+                cflags="$cflags $_BUILD_CFLAGS"
+                ;;
+            *)
+                echo "Unknown source file extension: $obj"
+                exit 1
+                ;;
+        esac
+
+        # Source file path can include ../ path items, ensure
+        # that the generated object do not back up the output
+        # directory by translating them to __/
+        obj=$(echo "$obj" | tr '../' '__/')
+
+        # Ensure we have unwind tables in the generated machine code
+        # This is useful to get good stack traces
+        cflags=$cflags" -funwind-tables"
+
+        obj=$_BUILD_DIR/$obj.o
+        if [ "$_BUILD_MK" ]; then
+            echo "$obj: $srcfull" >> $_BUILD_MK
+        fi
+        builder_log "${_BUILD_PREFIX}$text: $src"
+        builder_command mkdir -p $(dirname "$obj")
+        builder_command $NDK_CCACHE $cc -c -o "$obj" "$srcfull" $cflags
+        fail_panic "Could not compile ${_BUILD_PREFIX}$src"
+        _BUILD_OBJECTS=$_BUILD_OBJECTS" $obj"
+    done
+}
+
+builder_static_library ()
+{
+    local lib libname arflags
+    libname=$1
+    if [ -z "$_BUILD_DSTDIR" ]; then
+        panic "Destination directory not set"
+    fi
+    lib=$_BUILD_DSTDIR/$libname
+    lib=${lib%%.a}.a
+    if [ "$_BUILD_MK" ]; then
+        _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
+        echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
+    fi
+    if [ -z "${_BUILD_AR}" ]; then
+        _BUILD_AR=${AR:-ar}
+    fi
+    builder_log "${_BUILD_PREFIX}Archive: $libname"
+    rm -f "$lib"
+    arflags="crs"
+    case $HOST_TAG in
+        darwin*)
+            # XCode 'ar' doesn't support D flag
+            ;;
+        *)
+            arflags="${arflags}D"
+            ;;
+    esac
+    builder_command ${_BUILD_AR} $arflags "$lib" "$_BUILD_OBJECTS"
+    fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!"
+}
+
+builder_host_static_library ()
+{
+    local lib libname
+    libname=$1
+    if [ -z "$_BUILD_DSTDIR" ]; then
+        panic "Destination directory not set"
+    fi
+    lib=$_BUILD_DSTDIR/$libname
+    lib=${lib%%.a}.a
+    if [ "$_BUILD_MK" ]; then
+        _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
+        echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
+    fi
+    if [ -z "$BUILD_AR" ]; then
+        _BUILD_AR=${AR:-ar}
+    fi
+    builder_log "${_BUILD_PREFIX}Archive: $libname"
+    rm -f "$lib"
+    builder_command ${_BUILD_AR} crsD "$lib" "$_BUILD_OBJECTS"
+    fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!"
+}
+
+builder_shared_library ()
+{
+    local lib libname suffix
+    libname=$1
+    suffix=$2
+
+    if [ -z "$suffix" ]; then
+        suffix=".so"
+    fi
+    lib=$_BUILD_DSTDIR/$libname
+    lib=${lib%%${suffix}}${suffix}
+    if [ "$_BUILD_MK" ]; then
+        _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
+        echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
+    fi
+    builder_log "${_BUILD_PREFIX}SharedLibrary: $libname"
+
+    # Important: -lgcc must appear after objects and static libraries,
+    #            but before shared libraries for Android. It doesn't hurt
+    #            for other platforms.
+    #            Also $libm must come before -lc because bionic libc
+    #            accidentally exports a soft-float version of ldexp.
+    builder_command ${_BUILD_CXX} \
+        -Wl,-soname,$(basename $lib) \
+        -Wl,-shared \
+        $_BUILD_LDFLAGS_BEGIN_SO \
+        $_BUILD_OBJECTS \
+        $_BUILD_STATIC_LIBRARIES \
+        $_BUILD_COMPILER_RUNTIME_LDFLAGS \
+        $_BUILD_SHARED_LIBRARIES \
+        -lm -lc \
+        $_BUILD_LDFLAGS \
+        $_BUILD_LDFLAGS_END_SO \
+        -o $lib
+    fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname"
+}
+
+# Same as builder_shared_library, but do not link the default libs
+builder_nostdlib_shared_library ()
+{
+    local lib libname suffix
+    libname=$1
+    suffix=$2
+    if [ -z "$suffix" ]; then
+        suffix=".so"
+    fi
+    lib=$_BUILD_DSTDIR/$libname
+    lib=${lib%%${suffix}}${suffix}
+    if [ "$_BUILD_MK" ]; then
+        _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
+        echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
+    fi
+    builder_log "${_BUILD_PREFIX}SharedLibrary: $libname"
+
+    builder_command ${_BUILD_CXX} \
+        -Wl,-soname,$(basename $lib) \
+        -Wl,-shared \
+        $_BUILD_LDFLAGS_BEGIN_SO \
+        $_BUILD_OBJECTS \
+        $_BUILD_STATIC_LIBRARIES \
+        $_BUILD_SHARED_LIBRARIES \
+        $_BUILD_LDFLAGS \
+        $_BUILD_LDFLAGS_END_SO \
+        -o $lib
+    fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname"
+}
+
+builder_host_shared_library ()
+{
+    local lib libname
+    libname=$1
+    lib=$_BUILD_DSTDIR/$libname
+    lib=${lib%%.so}.so
+    if [ "$_BUILD_MK" ]; then
+        _BUILD_TARGETS=$_BUILD_TARGETS" $lib"
+        echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK
+    fi
+    builder_log "${_BUILD_PREFIX}SharedLibrary: $libname"
+
+    if [ -z "$_BUILD_CXX" ]; then
+        _BUILD_CXX=${CXX:-g++}
+    fi
+
+    # Important: -lgcc must appear after objects and static libraries,
+    #            but before shared libraries for Android. It doesn't hurt
+    #            for other platforms.
+    builder_command ${_BUILD_CXX} \
+        -shared -s \
+        $_BUILD_OBJECTS \
+        $_BUILD_STATIC_LIBRARIES \
+        $_BUILD_SHARED_LIBRARIES \
+        $_BUILD_LDFLAGS \
+        -o $lib
+    fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname"
+}
+
+builder_host_executable ()
+{
+    local exe exename
+    exename=$1
+    exe=$_BUILD_DSTDIR/$exename$HOST_EXE
+    if [ "$_BUILD_MK" ]; then
+        _BUILD_TARGETS=$_BUILD_TARGETS" $exe"
+        echo "$exe: $_BUILD_OBJECTS" >> $_BUILD_MK
+    fi
+    builder_log "${_BUILD_PREFIX}Executable: $exename$HOST_EXE"
+
+    if [ -z "$_BUILD_CXX" ]; then
+        _BUILD_CXX=${CXX:-g++}
+    fi
+
+    # Important: -lgcc must appear after objects and static libraries,
+    #            but before shared libraries for Android. It doesn't hurt
+    #            for other platforms.
+    builder_command ${_BUILD_CXX} \
+        -s \
+        $_BUILD_OBJECTS \
+        $_BUILD_STATIC_LIBRARIES \
+        $_BUILD_SHARED_LIBRARIES \
+        $_BUILD_LDFLAGS \
+        -o $exe
+    fail_panic "Could not create ${_BUILD_PREFIX}executable $libname"
+}
+
+
+builder_end ()
+{
+    if [ "$_BUILD_MK" ]; then
+        echo "all: $_BUILD_TARGETS" >> $_BUILD_MK
+        run make -j$NUM_JOBS -f $_BUILD_MK
+        fail_panic "Could not build project!"
+    fi
+
+    if [ "$_BUILD_DIR_NEW" ]; then
+        log "Cleaning up build directory: $_BUILD_DIR"
+        rm -rf "$_BUILD_DIR"
+        _BUILD_DIR_NEW=
+    fi
+}
+
+# Same as builder_begin, but to target Android with a specific ABI
+# $1: ABI name (e.g. armeabi)
+# $2: Build directory
+# $3: Gcc version
+# $4: Optional llvm version
+# $5: Optional Makefile name
+# $6: Platform (android-X)
+builder_begin_android ()
+{
+    local ABI BUILDDIR LLVM_VERSION MAKEFILE
+    local ARCH SYSROOT LDIR FLAGS
+    local CRTBEGIN_SO_O CRTEND_SO_O CRTBEGIN_EXE_SO CRTEND_SO_O
+    local BINPREFIX GCC_TOOLCHAIN LLVM_TRIPLE GCC_VERSION
+    local SCRATCH_FLAGS PLATFORM
+    local PREBUILT_NDK=$ANDROID_BUILD_TOP/prebuilts/ndk/current
+    if [ -z "$ANDROID_BUILD_TOP" ]; then
+        panic "ANDROID_BUILD_TOP is not defined!"
+    elif [ ! -d "$PREBUILT_NDK/platforms" ]; then
+        panic "Missing directory: $PREBUILT_NDK/platforms"
+    fi
+    ABI=$1
+    BUILDDIR=$2
+    GCC_VERSION=$3
+    LLVM_VERSION=$4
+    MAKEFILE=$5
+    ARCH=$(convert_abi_to_arch $ABI)
+    PLATFORM=$6
+
+    if [ -n "$LLVM_VERSION" ]; then
+        # override GCC_VERSION to pick $DEFAULT_LLVM_GCC??_VERSION instead
+        if [ "$ABI" != "${ABI%%64*}" ]; then
+            GCC_VERSION=$DEFAULT_LLVM_GCC64_VERSION
+        else
+            GCC_VERSION=$DEFAULT_LLVM_GCC32_VERSION
+        fi
+    fi
+    for TAG in $HOST_TAG $HOST_TAG32; do
+        BINPREFIX=$ANDROID_BUILD_TOP/prebuilts/ndk/current/$(get_toolchain_binprefix_for_arch $ARCH $GCC_VERSION $TAG)
+        if [ -f ${BINPREFIX}gcc ]; then
+            break;
+        fi
+    done
+    if [ -n "$LLVM_VERSION" ]; then
+        GCC_TOOLCHAIN=`dirname $BINPREFIX`
+        GCC_TOOLCHAIN=`dirname $GCC_TOOLCHAIN`
+        LLVM_BINPREFIX=$(get_llvm_toolchain_binprefix $TAG)
+    fi
+
+    if [ -z "$PLATFORM" ]; then
+      SYSROOT=$PREBUILT_NDK/$(get_default_platform_sysroot_for_arch $ARCH)
+    else
+      SYSROOT=$PREBUILT_NDK/platforms/$PLATFORM/arch-$ARCH
+    fi
+    LDIR=$SYSROOT"/usr/"$(get_default_libdir_for_abi $ABI)
+
+    CRTBEGIN_EXE_O=$LDIR/crtbegin_dynamic.o
+    CRTEND_EXE_O=$LDIR/crtend_android.o
+
+    CRTBEGIN_SO_O=$LDIR/crtbegin_so.o
+    CRTEND_SO_O=$LDIR/crtend_so.o
+    if [ ! -f "$CRTBEGIN_SO_O" ]; then
+        CRTBEGIN_SO_O=$CRTBEGIN_EXE_O
+    fi
+    if [ ! -f "$CRTEND_SO_O" ]; then
+        CRTEND_SO_O=$CRTEND_EXE_O
+    fi
+
+    builder_begin "$BUILDDIR" "$MAKEFILE"
+    builder_set_prefix "$ABI "
+    if [ -z "$LLVM_VERSION" ]; then
+        builder_set_binprefix "$BINPREFIX"
+    else
+        builder_set_binprefix_llvm "$LLVM_BINPREFIX" "$BINPREFIX"
+        case $ABI in
+            armeabi)
+                LLVM_TRIPLE=armv5te-none-linux-androideabi
+                ;;
+            armeabi-v7a)
+                LLVM_TRIPLE=armv7-none-linux-androideabi
+                ;;
+            arm64-v8a)
+                LLVM_TRIPLE=aarch64-none-linux-android
+                ;;
+            x86)
+                LLVM_TRIPLE=i686-none-linux-android
+                ;;
+            x86_64)
+                LLVM_TRIPLE=x86_64-none-linux-android
+                ;;
+            mips|mips32r6)
+                LLVM_TRIPLE=mipsel-none-linux-android
+                ;;
+            mips64)
+                LLVM_TRIPLE=mips64el-none-linux-android
+                ;;
+        esac
+        SCRATCH_FLAGS="-target $LLVM_TRIPLE $FLAGS"
+        builder_ldflags "$SCRATCH_FLAGS"
+        builder_cflags  "$SCRATCH_FLAGS"
+        builder_cxxflags "$SCRATCH_FLAGS"
+        if [ ! -z $GCC_TOOLCHAIN ]; then
+            SCRATCH_FLAGS="-gcc-toolchain $GCC_TOOLCHAIN"
+            builder_cflags "$SCRATCH_FLAGS"
+            builder_cxxflags "$SCRATCH_FLAGS"
+            builder_ldflags "$SCRATCH_FLAGS"
+            if [ "$ABI" = "mips" ]; then
+              # Help clang use mips64el multilib GCC
+              SCRATCH_FLAGS="-L${GCC_TOOLCHAIN}/lib/gcc/mips64el-linux-android/4.9.x/32/mips-r1 "
+              builder_ldflags "$SCRATCH_FLAGS"
+            fi
+        fi
+    fi
+
+    SCRATCH_FLAGS="--sysroot=$SYSROOT"
+    builder_cflags "$SCRATCH_FLAGS"
+    builder_cxxflags "$SCRATCH_FLAGS"
+
+    SCRATCH_FLAGS="--sysroot=$SYSROOT -nostdlib"
+    _BUILD_LDFLAGS_BEGIN_SO="$SCRATCH_FLAGS $CRTBEGIN_SO_O"
+    _BUILD_LDFLAGS_BEGIN_EXE="$SCRATCH_FLAGS $CRTBEGIN_EXE_O"
+
+    _BUILD_LDFLAGS_END_SO="$CRTEND_SO_O"
+    _BUILD_LDFLAGS_END_EXE="$CRTEND_EXE_O"
+
+    case $ABI in
+        armeabi)
+            if [ -z "$LLVM_VERSION" ]; then
+                # add -minline-thumb1-jumptable such that gabi++/stlport/libc++ can be linked
+                # with compiler-rt where helpers __gnu_thumb1_case_* (in libgcc.a) don't exist
+                SCRATCH_FLAGS="-minline-thumb1-jumptable"
+                builder_cflags "$SCRATCH_FLAGS"
+                builder_cxxflags "$SCRATCH_FLAGS"
+            else
+                builder_cflags ""
+                builder_cxxflags ""
+            fi
+            ;;
+        armeabi-v7a)
+            SCRATCH_FLAGS="-march=armv7-a -mfpu=vfpv3-d16 -mfloat-abi=softfp"
+            builder_cflags "$SCRATCH_FLAGS"
+            builder_cxxflags "$SCRATCH_FLAGS"
+            builder_ldflags "-march=armv7-a -Wl,--fix-cortex-a8"
+            ;;
+        mips)
+            SCRATCH_FLAGS="-mips32"
+            builder_cflags "$SCRATCH_FLAGS"
+            builder_cxxflags "$SCRATCH_FLAGS"
+            builder_ldflags "-mips32"
+            ;;
+    esac
+}
+
+# $1: Build directory
+# $2: Optional Makefile name
+builder_begin_host ()
+{
+    prepare_host_build
+    builder_begin "$1" "$2"
+    builder_set_prefix "$HOST_TAG "
+}
diff --git a/build/tools/common-build-host-funcs.sh b/build/tools/common-build-host-funcs.sh
new file mode 100644
index 0000000..f008007
--- /dev/null
+++ b/build/tools/common-build-host-funcs.sh
@@ -0,0 +1,809 @@
+# Copyright (C) 2012 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.
+#
+
+# A set of function shared by the 'build-host-xxxx.sh' scripts.
+# They are mostly related to building host libraries.
+#
+# NOTE: This script uses various prefixes:
+#
+#    BH_       Used for public macros
+#    bh_       Use for public functions
+#
+#    _BH_      Used for private macros
+#    _bh_      Used for private functions
+#
+# Callers should only rely on the public macros and functions defined here.
+#
+
+# List of macros defined by the functions here:
+#
+#   defined by 'bh_set_build_tag'
+#
+#   BH_BUILD_CONFIG     Generic GNU config triplet for build system
+#   BH_BUILD_OS         NDK system name
+#   BH_BUILD_ARCH       NDK arch name
+#   BH_BUILD_TAG        NDK system tag ($OS-$ARCH)
+#   BH_BUILD_BITS       build system bitness (32 or 64)
+#
+#   defined by 'bh_set_host_tag'
+#                          7
+#   BH_HOST_CONFIG
+#   BH_HOST_OS
+#   BH_HOST_ARCH
+#   BH_HOST_TAG
+#   BH_HOST_BITS
+#
+#   defined by 'bh_set_target_tag'
+#
+#   BH_TARGET_CONFIG
+#   BH_TARGET_OS
+#   BH_TARGET_ARCH
+#   BH_TARGET_TAG
+#   BH_TARGET_BITS
+#
+#
+
+
+# The values of HOST_OS/ARCH/TAG will be redefined during the build to
+# match those of the system the generated compiler binaries will run on.
+#
+# Save the original ones into BUILD_XXX variants, corresponding to the
+# machine where the build happens.
+#
+BH_BUILD_OS=$HOST_OS
+BH_BUILD_ARCH=$HOST_ARCH
+BH_BUILD_TAG=$HOST_TAG
+
+# Map an NDK system tag to an OS name
+# $1: system tag (e.g. linux-x86)
+# Out: system name (e.g. linux)
+bh_tag_to_os ()
+{
+    local RET
+    case $1 in
+        android-*) RET="android";;
+        linux-*) RET="linux";;
+        darwin-*) RET="darwin";;
+        windows|windows-*) RET="windows";;
+        *) echo "ERROR: Unknown tag $1" >&2; echo "INVALID"; exit 1;;
+    esac
+    echo $RET
+}
+
+# Map an NDK system tag to an architecture name
+# $1: system tag (e.g. linux-x86)
+# Out: arch name (e.g. x86)
+bh_tag_to_arch ()
+{
+    local RET
+    case $1 in
+        *-arm) RET=arm;;
+        *-arm64) RET=arm64;;
+        *-mips) RET=mips;;
+        *-mips64) RET=mips64;;
+        windows|*-x86) RET=x86;;
+        *-x86_64) RET=x86_64;;
+        *) echo "ERROR: Unknown tag $1" >&2; echo "INVALID"; exit 1;;
+    esac
+    echo $RET
+}
+
+# Map an NDK system tag to a bit number
+# $1: system tag (e.g. linux-x86)
+# Out: bit number (32 or 64)
+bh_tag_to_bits ()
+{
+    local RET
+    case $1 in
+        windows|*-x86|*-arm|*-mips) RET=32;;
+        *-x86_64|*-arm64|*-mips64) RET=64;;
+        *) echo "ERROR: Unknown tag $1" >&2; echo "INVALID"; exit 1;;
+    esac
+    echo $RET
+}
+
+# Map an NDK system tag to the corresponding GNU configuration triplet.
+# $1: NDK system tag
+# Out: GNU configuration triplet
+bh_tag_to_config_triplet ()
+{
+    local RET
+    case $1 in
+        linux-x86) RET=i686-linux-gnu;;
+        linux-x86_64) RET=x86_64-linux-gnu;;
+        darwin-x86) RET=i686-apple-darwin;;
+        darwin-x86_64) RET=x86_64-apple-darwin;;
+        windows|windows-x86) RET=i686-w64-mingw32;;
+        windows-x86_64) RET=x86_64-w64-mingw32;;
+        android-arm) RET=arm-linux-androideabi;;
+        android-arm64) RET=aarch64-linux-android;;
+        android-x86) RET=i686-linux-android;;
+        android-x86_64) RET=x86_64-linux-android;;
+        android-mips) RET=mipsel-linux-android;;
+        android-mips64) RET=mips64el-linux-android;;
+        *) echo "ERROR: Unknown tag $1" >&2; echo "INVALID"; exit 1;;
+    esac
+    echo "$RET"
+}
+
+
+bh_set_build_tag ()
+{
+  SAVED_OPTIONS=$(set +o)
+  set -e
+  BH_BUILD_OS=$(bh_tag_to_os $1)
+  BH_BUILD_ARCH=$(bh_tag_to_arch $1)
+  BH_BUILD_BITS=$(bh_tag_to_bits $1)
+  BH_BUILD_TAG=$BH_BUILD_OS-$BH_BUILD_ARCH
+  BH_BUILD_CONFIG=$(bh_tag_to_config_triplet $1)
+  eval "$SAVED_OPTIONS"
+}
+
+# Set default BH_BUILD macros.
+bh_set_build_tag $HOST_TAG
+
+bh_set_host_tag ()
+{
+  SAVED_OPTIONS=$(set +o)
+  set -e
+  BH_HOST_OS=$(bh_tag_to_os $1)
+  BH_HOST_ARCH=$(bh_tag_to_arch $1)
+  BH_HOST_BITS=$(bh_tag_to_bits $1)
+  BH_HOST_TAG=$BH_HOST_OS-$BH_HOST_ARCH
+  BH_HOST_CONFIG=$(bh_tag_to_config_triplet $1)
+  eval "$SAVED_OPTIONS"
+}
+
+bh_set_target_tag ()
+{
+  SAVED_OPTIONS=$(set +o)
+  set -e
+  BH_TARGET_OS=$(bh_tag_to_os $1)
+  BH_TARGET_ARCH=$(bh_tag_to_arch $1)
+  BH_TARGET_BITS=$(bh_tag_to_bits $1)
+  BH_TARGET_TAG=$BH_TARGET_OS-$BH_TARGET_ARCH
+  BH_TARGET_CONFIG=$(bh_tag_to_config_triplet $1)
+  eval "$SAVED_OPTIONS"
+}
+
+bh_sort_systems_build_first ()
+{
+  local IN_SYSTEMS="$1"
+  local OUT_SYSTEMS
+  # Pull out the host if there
+  for IN_SYSTEM in $IN_SYSTEMS; do
+    if [ "$IN_SYSTEM" = "$BH_BUILD_TAG" ]; then
+        OUT_SYSTEMS=$IN_SYSTEM
+    fi
+  done
+  # Append the rest
+  for IN_SYSTEM in $IN_SYSTEMS; do
+    if [ ! "$IN_SYSTEM" = "$BH_BUILD_TAG" ]; then
+        OUT_SYSTEMS=$OUT_SYSTEMS" $IN_SYSTEM"
+    fi
+  done
+  echo $OUT_SYSTEMS
+}
+
+# $1 is the string to search for
+# $2... is the list to search in
+# Returns first, yes or no.
+bh_list_contains ()
+{
+  local SEARCH="$1"
+  shift
+  # For dash, this has to be split over 2 lines.
+  # Seems to be a bug with dash itself:
+  # https://bugs.launchpad.net/ubuntu/+source/dash/+bug/141481
+  local LIST
+  LIST=$@
+  local RESULT=first
+  # Pull out the host if there
+  for ELEMENT in $LIST; do
+    if [ "$ELEMENT" = "$SEARCH" ]; then
+      echo $RESULT
+      return 0
+    fi
+    RESULT=yes
+  done
+  echo no
+  return 1
+}
+
+
+# Use this function to enable/disable colored output
+# $1: 'true' or 'false'
+bh_set_color_mode ()
+{
+  local DO_COLOR=
+  case $1 in
+    on|enable|true) DO_COLOR=true
+    ;;
+  esac
+  if [ "$DO_COLOR" ]; then
+    _BH_COLOR_GREEN="\033[32m"
+    _BH_COLOR_PURPLE="\033[35m"
+    _BH_COLOR_CYAN="\033[36m"
+    _BH_COLOR_END="\033[0m"
+  else
+    _BH_COLOR_GREEN=
+    _BH_COLOR_PURPLE=
+    _BH_COLOR_CYAN=
+    _BH_COLOR_END=
+  fi
+}
+
+# By default, enable color mode
+bh_set_color_mode true
+
+# Pretty printing with colors!
+bh_host_text ()
+{
+    printf "[${_BH_COLOR_GREEN}${BH_HOST_TAG}${_BH_COLOR_END}]"
+}
+
+bh_toolchain_text ()
+{
+    printf "[${_BH_COLOR_PURPLE}${BH_TOOLCHAIN}${_BH_COLOR_END}]"
+}
+
+bh_target_text ()
+{
+    printf "[${_BH_COLOR_CYAN}${BH_TARGET_TAG}${_BH_COLOR_END}]"
+}
+
+bh_arch_text ()
+{
+    # Print arch name in cyan
+    printf "[${_BH_COLOR_CYAN}${BH_TARGET_ARCH}${_BH_COLOR_END}]"
+}
+
+# Check that a given compiler generates code correctly
+#
+# This is to detect bad/broken toolchains, e.g. amd64-mingw32msvc
+# is totally broken on Ubuntu 10.10 and 11.04
+#
+# $1: compiler
+# $2: optional extra flags
+#
+bh_check_compiler ()
+{
+    local CC="$1"
+    local TMPC=$TMPDIR/build-host-$USER-$$.c
+    local TMPE=${TMPC%%.c}
+    local TMPL=$TMPC.log
+    local RET
+    shift
+    cat > $TMPC <<EOF
+int main(void) { return 0; }
+EOF
+    log_n "Checking compiler code generation ($CC)... "
+    $CC -o $TMPE $TMPC "$@" >$TMPL 2>&1
+    RET=$?
+    rm -f $TMPC $TMPE $TMPL
+    if [ "$RET" = 0 ]; then
+        log "yes"
+    else
+        log "no"
+    fi
+    return $RET
+}
+
+
+# $1: toolchain install dir
+# $2: toolchain prefix, no trailing dash (e.g. arm-linux-androideabi)
+# $3: optional -m32 or -m64.
+_bh_try_host_fullprefix ()
+{
+    local PREFIX="$1/bin/$2"
+    shift; shift;
+    if [ -z "$HOST_FULLPREFIX" ]; then
+        local GCC="$PREFIX-gcc"
+        if [ -f "$GCC" ]; then
+            if bh_check_compiler "$GCC" "$@"; then
+                HOST_FULLPREFIX="${GCC%%gcc}"
+                dump "$(bh_host_text) Using host gcc: $GCC $@"
+            else
+                dump "$(bh_host_text) Ignoring broken host gcc: $GCC $@"
+            fi
+        fi
+    fi
+}
+
+# $1: host prefix, no trailing slash (e.g. i686-linux-android)
+# $2: optional compiler args (should be empty, -m32 or -m64)
+_bh_try_host_prefix ()
+{
+    local PREFIX="$1"
+    shift
+    if [ -z "$HOST_FULLPREFIX" ]; then
+        local GCC="$(which $PREFIX-gcc 2>/dev/null)"
+        if [ "$GCC" -a -e "$GCC" ]; then
+            if bh_check_compiler "$GCC" "$@"; then
+                HOST_FULLPREFIX=${GCC%%gcc}
+                dump "$(bh_host_text) Using host gcc: ${HOST_FULLPREFIX}gcc $@"
+            else
+                dump "$(bh_host_text) Ignoring broken host gcc: $GCC $@"
+            fi
+        fi
+    fi
+}
+
+# Used to determine the minimum possible Darwin version that a Darwin SDK
+# can target. This actually depends from the host architecture.
+# $1: Host architecture name
+# out: SDK version number (e.g. 10.4 or 10.5)
+_bh_darwin_arch_to_min_version ()
+{
+  if [ "$1" = "x86" ]; then
+    echo "10.4"
+  else
+    echo "10.5"
+  fi
+}
+
+# Use the check for the availability of a compatibility SDK in Darwin
+# this can be used to generate binaries compatible with either Tiger or
+# Leopard.
+#
+# $1: SDK root path
+# $2: Darwin compatibility minimum version
+_bh_check_darwin_sdk ()
+{
+    if [ -d "$1" -a -z "$HOST_CFLAGS" ] ; then
+        HOST_CFLAGS="-isysroot $1 -mmacosx-version-min=$2 -DMAXOSX_DEPLOYEMENT_TARGET=$2"
+        HOST_CXXFLAGS=$HOST_CFLAGS
+        HOST_LDFLAGS="-syslibroot $1 -mmacosx-version-min=$2"
+        dump "Generating $2-compatible binaries."
+        return 0  # success
+    fi
+    return 1
+}
+
+# Check that a given compiler generates 32 or 64 bit code.
+# $1: compiler full path (.e.g  /path/to/fullprefix-gcc)
+# $2: 32 or 64
+# $3: extract compiler flags
+# Return: success iff the compiler generates $2-bits code
+_bh_check_compiler_bitness ()
+{
+    local CC="$1"
+    local BITS="$2"
+    local TMPC=$TMPDIR/build-host-gcc-bits-$USER-$$.c
+    local TMPL=$TMPC.log
+    local RET
+    shift; shift;
+    cat > $TMPC <<EOF
+/* this program will fail to compile if the compiler doesn't generate BITS-bits code */
+int tab[1-2*(sizeof(void*)*8 != BITS)];
+EOF
+    dump_n "$(bh_host_text) Checking that the compiler generates $BITS-bits code ($@)... "
+    $CC -c -DBITS=$BITS -o /dev/null $TMPC $HOST_CFLAGS "$@" > $TMPL 2>&1
+    RET=$?
+    rm -f $TMPC $TMPL
+    if [ "$RET" = 0 ]; then
+        dump "yes"
+    else
+        dump "no"
+    fi
+    return $RET
+}
+
+# This function probes the system to find the best toolchain or cross-toolchain
+# to build binaries that run on a given host system. After that, it generates
+# a wrapper toolchain under $2 with a prefix of ${BH_HOST_CONFIG}-
+# where $BH_HOST_CONFIG is a GNU configuration name.
+#
+# Important: this script might redefine $BH_HOST_CONFIG to a different value!
+# (This behavior previously happened with MinGW, but doesn't anymore.)
+#
+# $1: NDK system tag (e.g. linux-x86)
+#
+# The following can be defined, otherwise they'll be auto-detected and set.
+#
+#  DARWIN_MIN_VERSION   -> Darwmin minimum compatibility version
+#  DARWIN_SDK_VERSION   -> Darwin SDK version
+#
+# The following can be defined for extra features:
+#
+#  DARWIN_TOOLCHAIN     -> Path to Darwin cross-toolchain (cross-compile only).
+#  DARWIN_SYSROOT       -> Path to Darwin SDK sysroot (cross-compile only).
+#  NDK_CCACHE           -> Ccache binary to use to speed up rebuilds.
+#  ANDROID_NDK_ROOT     -> Top-level NDK directory, for automatic probing
+#                          of prebuilt platform toolchains.
+#
+_bh_select_toolchain_for_host ()
+{
+    local HOST_CFLAGS HOST_CXXFLAGS HOST_LDFLAGS
+    local HOST_ASFLAGS HOST_WINDRES_FLAGS
+    local HOST_FULLPREFIX
+    local DARWIN_ARCH DARWIN_SDK_SUBDIR
+
+    # We do all the complex auto-detection magic in the setup phase,
+    # then save the result in host-specific global variables.
+    #
+    # In the build phase, we will simply restore the values into the
+    # global HOST_FULLPREFIX / HOST_BUILD_DIR
+    # variables.
+    #
+
+    # Try to find the best toolchain to do that job, assuming we are in
+    # a full Android platform source checkout, we can look at the prebuilts/
+    # directory.
+    case $1 in
+        linux-x86)
+            # If possible, automatically use our custom toolchain to generate
+            # 32-bit executables that work on Ubuntu 8.04 and higher.
+            _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.6" i686-linux
+            _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/i686-linux-glibc2.7-4.4.3" i686-linux
+            _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilt/linux-x86/toolchain/i686-linux-glibc2.7-4.4.3" i686-linux
+            _bh_try_host_prefix i686-linux-gnu
+            _bh_try_host_prefix i686-linux
+            _bh_try_host_prefix x86_64-linux-gnu -m32
+            _bh_try_host_prefix x86_64-linux -m32
+            ;;
+
+        linux-x86_64)
+            # If possible, automaticaly use our custom toolchain to generate
+            # 64-bit executables that work on Ubuntu 8.04 and higher.
+            _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8" x86_64-linux
+            _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.7-4.6" x86_64-linux
+            _bh_try_host_prefix x86_64-linux-gnu
+            _bh_try_host_prefix x84_64-linux
+            _bh_try_host_prefix i686-linux-gnu -m64
+            _bh_try_host_prefix i686-linux -m64
+            ;;
+
+        darwin-*)
+            DARWIN_ARCH=$(bh_tag_to_arch $1)
+            if [ -z "$DARWIN_MIN_VERSION" ]; then
+                DARWIN_MIN_VERSION=$(_bh_darwin_arch_to_min_version $DARWIN_ARCH)
+            fi
+            case $BH_BUILD_OS in
+                darwin)
+                    if [ "$DARWIN_SDK_VERSION" ]; then
+                        # Compute SDK subdirectory name
+                        case $DARWIN_SDK_VERSION in
+                            10.4) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdku;;
+                            *) DARWIN_SDK_SUBDIR=$DARWIN_SDK.sdk;;
+                        esac
+                        # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder.
+                        _bh_check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_MIN_VERSION
+                        _bh_check_darwin_sdk /Developer/SDKs/MacOSX$DARWIN_SDK_SUBDIR $DARWIN_MIN_VERSION
+                    else
+                        # Since xCode moved to the App Store the SDKs have been 'sandboxed' into the Xcode.app folder.
+                        _bh_check_darwin_sdk /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk $DARWIN_MIN_VERSION
+                        _bh_check_darwin_sdk /Developer/SDKs/MacOSX10.7.sdk  $DARWIN_MIN_VERSION
+                        _bh_check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk  $DARWIN_MIN_VERSION
+                        # NOTE: The 10.5.sdk on Lion is buggy and cannot build basic C++ programs
+                        #_bh_check_darwin_sdk /Developer/SDKs/MacOSX10.5.sdk  $DARWIN_ARCH
+                        # NOTE: The 10.4.sdku is not available anymore and could not be tested.
+                        #_bh_check_darwin_sdk /Developer/SDKs/MacOSX10.4.sdku $DARWIN_ARCH
+                    fi
+                    if [ -z "$HOST_CFLAGS" ]; then
+                        local version="$(sw_vers -productVersion)"
+                        log "Generating $version-compatible binaries!"
+                    fi
+                    ;;
+                *)
+                    if [ -z "$DARWIN_TOOLCHAIN" -o -z "$DARWIN_SYSROOT" ]; then
+                        dump "If you want to build Darwin binaries on a non-Darwin machine,"
+                        dump "Please define DARWIN_TOOLCHAIN to name it, and DARWIN_SYSROOT to point"
+                        dump "to the SDK. For example:"
+                        dump ""
+                        dump "   DARWIN_TOOLCHAIN=\"i686-apple-darwin11\""
+                        dump "   DARWIN_SYSROOT=\"~/darwin-cross/MacOSX10.7.sdk\""
+                        dump "   export DARWIN_TOOLCHAIN DARWIN_SYSROOT"
+                        dump ""
+                        exit 1
+                    fi
+                    _bh_check_darwin_sdk $DARWIN_SYSROOT $DARWIN_MIN_VERSION
+                    _bh_try_host_prefix "$DARWIN_TOOLCHAIN" -m$(bh_tag_to_bits $1) --sysroot "$DARWIN_SYSROOT"
+                    if [ -z "$HOST_FULLPREFIX" ]; then
+                        dump "It looks like $DARWIN_TOOLCHAIN-gcc is not in your path, or does not work correctly!"
+                        exit 1
+                    fi
+                    dump "Using darwin cross-toolchain: ${HOST_FULLPREFIX}gcc"
+                    ;;
+            esac
+            ;;
+
+        windows|windows-x86)
+            case $BH_BUILD_OS in
+                linux)
+                    # Prefer the prebuilt cross-compiler.
+                    _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" x86_64-w64-mingw32 -m32
+                    # We favor these because they are more recent, and because
+                    # we have a script to rebuild them from scratch. See
+                    # build-mingw64-toolchain.sh. Typically provided by the
+                    # 'mingw-w64' package on Debian and Ubuntu systems.
+                    _bh_try_host_prefix i686-w64-mingw32
+                    _bh_try_host_prefix x86_64-w64-mingw32 -m32
+                    # Special note for Fedora: this distribution used
+                    # to have a mingw32-gcc package that provided a 32-bit
+                    # only cross-toolchain named i686-pc-mingw32.
+                    # Later versions of the distro now provide a new package
+                    # named mingw-gcc which provides i686-w64-mingw32 and
+                    # x86_64-w64-mingw32 instead.
+                    if [ -z "$HOST_FULLPREFIX" ]; then
+                        dump "There is no Windows cross-compiler. Ensure that you"
+                        dump "have one of these installed and in your path:"
+                        dump "   i686-w64-mingw32-gcc    (see build-mingw64-toolchain.sh)"
+                        dump "   x86_64-w64-mingw32-gcc  (see build-mingw64-toolchain.sh)"
+                        dump ""
+                        exit 1
+                    fi
+                    if [ "$BH_HOST_CONFIG" != i686-w64-mingw32 ]; then
+                        panic "Unexpected value of BH_HOST_CONFIG: $BH_HOST_CONFIG"
+                    fi
+                    # If the 32-bit wrappers call a 64-bit toolchain, add flags
+                    # to default ld/as/windres to 32 bits.
+                    case "$HOST_FULLPREFIX" in
+                        *x86_64-w64-mingw32-)
+                            HOST_LDFLAGS="-m i386pe"
+                            HOST_ASFLAGS="--32"
+                            HOST_WINDRES_FLAGS="-F pe-i386"
+                            ;;
+                        *)
+                            ;;
+                    esac
+                    ;;
+                *) panic "Sorry, this script only supports building windows binaries on Linux."
+                ;;
+            esac
+            HOST_CFLAGS=$HOST_CFLAGS" -D__USE_MINGW_ANSI_STDIO=1"
+            HOST_CXXFLAGS=$HOST_CXXFLAGS" -D__USE_MINGW_ANSI_STDIO=1"
+            ;;
+
+        windows-x86_64)
+            case $BH_BUILD_OS in
+                linux)
+                    # Prefer the prebuilt cross-compiler.
+                    # See comments above for windows-x86.
+                    _bh_try_host_fullprefix "$(dirname $ANDROID_NDK_ROOT)/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8" x86_64-w64-mingw32
+                    _bh_try_host_prefix x86_64-w64-mingw32
+                    if [ -z "$HOST_FULLPREFIX" ]; then
+                        dump "There is no Windows cross-compiler in your path. Ensure you"
+                        dump "have one of these installed and in your path:"
+                        dump "   x86_64-w64-mingw32-gcc  (see build-mingw64-toolchain.sh)"
+                        dump ""
+                        exit 1
+                    fi
+                    if [ "$BH_HOST_CONFIG" != x86_64-w64-mingw32 ]; then
+                        panic "Unexpected value of BH_HOST_CONFIG: $BH_HOST_CONFIG"
+                    fi
+                    ;;
+
+                *) panic "Sorry, this script only supports building windows binaries on Linux."
+                ;;
+            esac
+            HOST_CFLAGS=$HOST_CFLAGS" -D__USE_MINGW_ANSI_STDIO=1"
+            HOST_CXXFLAGS=$HOST_CXXFLAGS" -D__USE_MINGW_ANSI_STDIO=1"
+            ;;
+    esac
+
+    # Determine the default bitness of our compiler. It it doesn't match
+    # HOST_BITS, tries to see if it supports -m32 or -m64 to change it.
+    if ! _bh_check_compiler_bitness ${HOST_FULLPREFIX}gcc $BH_HOST_BITS; then
+        local TRY_CFLAGS
+        case $BH_HOST_BITS in
+            32) TRY_CFLAGS=-m32;;
+            64) TRY_CFLAGS=-m64;;
+        esac
+        if ! _bh_check_compiler_bitness ${HOST_FULLPREFIX}gcc $BH_HOST_BITS $TRY_CFLAGS; then
+            panic "Can't find a way to generate $BH_HOST_BITS binaries with this compiler: ${HOST_FULLPREFIX}gcc"
+        fi
+        HOST_CFLAGS=$HOST_CFLAGS" "$TRY_CFLAGS
+        HOST_CXXFLAGS=$HOST_CXXFLAGS" "$TRY_CFLAGS
+    fi
+
+    # Support for ccache, to speed up rebuilds.
+    DST_PREFIX=$HOST_FULLPREFIX
+    local CCACHE=
+    if [ "$NDK_CCACHE" ]; then
+        CCACHE="--ccache=$NDK_CCACHE"
+    fi
+
+    # We're going to generate a wrapper toolchain with the $HOST prefix
+    # i.e. if $HOST is 'i686-linux-gnu', then we're going to generate a
+    # wrapper toolchain named 'i686-linux-gnu-gcc' that will redirect
+    # to whatever HOST_FULLPREFIX points to, with appropriate modifier
+    # compiler/linker flags.
+    #
+    # This helps tremendously getting stuff to compile with the GCC
+    # configure scripts.
+    #
+    run mkdir -p "$BH_WRAPPERS_DIR" &&
+    run $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh "$BH_WRAPPERS_DIR" \
+        --src-prefix="$BH_HOST_CONFIG-" \
+        --dst-prefix="$DST_PREFIX" \
+        --cflags="$HOST_CFLAGS" \
+        --cxxflags="$HOST_CXXFLAGS" \
+        --ldflags="$HOST_LDFLAGS" \
+        --asflags="$HOST_ASFLAGS" \
+        --windres-flags="$HOST_WINDRES_FLAGS" \
+        $CCACHE
+}
+
+
+# Setup the build directory, i.e. a directory where all intermediate
+# files will be placed.
+#
+# $1: Build directory. Required.
+#
+# $2: Either 'preserve' or 'remove'. Indicates what to do of
+#     existing files in the build directory, if any.
+#
+# $3: Either 'release' or 'debug'. Compilation mode.
+#
+bh_setup_build_dir ()
+{
+    BH_BUILD_DIR="$1"
+    if [ -z "$BH_BUILD_DIR" ]; then
+        panic "bh_setup_build_dir received no build directory"
+    fi
+    mkdir -p "$BH_BUILD_DIR"
+    fail_panic "Could not create build directory: $BH_BUILD_DIR"
+
+    if [ "$_BH_OPTION_FORCE" ]; then
+        rm -rf "$BH_BUILD_DIR"/*
+    fi
+
+    if [ "$_BH_OPTION_NO_STRIP" ]; then
+        BH_BUILD_MODE=debug
+    else
+        BH_BUILD_MODE=release
+    fi
+
+    # The directory that will contain our toolchain wrappers
+    BH_WRAPPERS_DIR=$BH_BUILD_DIR/toolchain-wrappers
+    rm -rf "$BH_WRAPPERS_DIR" && mkdir "$BH_WRAPPERS_DIR"
+    fail_panic "Could not create wrappers dir: $BH_WRAPPERS_DIR"
+
+    # The directory that will contain our timestamps
+    BH_STAMPS_DIR=$BH_BUILD_DIR/timestamps
+    mkdir -p "$BH_STAMPS_DIR"
+    fail_panic "Could not create timestamps dir"
+}
+
+# Call this before anything else to setup a few important variables that are
+# used consistently to build any host-specific binaries.
+#
+# $1: Host system name (e.g. linux-x86), this is the name of the host system
+#     where the generated GCC binaries will run, not the current machine's
+#     type (this one is in $ORIGINAL_HOST_TAG instead).
+#
+bh_setup_build_for_host ()
+{
+    local HOST_VARNAME=$(dashes_to_underscores $1)
+    local HOST_VAR=_BH_HOST_${HOST_VARNAME}
+
+    # Determine the host configuration triplet in $HOST
+    bh_set_host_tag $1
+
+    # Note: since _bh_select_toolchain_for_host can change the value of
+    # $BH_HOST_CONFIG, we need to save it in a variable to later get the
+    # correct one when this function is called again.
+    if [ -z "$(var_value ${HOST_VAR}_SETUP)" ]; then
+        _bh_select_toolchain_for_host $1
+        var_assign ${HOST_VAR}_CONFIG $BH_HOST_CONFIG
+        var_assign ${HOST_VAR}_SETUP true
+    else
+        BH_HOST_CONFIG=$(var_value ${HOST_VAR}_CONFIG)
+    fi
+}
+
+# This function is used to setup the build environment whenever we
+# generate host-specific binaries. You should call it before invoking
+# a configure script or make.
+#
+# It assume sthat bh_setup_build_for_host was called with the right
+# host system tag and wrappers directory.
+#
+bh_setup_host_env ()
+{
+    CC=$BH_HOST_CONFIG-gcc
+    CXX=$BH_HOST_CONFIG-g++
+    LD=$BH_HOST_CONFIG-ld
+    AR=$BH_HOST_CONFIG-ar
+    AS=$BH_HOST_CONFIG-as
+    RANLIB=$BH_HOST_CONFIG-ranlib
+    NM=$BH_HOST_CONFIG-nm
+    STRIP=$BH_HOST_CONFIG-strip
+    STRINGS=$BH_HOST_CONFIG-strings
+    export CC CXX LD AR AS RANLIB NM STRIP STRINGS
+
+    CFLAGS=
+    CXXFLAGS=
+    LDFLAGS=
+    case $BH_BUILD_MODE in
+        release)
+            CFLAGS="-O2 -Os -fomit-frame-pointer -s"
+            CXXFLAGS=$CFLAGS
+            ;;
+        debug)
+            CFLAGS="-O0 -g"
+            CXXFLAGS=$CFLAGS
+            ;;
+    esac
+    export CFLAGS CXXFLAGS LDFLAGS
+
+    export PATH=$BH_WRAPPERS_DIR:$PATH
+}
+
+_bh_option_no_color ()
+{
+    bh_set_color_mode off
+}
+
+# This function is used to register a few command-line options that
+# impact the build of host binaries. Call it before invoking
+# extract_parameters to add them automatically.
+#
+bh_register_options ()
+{
+    BH_HOST_SYSTEMS="$BH_BUILD_TAG"
+    register_var_option "--systems=<list>" BH_HOST_SYSTEMS "Build binaries that run on these systems."
+
+    _BH_OPTION_FORCE=
+    register_var_option "--force" _BH_OPTION_FORCE "Force rebuild."
+
+    _BH_OPTION_NO_STRIP=
+    register_var_option "--no-strip" _BH_OPTION_NO_STRIP "Don't strip generated binaries."
+
+    register_option "--no-color" _bh_option_no_color "Don't output colored text."
+
+    if [ "$HOST_OS" = darwin ]; then
+        DARWIN_SDK_VERSION=
+        register_var_option "--darwin-sdk-version=<version>" DARWIN_SDK "Select Darwin SDK version."
+
+        DARWIN_MIN_VERSION=
+        register_var_option "--darwin-min-version=<version>" DARWIN_MIN_VERSION "Select minimum OS X version of generated host toolchains."
+    fi
+}
+
+# Execute a given command.
+#
+# NOTE: The command is run in its own sub-shell to avoid environment
+#        contamination.
+#
+# $@: command
+bh_do ()
+{
+    ("$@")
+    fail_panic
+}
+
+# Return the build install directory of a given Python version
+#
+# $1: host system tag
+# $2: python version
+# The suffix of this has to match python_ndk_install_dir
+#  as I package them from the build folder, substituting
+#  the end part of python_build_install_dir matching
+#  python_ndk_install_dir with nothing.
+python_build_install_dir ()
+{
+    echo "$BH_BUILD_DIR/$1/install/host-tools"
+}
+
+# Same as python_build_install_dir, but for the final NDK installation
+# directory. Relative to $NDK_DIR.
+#
+# $1: host system tag
+python_ndk_install_dir ()
+{
+    echo "host-tools"
+}
diff --git a/build/tools/dev-cleanup.sh b/build/tools/dev-cleanup.sh
new file mode 100755
index 0000000..a826a06
--- /dev/null
+++ b/build/tools/dev-cleanup.sh
@@ -0,0 +1,90 @@
+#!/bin/bash
+#
+# Copyright (C) 2010 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.
+#
+# dev-cleanup.sh
+#
+# Remove any intermediate files (e.g. object files) from the development
+# directories.
+#
+. `dirname $0`/prebuilt-common.sh
+
+DIR=$ANDROID_NDK_ROOT
+
+if [ -f $DIR/RELEASE/TXT ]; then
+    echo "ERROR: You cannot run this script in a release directory !"
+    exit 1
+fi
+if [ ! -d $DIR/.git ] ; then
+    echo "ERROR: You must call this script in a development directory !"
+    exit 1
+fi
+
+# Remove generated directories
+rm -rf $DIR/platforms
+rm -rf $DIR/prebuilt
+
+# Remove prebuilt binaries
+rm -rf $DIR/$STLPORT_SUBDIR/libs
+rm -rf $DIR/$GABIXX_SUBDIR/libs
+for VERSION in $DEFAULT_GCC_VERSION_LIST; do
+    rm -rf $DIR/$GNUSTL_SUBDIR/$VERSION
+done
+rm -rf $DIR/$COMPILER_RT_SUBDIR/libs
+rm -rf $DIR/$GCCUNWIND_SUBDIR/libs
+rm -rf $DIR/$LIBCXX_SUBDIR/libs
+rm -rf $DIR/$SUPPORT_SUBDIR/libs
+
+clean_dir ()
+{
+    if [ -d "$1" ] ; then
+        echo "rm -rf $1"
+        rm -rf $1
+    fi
+}
+
+clean_file ()
+{
+    if [ -f "$1" ] ; then
+        echo "rm -f $1"
+        rm -f $1
+    fi
+}
+
+cleanup_project ()
+{
+    clean_dir  $1/obj
+    clean_dir  $1/libs
+    clean_dir  $1/bin
+    clean_dir  $1/gen
+    clean_file $1/build.xml
+    clean_file $1/local.properties
+}
+
+# Cleanup the tests
+DIR=$ANDROID_NDK_ROOT
+for PROJECT in $DIR/tests/build/*; do
+    cleanup_project $PROJECT
+done
+for PROJECT in $DIR/tests/device/*; do
+    cleanup_project $PROJECT
+done
+
+# Cleanup development/ndk
+DIR=`dirname $ANDROID_NDK_ROOT`/development/ndk
+if [ ! -d $DIR ] ; then
+    echo "WARNING: Development directory missing: $DIR"
+    exit 0
+fi
diff --git a/build/tools/dev-defaults.sh b/build/tools/dev-defaults.sh
new file mode 100644
index 0000000..9834ed7
--- /dev/null
+++ b/build/tools/dev-defaults.sh
@@ -0,0 +1,298 @@
+# Default values used by several dev-scripts.
+#
+
+# This script is imported while building the NDK, while running the tests, and
+# when running make-standalone-toolchain.sh. Check if we have our own platforms
+# tree (as we would in an installed NDK) first, and fall back to prebuilts/ndk.
+PLATFORMS_DIR=$ANDROID_NDK_ROOT/platforms
+if [ ! -d "$PLATFORMS_DIR" ]; then
+    PLATFORMS_DIR=$ANDROID_NDK_ROOT/../prebuilts/ndk/current/platforms
+fi
+API_LEVELS=$(ls $PLATFORMS_DIR | sed 's/android-//' | sort -n)
+
+# The latest API level is the last one in the list.
+LATEST_API_LEVEL=$(echo $API_LEVELS | awk '{ print $NF }')
+
+FIRST_API64_LEVEL=21
+
+# Default ABIs for the target prebuilt binaries.
+PREBUILT_ABIS="armeabi armeabi-v7a x86 mips arm64-v8a x86_64 mips64"
+
+# Location of the STLport sources, relative to the NDK root directory
+STLPORT_SUBDIR=sources/cxx-stl/stlport
+
+# Location of the GAbi++ sources, relative to the NDK root directory
+GABIXX_SUBDIR=sources/cxx-stl/gabi++
+
+# Location of the GNU libstdc++ headers and libraries, relative to the NDK
+# root directory.
+GNUSTL_SUBDIR=sources/cxx-stl/gnu-libstdc++
+
+# Location of the LLVM libc++ headers and libraries, relative to the NDK
+# root directory.
+LIBCXX_SUBDIR=sources/cxx-stl/llvm-libc++
+
+# Location of the LLVM libc++abi headers, relative to the NDK # root directory.
+LIBCXXABI_SUBDIR=sources/cxx-stl/llvm-libc++abi/libcxxabi
+
+# Location of the gccunwind sources, relative to the NDK root directory
+GCCUNWIND_SUBDIR=sources/android/gccunwind
+
+# Location of the support sources for libc++, relative to the NDK root directory
+SUPPORT_SUBDIR=sources/android/support
+
+# The date to use when downloading toolchain sources from AOSP servers
+# Leave it empty for tip of tree.
+TOOLCHAIN_GIT_DATE=now
+
+# The space-separated list of all GCC versions we support in this NDK
+DEFAULT_GCC_VERSION_LIST="4.9"
+
+DEFAULT_GCC32_VERSION=4.9
+DEFAULT_GCC64_VERSION=4.9
+FIRST_GCC32_VERSION=4.9
+FIRST_GCC64_VERSION=4.9
+DEFAULT_LLVM_GCC32_VERSION=4.9
+DEFAULT_LLVM_GCC64_VERSION=4.9
+
+DEFAULT_BINUTILS_VERSION=2.27
+DEFAULT_GDB_VERSION=7.11
+DEFAULT_MPFR_VERSION=3.1.1
+DEFAULT_GMP_VERSION=5.0.5
+DEFAULT_MPC_VERSION=1.0.1
+DEFAULT_CLOOG_VERSION=0.18.0
+DEFAULT_ISL_VERSION=0.11.1
+DEFAULT_PPL_VERSION=1.0
+DEFAULT_PYTHON_VERSION=2.7.5
+DEFAULT_PERL_VERSION=5.16.2
+
+# Default platform to build target binaries against.
+DEFAULT_PLATFORM=android-14
+
+# The list of default CPU architectures we support
+DEFAULT_ARCHS="arm x86 mips arm64 x86_64 mips64"
+
+# Default toolchain names and prefix
+#
+# This is used by get_default_toolchain_name_for_arch and get_default_toolchain_prefix_for_arch
+# defined below
+DEFAULT_ARCH_TOOLCHAIN_NAME_arm=arm-linux-androideabi
+DEFAULT_ARCH_TOOLCHAIN_PREFIX_arm=arm-linux-androideabi
+
+DEFAULT_ARCH_TOOLCHAIN_NAME_arm64=aarch64-linux-android
+DEFAULT_ARCH_TOOLCHAIN_PREFIX_arm64=aarch64-linux-android
+
+DEFAULT_ARCH_TOOLCHAIN_NAME_x86=x86
+DEFAULT_ARCH_TOOLCHAIN_PREFIX_x86=i686-linux-android
+
+DEFAULT_ARCH_TOOLCHAIN_NAME_x86_64=x86_64
+DEFAULT_ARCH_TOOLCHAIN_PREFIX_x86_64=x86_64-linux-android
+
+DEFAULT_ARCH_TOOLCHAIN_NAME_mips=mips64el-linux-android
+DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips=mips64el-linux-android
+
+DEFAULT_ARCH_TOOLCHAIN_NAME_mips64=mips64el-linux-android
+DEFAULT_ARCH_TOOLCHAIN_PREFIX_mips64=mips64el-linux-android
+
+# The build number of clang used to build pieces of the NDK (like platforms).
+DEFAULT_LLVM_VERSION="2455903"
+
+# The default URL to download the LLVM tar archive
+DEFAULT_LLVM_URL="http://llvm.org/releases"
+
+# The list of default host NDK systems we support
+DEFAULT_SYSTEMS="linux-x86 windows darwin-x86"
+
+# The default issue tracker URL
+DEFAULT_ISSUE_TRACKER_URL="http://source.android.com/source/report-bugs.html"
+
+# Return the default gcc version for a given architecture
+# $1: Architecture name (e.g. 'arm')
+# Out: default arch-specific gcc version
+get_default_gcc_version_for_arch ()
+{
+    case $1 in
+       *64) echo $DEFAULT_GCC64_VERSION ;;
+       *) echo $DEFAULT_GCC32_VERSION ;;
+    esac
+}
+
+# Return the first gcc version for a given architecture
+# $1: Architecture name (e.g. 'arm')
+# Out: default arch-specific gcc version
+get_first_gcc_version_for_arch ()
+{
+    case $1 in
+       *64) echo $FIRST_GCC64_VERSION ;;
+       *) echo $FIRST_GCC32_VERSION ;;
+    esac
+}
+
+# Return default NDK ABI for a given architecture name
+# $1: Architecture name
+# Out: ABI name
+get_default_abi_for_arch ()
+{
+    local RET
+    case $1 in
+        arm)
+            RET="armeabi"
+            ;;
+        arm64)
+            RET="arm64-v8a"
+            ;;
+        x86|x86_64|mips|mips64)
+            RET="$1"
+            ;;
+        mips32r6)
+            RET="mips"
+            ;;
+        *)
+            2> echo "ERROR: Unsupported architecture name: $1, use one of: arm arm64 x86 x86_64 mips mips64"
+            exit 1
+            ;;
+    esac
+    echo "$RET"
+}
+
+
+# Retrieve the list of default ABIs supported by a given architecture
+# $1: Architecture name
+# Out: space-separated list of ABI names
+get_default_abis_for_arch ()
+{
+    local RET
+    case $1 in
+        arm)
+            RET="armeabi armeabi-v7a"
+            ;;
+        arm64)
+            RET="arm64-v8a"
+            ;;
+        x86|x86_64|mips|mips32r6|mips64)
+            RET="$1"
+            ;;
+        *)
+            2> echo "ERROR: Unsupported architecture name: $1, use one of: arm arm64 x86 x86_64 mips mips64"
+            exit 1
+            ;;
+    esac
+    echo "$RET"
+}
+
+# Return toolchain name for given architecture and GCC version
+# $1: Architecture name (e.g. 'arm')
+# $2: optional, GCC version (e.g. '4.8')
+# Out: default arch-specific toolchain name (e.g. 'arm-linux-androideabi-$GCC_VERSION')
+# Return empty for unknown arch
+get_toolchain_name_for_arch ()
+{
+    if [ ! -z "$2" ] ; then
+        eval echo \"\${DEFAULT_ARCH_TOOLCHAIN_NAME_$1}-$2\"
+    else
+        eval echo \"\${DEFAULT_ARCH_TOOLCHAIN_NAME_$1}\"
+    fi
+}
+
+# Return the default toolchain name for a given architecture
+# $1: Architecture name (e.g. 'arm')
+# Out: default arch-specific toolchain name (e.g. 'arm-linux-androideabi-$GCCVER')
+# Return empty for unknown arch
+get_default_toolchain_name_for_arch ()
+{
+    local GCCVER=$(get_default_gcc_version_for_arch $1)
+    eval echo \"\${DEFAULT_ARCH_TOOLCHAIN_NAME_$1}-$GCCVER\"
+}
+
+# Return the default toolchain program prefix for a given architecture
+# $1: Architecture name
+# Out: default arch-specific toolchain prefix (e.g. arm-linux-androideabi)
+# Return empty for unknown arch
+get_default_toolchain_prefix_for_arch ()
+{
+    eval echo "\$DEFAULT_ARCH_TOOLCHAIN_PREFIX_$1"
+}
+
+# Get the list of all toolchain names for a given architecture
+# $1: architecture (e.g. 'arm')
+# $2: comma separated versions (optional)
+# Out: list of toolchain names for this arch (e.g. arm-linux-androideabi-4.8 arm-linux-androideabi-4.9)
+# Return empty for unknown arch
+get_toolchain_name_list_for_arch ()
+{
+    local PREFIX VERSION RET ADD FIRST_GCC_VERSION VERSIONS
+    PREFIX=$(eval echo \"\$DEFAULT_ARCH_TOOLCHAIN_NAME_$1\")
+    if [ -z "$PREFIX" ]; then
+        return 0
+    fi
+    RET=""
+    FIRST_GCC_VERSION=$(get_first_gcc_version_for_arch $1)
+    ADD=""
+    VERSIONS=$(commas_to_spaces $2)
+    if [ -z "$VERSIONS" ]; then
+        VERSIONS=$DEFAULT_GCC_VERSION_LIST
+    else
+        ADD="yes" # include everything we passed explicitly
+    fi
+    for VERSION in $VERSIONS; do
+        if [ -z "$ADD" -a "$VERSION" = "$FIRST_GCC_VERSION" ]; then
+            ADD="yes"
+        fi
+        if [ -z "$ADD" ]; then
+            continue
+        fi
+        RET=$RET" $PREFIX-$VERSION"
+    done
+    RET=${RET## }
+    echo "$RET"
+}
+
+# Return the binutils version to be used by default when
+# building a given version of GCC. This is needed to ensure
+# we use binutils-2.19 when building gcc-4.4.3 for ARM and x86,
+# and later binutils in other cases (mips, or gcc-4.6+).
+#
+# Note that technically, we could use latest binutils for all versions of
+# GCC, however, in NDK r7, we did build GCC 4.4.3 with binutils-2.20.1
+# and this resulted in weird C++ debugging bugs. For NDK r7b and higher,
+# binutils was reverted to 2.19, to ensure at least
+# feature/bug compatibility.
+#
+# $1: toolchain with version number (e.g. 'arm-linux-androideabi-4.8')
+#
+get_default_binutils_version_for_gcc ()
+{
+    echo "$DEFAULT_BINUTILS_VERSION"
+}
+
+# Return the binutils version to be used by default when
+# building a given version of llvm. For llvm-3.4 or later,
+# we use binutils-2.23+ to ensure the LLVMgold.so could be
+# built properly. For llvm-3.3, we use binutils-2.21 as default.
+#
+# $1: toolchain with version numer (e.g. 'llvm-3.3')
+#
+get_default_binutils_version_for_llvm ()
+{
+    echo "$DEFAULT_BINUTILS_VERSION"
+}
+
+# Return the gdb version to be used by default when building a given
+# version of GCC.
+#
+# $1: toolchain with version number (e.g. 'arm-linux-androideabi-4.8')
+#
+get_default_gdb_version_for_gcc ()
+{
+    echo "$DEFAULT_GDB_VERSION"
+}
+
+# Return the gdbserver version to be used by default when building a given
+# version of GCC.
+#
+# $1: toolchain with version number (e.g. 'arm-linux-androideabi-4.8')
+#
+get_default_gdbserver_version ()
+{
+    echo "$DEFAULT_GDB_VERSION"
+}
diff --git a/build/tools/gen-toolchain-wrapper.sh b/build/tools/gen-toolchain-wrapper.sh
new file mode 100755
index 0000000..a35257e
--- /dev/null
+++ b/build/tools/gen-toolchain-wrapper.sh
@@ -0,0 +1,186 @@
+#!/bin/bash
+#
+# Copyright (C) 2012 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.
+#
+#  This shell script is used to rebuild the gcc and toolchain binaries
+#  for the Android NDK.
+#
+
+PROGDIR=$(dirname "$0")
+. "$PROGDIR/prebuilt-common.sh"
+
+PROGRAM_PARAMETERS="<dst-dir>"
+PROGRAM_DESCRIPTION="\
+This script allows you to generate a 'wrapper toolchain', i.e. a set of
+simple scripts that act as toolchain binaries (e.g. my-cc, my-c++, my-ld,
+etc...) but call another installed toolchain instead, possibly with additional
+command-line options.
+
+For example, imagine we want a toolchain that generates 32-bit binaries while
+running on a 64-bit system, we could call this script as:
+
+   $PROGNAME --cflags="-m32" --cxxflags="-m32" --ldflags="-m32" /tmp/my-toolchain
+
+Then, this will create programs like:
+
+   /tmp/my-toolchain/my-cc
+   /tmp/my-toolchain/my-gcc
+   /tmp/my-toolchain/my-c++
+   /tmp/my-toolchain/my-g++
+   /tmp/my-toolchain/my-ld
+   ...
+
+Where the compilers and linkers will add the -m32 flag to the command-line before
+calling the host version of 'cc', 'gcc', etc...
+
+Generally speaking:
+
+  - The 'destination toolchain' is the one that will be called by the
+    generated wrapper script. It is identified by a 'destination prefix'
+    (e.g. 'x86_64-linux-gnu-', note the dash at the end).
+
+    If is empty by default, but can be changed with --dst-prefix=<prefix>
+
+  - The 'source prefix' is the prefix added to the generated toolchain scripts,
+    it is 'my-' by default, but can be changed with --src-prefix=<prefix>
+
+  - You can use --cflags, --cxxflags, --ldflags, etc... to add extra
+    command-line flags for the generated compiler, linker, etc.. scripts
+
+"
+
+DEFAULT_SRC_PREFIX="my-"
+DEFAULT_DST_PREFIX=""
+
+SRC_PREFIX=$DEFAULT_SRC_PREFIX
+register_var_option "--src-prefix=<prefix>" SRC_PREFIX "Set source toolchain prefix"
+
+DST_PREFIX=$DEFAULT_DST_PREFIX
+register_var_option "--dst-prefix=<prefix>" DST_PREFIX "Set destination toolchain prefix"
+
+EXTRA_CFLAGS=
+register_var_option "--cflags=<options>" EXTRA_CFLAGS "Add extra C compiler flags"
+
+EXTRA_CXXFLAGS=
+register_var_option "--cxxflags=<options>" EXTRA_CXXFLAGS "Add extra C++ compiler flags"
+
+EXTRA_LDFLAGS=
+register_var_option "--ldflags=<options>" EXTRA_LDFLAGS "Add extra linker flags"
+
+EXTRA_ASFLAGS=
+register_var_option "--asflags=<options>" EXTRA_ASFLAGS "Add extra assembler flags"
+
+EXTRA_ARFLAGS=
+register_var_option "--arflags=<options>" EXTRA_ARFLAGS "Add extra archiver flags"
+
+EXTRA_WINDRES_FLAGS=
+register_var_option "--windres-flags=<options>" EXTRA_WINDRES_FLAGS "Add extra windres flags"
+
+CCACHE=
+register_var_option "--ccache=<prefix>" CCACHE "Use ccache compiler driver"
+
+PROGRAMS="cc gcc c++ g++ cpp as ld ar ranlib strip strings nm objdump dlltool windres"
+register_var_option "--programs=<list>" PROGRAMS "List of programs to generate wrapper for"
+
+extract_parameters "$@"
+
+PROGRAMS=$(commas_to_spaces "$PROGRAMS")
+if [ -z "$PROGRAMS" ]; then
+    panic "Empty program list, nothing to do!"
+fi
+
+DST_DIR="$PARAMETERS"
+if [ -z "$DST_DIR" ]; then
+    panic "Please provide a destination directory as a parameter! See --help for details."
+fi
+
+mkdir -p "$DST_DIR"
+fail_panic "Could not create destination directory: $DST_DIR"
+
+# Check if mingw compiler has dlfcn.h
+# $1: mignw compiler
+#
+mingw_has_dlfcn_h ()
+{
+   local CC="$1"
+
+   if [ ! -f "$CC" ]; then
+       # compiler not found
+       return 1
+   fi
+   "$CC" -xc /dev/null -dM -E | grep -q MINGW
+   if [ $? != 0 ]; then
+       # not a mingw compiler
+       return 1
+   fi
+
+   "$CC" -xc -c /dev/null -include dlfcn.h -o /dev/null > /dev/null 2>&1
+}
+
+# Generate a small wrapper program
+#
+# $1: program name, without any prefix (e.g. gcc, g++, ar, etc..)
+# $2: source prefix (e.g. 'i586-mingw32msvc-')
+# $3: destination prefix (e.g. 'i586-px-mingw32msvc-')
+# $4: destination directory for the generate program
+#
+gen_wrapper_program ()
+{
+    local PROG="$1"
+    local SRC_PREFIX="$2"
+    local DST_PREFIX="$3"
+    local DST_FILE="$4/${SRC_PREFIX}$PROG"
+    local FLAGS=""
+    local LDFLAGS=""
+
+    case $PROG in
+      cc|gcc|cpp)
+          FLAGS=$FLAGS" $EXTRA_CFLAGS"
+          if mingw_has_dlfcn_h ${DST_PREFIX}$PROG; then
+              LDFLAGS="-ldl"
+          fi
+          ;;
+      c++|g++)
+          FLAGS=$FLAGS" $EXTRA_CXXFLAGS"
+          if mingw_has_dlfcn_h ${DST_PREFIX}$PROG; then
+              LDFLAGS="-ldl"
+          fi
+          ;;
+      ar) FLAGS=$FLAGS" $EXTRA_ARFLAGS";;
+      as) FLAGS=$FLAGS" $EXTRA_ASFLAGS";;
+      ld|ld.bfd|ld.gold) FLAGS=$FLAGS" $EXTRA_LDFLAGS";;
+      windres) FLAGS=$FLAGS" $EXTRA_WINDRES_FLAGS";;
+    esac
+
+    if [ -n "$CCACHE" ]; then
+        DST_PREFIX=$CCACHE" "$DST_PREFIX
+    fi
+
+    cat > "$DST_FILE" << EOF
+#!/bin/sh
+# Auto-generated, do not edit
+${DST_PREFIX}$PROG $FLAGS "\$@" $LDFLAGS
+EOF
+    chmod +x "$DST_FILE"
+    log "Generating: ${SRC_PREFIX}$PROG"
+}
+
+log "Generating toolchain wrappers in: $DST_DIR"
+
+for PROG in $PROGRAMS; do
+  gen_wrapper_program $PROG "$SRC_PREFIX" "$DST_PREFIX" "$DST_DIR"
+done
+
+log "Done!"
diff --git a/build/tools/make-standalone-toolchain.sh b/build/tools/make-standalone-toolchain.sh
new file mode 100755
index 0000000..3eface7
--- /dev/null
+++ b/build/tools/make-standalone-toolchain.sh
@@ -0,0 +1,164 @@
+#!/bin/bash
+# Copyright (C) 2010 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.
+#
+
+# Create a standalone toolchain package for Android.
+
+. `dirname $0`/prebuilt-common.sh
+
+PROGRAM_PARAMETERS=""
+PROGRAM_DESCRIPTION=\
+"Generate a customized Android toolchain installation that includes
+a working sysroot. The result is something that can more easily be
+used as a standalone cross-compiler, e.g. to run configure and
+make scripts."
+
+TOOLCHAIN_NAME=
+register_var_option "--toolchain=<name>" TOOLCHAIN_NAME "Specify toolchain name"
+
+do_option_use_llvm () {
+  true;
+}
+register_option "--use-llvm" do_option_use_llvm "No-op. Clang is always available."
+
+STL=gnustl
+register_var_option "--stl=<name>" STL "Specify C++ STL"
+
+ARCH=
+register_var_option "--arch=<name>" ARCH "Specify target architecture"
+
+# Grab the ABIs that match the architecture.
+ABIS=
+register_var_option "--abis=<list>" ABIS "No-op. Derived from --arch or --toolchain."
+
+NDK_DIR=
+register_var_option "--ndk-dir=<path>" NDK_DIR "Unsupported."
+
+PACKAGE_DIR=$TMPDIR
+register_var_option "--package-dir=<path>" PACKAGE_DIR "Place package file in <path>"
+
+INSTALL_DIR=
+register_var_option "--install-dir=<path>" INSTALL_DIR "Don't create package, install files to <path> instead."
+
+DRYRUN=
+register_var_option "--dryrun" DRYRUN "Unsupported."
+
+PLATFORM=
+register_option "--platform=<name>" do_platform "Specify target Android platform/API level." "android-14"
+do_platform () {
+    PLATFORM=$1;
+    if [ "$PLATFORM" = "android-L" ]; then
+        echo "WARNING: android-L is renamed as android-21"
+        PLATFORM=android-21
+    fi
+}
+
+FORCE=
+do_force () {
+    FORCE=true
+}
+register_option "--force" do_force "Remove existing install directory."
+
+extract_parameters "$@"
+
+if [ -n "$NDK_DIR" ]; then
+    dump "The --ndk-dir argument is no longer supported."
+    exit 1
+fi
+
+if [ -n "$DRYRUN" ]; then
+    dump "--dryrun is not supported."
+    exit 1
+fi
+
+# Check TOOLCHAIN_NAME
+ARCH_BY_TOOLCHAIN_NAME=
+if [ -n "$TOOLCHAIN_NAME" ]; then
+    case $TOOLCHAIN_NAME in
+        arm-*)
+            ARCH_BY_TOOLCHAIN_NAME=arm
+            ;;
+        x86-*)
+            ARCH_BY_TOOLCHAIN_NAME=x86
+            ;;
+        mipsel-*)
+            ARCH_BY_TOOLCHAIN_NAME=mips
+            ;;
+        aarch64-*)
+            ARCH_BY_TOOLCHAIN_NAME=arm64
+            ;;
+        x86_64-linux-android-*)
+            ARCH_BY_TOOLCHAIN_NAME=x86_64
+            TOOLCHAIN_NAME=$(echo "$TOOLCHAIN_NAME" | sed -e 's/-linux-android//')
+            echo "Auto-truncate: --toolchain=$TOOLCHAIN_NAME"
+            ;;
+        x86_64-*)
+            ARCH_BY_TOOLCHAIN_NAME=x86_64
+            ;;
+        mips64el-*)
+            ARCH_BY_TOOLCHAIN_NAME=mips64
+            ;;
+        *)
+            echo "Invalid toolchain $TOOLCHAIN_NAME"
+            exit 1
+            ;;
+    esac
+fi
+# Check ARCH
+if [ -z "$ARCH" ]; then
+    ARCH=$ARCH_BY_TOOLCHAIN_NAME
+    if [ -z "$ARCH" ]; then
+        ARCH=arm
+    fi
+    echo "Auto-config: --arch=$ARCH"
+fi
+
+# Install or Package
+FORCE_ARG=
+if [ -n "$INSTALL_DIR" ] ; then
+    INSTALL_ARG="--install-dir=$INSTALL_DIR"
+    INSTALL_LOCATION=$INSTALL_DIR
+    if [ "$FORCE" = "true" ]; then
+        FORCE_ARG="--force"
+    else
+        if [ -e "$INSTALL_DIR" ]; then
+            dump "Refusing to clobber existing install directory: $INSTALL_DIR.
+
+make-standalone-toolchain.sh used to install a new toolchain into an existing
+directory. This is not desirable, as it will not clean up any stale files. If
+you wish to remove the install directory before creation, pass --force."
+            exit 1
+        fi
+    fi
+else
+    INSTALL_ARG="--package-dir=$PACKAGE_DIR"
+fi
+
+PLATFORM_NUMBER=${PLATFORM#android-}
+if [ -n "$PLATFORM_NUMBER" ]; then
+  PLATFORM_ARG="--api $PLATFORM_NUMBER"
+else
+  PLATFORM_ARG=""
+fi
+
+run python `dirname $0`/make_standalone_toolchain.py \
+    --arch $ARCH $PLATFORM_ARG --stl $STL $INSTALL_ARG $FORCE_ARG
+fail_panic "Failed to create toolchain."
+
+if [ -n "$INSTALL_DIR" ]; then
+    dump "Toolchain installed to $INSTALL_DIR."
+else
+    dump "Package installed to $PACKAGE_DIR."
+fi
diff --git a/build/tools/make_standalone_toolchain.py b/build/tools/make_standalone_toolchain.py
new file mode 100755
index 0000000..daba335
--- /dev/null
+++ b/build/tools/make_standalone_toolchain.py
@@ -0,0 +1,666 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 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.
+#
+"""Creates a toolchain installation for a given Android target.
+
+The output of this tool is a more typical cross-compiling toolchain. It is
+indended to be used with existing build systems such as autotools.
+"""
+import argparse
+import atexit
+import inspect
+import logging
+import platform
+import os
+import shutil
+import stat
+import sys
+import tempfile
+import textwrap
+
+
+THIS_DIR = os.path.realpath(os.path.dirname(__file__))
+NDK_DIR = os.path.realpath(os.path.join(THIS_DIR, '../..'))
+
+
+def logger():
+    """Return the main logger for this module."""
+    return logging.getLogger(__name__)
+
+
+def check_ndk_or_die():
+    """Verify that our NDK installation is sane or die."""
+    checks = [
+        'build/core',
+        'prebuilt',
+        'platforms',
+        'toolchains',
+    ]
+
+    for check in checks:
+        check_path = os.path.join(NDK_DIR, check)
+        if not os.path.exists(check_path):
+            sys.exit('Failed sanity check: missing {}'.format(check_path))
+
+
+def get_triple(arch):
+    """Return the triple for the given architecture."""
+    return {
+        'arm': 'arm-linux-androideabi',
+        'arm64': 'aarch64-linux-android',
+        'x86': 'i686-linux-android',
+        'x86_64': 'x86_64-linux-android',
+    }[arch]
+
+
+def get_abis(arch):
+    """Return the ABIs supported for the given architecture."""
+    return {
+        'arm': ['armeabi-v7a'],
+        'arm64': ['arm64-v8a'],
+        'x86': ['x86'],
+        'x86_64': ['x86_64'],
+    }[arch]
+
+
+def get_host_tag_or_die():
+    """Return the host tag for this platform. Die if not supported."""
+    if platform.system() == 'Linux':
+        return 'linux-x86_64'
+    elif platform.system() == 'Darwin':
+        return 'darwin-x86_64'
+    elif platform.system() == 'Windows':
+        host_tag = 'windows-x86_64'
+        if not os.path.exists(os.path.join(NDK_DIR, 'prebuilt', host_tag)):
+            host_tag = 'windows'
+        return host_tag
+    sys.exit('Unsupported platform: ' + platform.system())
+
+
+def get_sysroot_path_or_die(arch, api_level):
+    """Return the sysroot path for our architecture and API level or die."""
+    platforms_root_path = os.path.join(NDK_DIR, 'platforms')
+    platform_path = os.path.join(
+        platforms_root_path, 'android-{}'.format(api_level))
+
+    if not os.path.exists(platform_path):
+        valid_platforms = os.listdir(platforms_root_path)
+        sys.exit('Could not find {}. Valid platforms:\n{}'.format(
+            platform_path, '\n'.join(valid_platforms)))
+
+    sysroot_path = os.path.join(platform_path, 'arch-' + arch)
+    if not os.path.exists(sysroot_path):
+        sys.exit('Could not find {}'.format(sysroot_path))
+
+    return sysroot_path
+
+
+def get_gcc_path_or_die(arch, host_tag):
+    """Return the GCC path for our host and architecture or die."""
+    toolchain = {
+        'arm': 'arm-linux-androideabi',
+        'arm64': 'aarch64-linux-android',
+        'x86': 'x86',
+        'x86_64': 'x86_64',
+    }[arch] + '-4.9'
+
+    gcc_toolchain_path = os.path.join(
+        NDK_DIR, 'toolchains', toolchain, 'prebuilt', host_tag)
+    if not os.path.exists(gcc_toolchain_path):
+        sys.exit('Could not find GCC/binutils: {}'.format(gcc_toolchain_path))
+    return gcc_toolchain_path
+
+
+def get_clang_path_or_die(host_tag):
+    """Return the Clang path for our host or die."""
+    clang_toolchain_path = os.path.join(
+        NDK_DIR, 'toolchains/llvm/prebuilt', host_tag)
+    if not os.path.exists(clang_toolchain_path):
+        sys.exit('Could not find Clang: {}'.format(clang_toolchain_path))
+    return clang_toolchain_path
+
+
+def copy_directory_contents(src, dst):
+    """Copies the contents of a directory, merging with the destination.
+
+    shutil.copytree requires that the destination does not exist. This function
+    behaves like `cp -r`. That is, it merges the source and destination
+    directories if appropriate.
+    """
+    for root, dirs, files in os.walk(src):
+        subdir = os.path.relpath(root, src)
+        dst_dir = os.path.join(dst, subdir)
+        if not os.path.exists(dst_dir):
+            os.makedirs(dst_dir)
+
+        # This makes sure we copy even empty directories. We don't actually
+        # need it, but for now it lets us diff between our result and the
+        # legacy tool.
+        for d in dirs:
+            d_path = os.path.join(root, d)
+            if os.path.islink(d_path):
+                linkto = os.readlink(d_path)
+                dst_file = os.path.join(dst_dir, d)
+                logger().debug('Symlinking %s to %s', dst_file, linkto)
+                os.symlink(linkto, dst_file)
+            else:
+                new_dir = os.path.join(dst_dir, d)
+                if not os.path.exists(new_dir):
+                    logger().debug('Making directory %s', new_dir)
+                    os.makedirs(new_dir)
+
+        for f in files:
+            src_file = os.path.join(root, f)
+            if os.path.islink(src_file):
+                linkto = os.readlink(src_file)
+                dst_file = os.path.join(dst_dir, f)
+                logger().debug('Symlinking %s to %s', dst_file, linkto)
+                os.symlink(linkto, dst_file)
+            else:
+                logger().debug('Copying %s', src_file)
+                shutil.copy2(src_file, dst_dir)
+
+
+def make_clang_scripts(install_dir, triple, api, windows):
+    """Creates Clang wrapper scripts.
+
+    The Clang in standalone toolchains historically was designed to be used as
+    a drop-in replacement for GCC for better compatibility with existing
+    projects. Since a large number of projects are not set up for cross
+    compiling (and those that are expect the GCC style), our Clang should
+    already know what target it is building for.
+
+    Create wrapper scripts that invoke Clang with `-target` and `--sysroot`
+    preset.
+    """
+    with open(os.path.join(install_dir, 'AndroidVersion.txt')) as version_file:
+        major, minor, _build = version_file.read().strip().split('.')
+
+    version_number = major + minor
+
+    exe = ''
+    if windows:
+        exe = '.exe'
+
+    bin_dir = os.path.join(install_dir, 'bin')
+    shutil.move(os.path.join(bin_dir, 'clang' + exe),
+                os.path.join(bin_dir, 'clang{}'.format(version_number) + exe))
+    shutil.move(os.path.join(bin_dir, 'clang++' + exe),
+                os.path.join(bin_dir, 'clang{}++'.format(
+                    version_number) + exe))
+
+    arch, os_name, env = triple.split('-')
+    if arch == 'arm':
+        arch = 'armv7a'  # Target armv7, not armv5.
+
+    target = '-'.join([arch, 'none', os_name, env])
+    common_flags = '-target {}'.format(target)
+    common_flags += ' -D__ANDROID_API__={}'.format(api)
+    if arch == 'i686':
+        common_flags += ' -mstackrealign'
+
+    unix_flags = common_flags
+    unix_flags += ' --sysroot `dirname $0`/../sysroot'
+
+    clang_path = os.path.join(install_dir, 'bin/clang')
+    with open(clang_path, 'w') as clang:
+        clang.write(textwrap.dedent("""\
+            #!/bin/bash
+            if [ "$1" != "-cc1" ]; then
+                `dirname $0`/clang{version} {flags} "$@"
+            else
+                # target/triple already spelled out.
+                `dirname $0`/clang{version} "$@"
+            fi
+        """.format(version=version_number, flags=unix_flags)))
+
+    mode = os.stat(clang_path).st_mode
+    os.chmod(clang_path, mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
+
+    clangpp_path = os.path.join(install_dir, 'bin/clang++')
+    with open(clangpp_path, 'w') as clangpp:
+        clangpp.write(textwrap.dedent("""\
+            #!/bin/bash
+            if [ "$1" != "-cc1" ]; then
+                `dirname $0`/clang{version}++ {flags} "$@"
+            else
+                # target/triple already spelled out.
+                `dirname $0`/clang{version}++ "$@"
+            fi
+        """.format(version=version_number, flags=unix_flags)))
+
+    mode = os.stat(clangpp_path).st_mode
+    os.chmod(clangpp_path, mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
+
+    shutil.copy2(os.path.join(install_dir, 'bin/clang'),
+                 os.path.join(install_dir, 'bin', triple + '-clang'))
+    shutil.copy2(os.path.join(install_dir, 'bin/clang++'),
+                 os.path.join(install_dir, 'bin', triple + '-clang++'))
+
+    if windows:
+        win_flags = common_flags
+        win_flags += ' --sysroot %_BIN_DIR%..\\sysroot'
+
+        for pp_suffix in ('', '++'):
+            exe_name = 'clang{}{}.exe'.format(version_number, pp_suffix)
+            clangbat_text = textwrap.dedent("""\
+                @echo off
+                setlocal
+                call :find_bin
+                if "%1" == "-cc1" goto :L
+
+                set "_BIN_DIR=" && %_BIN_DIR%{exe} {flags} %*
+                if ERRORLEVEL 1 exit /b 1
+                goto :done
+
+                :L
+                rem target/triple already spelled out.
+                set "_BIN_DIR=" && %_BIN_DIR%{exe} %*
+                if ERRORLEVEL 1 exit /b 1
+                goto :done
+
+                :find_bin
+                rem Accommodate a quoted arg0, e.g.: "clang"
+                rem https://github.com/android-ndk/ndk/issues/616
+                set _BIN_DIR=%~dp0
+                exit /b
+
+                :done
+            """.format(exe=exe_name, flags=win_flags))
+
+            for triple_prefix in ('', triple + '-'):
+                clangbat_path = os.path.join(
+                    install_dir, 'bin',
+                    '{}clang{}.cmd'.format(triple_prefix, pp_suffix))
+                with open(clangbat_path, 'w') as clangbat:
+                    clangbat.write(clangbat_text)
+
+
+def copy_gnustl_abi_headers(src_dir, dst_dir, gcc_ver, triple, abi,
+                            thumb=False):
+    """Copy the ABI specific headers for gnustl."""
+    abi_src_dir = os.path.join(
+        src_dir, 'libs', abi, 'include/bits')
+
+    # Most ABIs simply install to bits, but armeabi-v7a needs to be
+    # installed to armv7-a/bits.
+    bits_dst_dir = 'bits'
+    if thumb:
+        bits_dst_dir = os.path.join('thumb', bits_dst_dir)
+    if abi == 'armeabi-v7a':
+        bits_dst_dir = os.path.join('armv7-a', bits_dst_dir)
+    abi_dst_dir = os.path.join(
+        dst_dir, 'include/c++', gcc_ver, triple, bits_dst_dir)
+
+    shutil.copytree(abi_src_dir, abi_dst_dir)
+
+
+def get_src_libdir(src_dir, abi):
+    """Gets the ABI specific lib directory for an NDK project."""
+    return os.path.join(src_dir, 'libs', abi)
+
+
+def get_dest_libdir(dst_dir, triple, abi):
+    """Get the ABI specific library directory for the toolchain."""
+    libdir_name = 'lib'
+    if abi == 'x86_64':
+        # ARM64 isn't a real multilib target, so it's just installed to lib.
+        libdir_name = 'lib64'
+    dst_libdir = os.path.join(dst_dir, triple, libdir_name)
+    if abi.startswith('armeabi-v7a'):
+        dst_libdir = os.path.join(dst_libdir, 'armv7-a')
+    return dst_libdir
+
+
+def copy_gnustl_libs(src_dir, dst_dir, triple, abi, thumb=False):
+    """Copy the gnustl libraries to the toolchain."""
+    src_libdir = get_src_libdir(src_dir, abi)
+    dst_libdir = get_dest_libdir(dst_dir, triple, abi)
+    if thumb:
+        dst_libdir = os.path.join(dst_libdir, 'thumb')
+
+    logger().debug('Copying %s libs to %s', abi, dst_libdir)
+
+    if not os.path.exists(dst_libdir):
+        os.makedirs(dst_libdir)
+
+    shutil.copy2(os.path.join(src_libdir, 'libgnustl_shared.so'), dst_libdir)
+    shutil.copy2(os.path.join(src_libdir, 'libsupc++.a'), dst_libdir)
+
+    # Copy libgnustl_static.a to libstdc++.a since that's what the world
+    # expects. Can't do this reliably with libgnustl_shared.so because the
+    # SONAME is wrong.
+    shutil.copy2(os.path.join(src_libdir, 'libgnustl_static.a'),
+                 os.path.join(dst_libdir, 'libstdc++.a'))
+
+
+def copy_stlport_libs(src_dir, dst_dir, triple, abi, thumb=False):
+    """Copy the stlport libraries to the toolchain."""
+    src_libdir = get_src_libdir(src_dir, abi)
+    dst_libdir = get_dest_libdir(dst_dir, triple, abi)
+    if thumb:
+        dst_libdir = os.path.join(dst_libdir, 'thumb')
+
+    if not os.path.exists(dst_libdir):
+        os.makedirs(dst_libdir)
+
+    shutil.copy2(os.path.join(src_libdir, 'libstlport_shared.so'), dst_libdir)
+    shutil.copy2(os.path.join(src_libdir, 'libstlport_static.a'),
+                 os.path.join(dst_libdir, 'libstdc++.a'))
+
+
+def fix_linker_script(path):
+    """Remove libandroid_support from the given linker script.
+
+    See https://github.com/android-ndk/ndk/issues/672 or the comment in
+    copy_libcxx_libs for more details.
+    """
+    with open(path, 'r+') as script:
+        contents = script.read()
+        script.seek(0)
+        script.write(contents.replace('-landroid_support', ''))
+        script.truncate()
+
+
+def copy_libcxx_libs(src_dir, dst_dir, abi, api):
+    shutil.copy2(os.path.join(src_dir, 'libc++_shared.so'), dst_dir)
+    shutil.copy2(os.path.join(src_dir, 'libc++_static.a'), dst_dir)
+    if api < 21:
+        shutil.copy2(os.path.join(src_dir, 'libandroid_support.a'), dst_dir)
+    shutil.copy2(os.path.join(src_dir, 'libc++abi.a'), dst_dir)
+
+    if abi == 'armeabi-v7a':
+        shutil.copy2(os.path.join(src_dir, 'libunwind.a'), dst_dir)
+
+    # libc++ is different from the other STLs. It has a libc++.(a|so) that is a
+    # linker script which automatically pulls in the necessary libraries. This
+    # way users don't have to do `-lc++abi -lunwind -landroid_support` on their
+    # own.
+    #
+    # As with the other STLs, we still copy this as libstdc++.a so the compiler
+    # will pick it up by default.
+    #
+    # Unlike the other STLs, also copy libc++.so (another linker script) over
+    # as libstdc++.so.  Since it's a linker script, the linker will still get
+    # the right DT_NEEDED from the SONAME of the actual linked object.
+    #
+    # TODO(danalbert): We should add linker scripts for the other STLs too
+    # since it lets the user avoid the current mess of having to always
+    # manually add `-lstlport_shared` (or whichever STL).
+    shutil.copy2(os.path.join(src_dir, 'libc++.a'),
+                 os.path.join(dst_dir, 'libstdc++.a'))
+    shutil.copy2(os.path.join(src_dir, 'libc++.so'),
+                 os.path.join(dst_dir, 'libstdc++.so'))
+
+    # TODO: Find a better fix for r18.
+    # https://github.com/android-ndk/ndk/issues/672
+    # The linker scripts in the NDK distribution are not correct for LP32 API
+    # 21+. In this case, rewrite the linker script to not link
+    # libandroid_support. We do this rather than generating our own linker
+    # scripts to avoid issues of updating one template and forgetting the
+    # other.
+    if '64' not in abi and api >= 21:
+        fix_linker_script(os.path.join(dst_dir, 'libstdc++.a'))
+        fix_linker_script(os.path.join(dst_dir, 'libstdc++.so'))
+
+
+def create_toolchain(install_path, arch, api, gcc_path, clang_path,
+                     platforms_path, stl, host_tag):
+    """Create a standalone toolchain."""
+    copy_directory_contents(gcc_path, install_path)
+    copy_directory_contents(clang_path, install_path)
+    triple = get_triple(arch)
+    make_clang_scripts(
+        install_path, triple, api, host_tag.startswith('windows'))
+
+    sysroot = os.path.join(NDK_DIR, 'sysroot')
+    headers = os.path.join(sysroot, 'usr/include')
+    install_sysroot = os.path.join(install_path, 'sysroot')
+    install_headers = os.path.join(install_sysroot, 'usr/include')
+    os.makedirs(os.path.dirname(install_headers))
+    shutil.copytree(headers, install_headers)
+
+    arch_headers = os.path.join(sysroot, 'usr/include', triple)
+    copy_directory_contents(arch_headers, os.path.join(install_headers))
+
+    for lib_suffix in ('', '64'):
+        lib_path = os.path.join(platforms_path, 'usr/lib{}'.format(lib_suffix))
+        lib_install = os.path.join(
+            install_sysroot, 'usr/lib{}'.format(lib_suffix))
+        if os.path.exists(lib_path):
+            shutil.copytree(lib_path, lib_install)
+
+    static_lib_path = os.path.join(sysroot, 'usr/lib', triple)
+    static_lib_install = os.path.join(install_sysroot, 'usr/lib')
+    if arch == 'x86_64':
+        static_lib_install += '64'
+    copy_directory_contents(static_lib_path, static_lib_install)
+
+    prebuilt_path = os.path.join(NDK_DIR, 'prebuilt', host_tag)
+    copy_directory_contents(prebuilt_path, install_path)
+
+    gdbserver_path = os.path.join(
+        NDK_DIR, 'prebuilt', 'android-' + arch, 'gdbserver')
+    gdbserver_install = os.path.join(install_path, 'share', 'gdbserver')
+    shutil.copytree(gdbserver_path, gdbserver_install)
+
+    toolchain_lib_dir = os.path.join(gcc_path, 'lib/gcc', triple)
+    dirs = os.listdir(toolchain_lib_dir)
+    assert len(dirs) == 1
+    gcc_ver = dirs[0]
+
+    cxx_headers = os.path.join(install_path, 'include/c++', gcc_ver)
+
+    # Historically these were installed to the same directory as the C++
+    # headers, but with the updated libc++ we have copies of a lot of those
+    # headers in libc++ itself that we end up clobbering.
+    #
+    # This problem should go away with unified headers, but those aren't ready
+    # yet. For the time being, install the libandroid_support headers to a
+    # different builtin include path. usr/local/include seems to be the least
+    # objectionable option.
+    support_headers = os.path.join(install_path, 'sysroot/usr/local/include')
+
+    if stl == 'gnustl':
+        gnustl_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/gnu-libstdc++/4.9')
+        shutil.copytree(os.path.join(gnustl_dir, 'include'), cxx_headers)
+
+        for abi in get_abis(arch):
+            copy_gnustl_abi_headers(gnustl_dir, install_path, gcc_ver, triple,
+                                    abi)
+            copy_gnustl_libs(gnustl_dir, install_path, triple, abi)
+            if arch == 'arm':
+                copy_gnustl_abi_headers(gnustl_dir, install_path, gcc_ver,
+                                        triple, abi, thumb=True)
+                copy_gnustl_libs(gnustl_dir, install_path, triple, abi,
+                                 thumb=True)
+    elif stl == 'libc++':
+        libcxx_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/llvm-libc++')
+        libcxxabi_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/llvm-libc++abi')
+        copy_directory_contents(os.path.join(libcxx_dir, 'include'),
+                                cxx_headers)
+        if api < 21:
+            support_dir = os.path.join(NDK_DIR, 'sources/android/support')
+            copy_directory_contents(os.path.join(support_dir, 'include'),
+                                    support_headers)
+
+        # I have no idea why we need this, but the old one does it too.
+        copy_directory_contents(
+            os.path.join(libcxxabi_dir, 'include'),
+            os.path.join(install_path, 'include/llvm-libc++abi/include'))
+
+        headers = [
+            'cxxabi.h',
+            '__cxxabi_config.h',
+        ]
+        for header in headers:
+            shutil.copy2(
+                os.path.join(libcxxabi_dir, 'include', header),
+                os.path.join(cxx_headers, header))
+
+        for abi in get_abis(arch):
+            src_libdir = get_src_libdir(libcxx_dir, abi)
+            dest_libdir = get_dest_libdir(install_path, triple, abi)
+            copy_libcxx_libs(src_libdir, dest_libdir, abi, api)
+            if arch == 'arm':
+                thumb_libdir = os.path.join(dest_libdir, 'thumb')
+                copy_libcxx_libs(src_libdir, thumb_libdir, abi, api)
+    elif stl == 'stlport':
+        stlport_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/stlport')
+        gabixx_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/gabi++')
+
+        copy_directory_contents(
+            os.path.join(stlport_dir, 'stlport'), cxx_headers)
+
+        # Same as for libc++. Not sure why we have this extra directory, but
+        # keep the cruft for diff.
+        copy_directory_contents(
+            os.path.join(gabixx_dir, 'include'),
+            os.path.join(install_path, 'include/gabi++/include'))
+
+        headers = [
+            'cxxabi.h',
+            'unwind.h',
+            'unwind-arm.h',
+            'unwind-itanium.h',
+            'gabixx_config.h',
+        ]
+        for header in headers:
+            shutil.copy2(
+                os.path.join(gabixx_dir, 'include', header),
+                os.path.join(cxx_headers, header))
+
+        for abi in get_abis(arch):
+            copy_stlport_libs(stlport_dir, install_path, triple, abi)
+            if arch == 'arm':
+                copy_stlport_libs(stlport_dir, install_path, triple, abi,
+                                  thumb=True)
+    else:
+        raise ValueError(stl)
+
+    # Not needed for every STL, but the old one does this. Keep it for the sake
+    # of diff. Done at the end so copytree works.
+    cxx_target_headers = os.path.join(cxx_headers, triple)
+    if not os.path.exists(cxx_target_headers):
+        os.makedirs(cxx_target_headers)
+
+
+def parse_args():
+    """Parse command line arguments from sys.argv."""
+    parser = argparse.ArgumentParser(
+        description=inspect.getdoc(sys.modules[__name__]))
+
+    parser.add_argument(
+        '--arch', required=True,
+        choices=('arm', 'arm64', 'x86', 'x86_64'))
+    parser.add_argument(
+        '--api', type=int,
+        help='Target the given API version (example: "--api 24").')
+    parser.add_argument(
+        '--stl', choices=('gnustl', 'libc++', 'stlport'), default='libc++',
+        help='C++ STL to use.')
+
+    parser.add_argument(
+        '--force', action='store_true',
+        help='Remove existing installation directory if it exists.')
+    parser.add_argument(
+        '-v', '--verbose', action='count', help='Increase output verbosity.')
+
+    output_group = parser.add_mutually_exclusive_group()
+    output_group.add_argument(
+        '--package-dir', type=os.path.realpath, default=os.getcwd(),
+        help=('Build a tarball and install it to the given directory. If '
+              'neither --package-dir nor --install-dir is specified, a '
+              'tarball will be created and installed to the current '
+              'directory.'))
+    output_group.add_argument(
+        '--install-dir', type=os.path.realpath,
+        help='Install toolchain to the given directory instead of packaging.')
+
+    return parser.parse_args()
+
+
+def main():
+    """Program entry point."""
+    args = parse_args()
+
+    if args.verbose is None:
+        logging.basicConfig(level=logging.WARNING)
+    elif args.verbose == 1:
+        logging.basicConfig(level=logging.INFO)
+    elif args.verbose >= 2:
+        logging.basicConfig(level=logging.DEBUG)
+
+    if args.stl != 'libc++':
+        logger().warning(
+            '%s is deprecated and will be removed in the next release. '
+            'Please switch to libc++. See '
+            'https://developer.android.com/ndk/guides/cpp-support.html '
+            'for more information.',
+            args.stl)
+
+    check_ndk_or_die()
+
+    lp32 = args.arch in ('arm', 'x86')
+    min_api = 14 if lp32 else 21
+    api = args.api
+    if api is None:
+        logger().warning(
+            'Defaulting to target API %d (minimum supported target for %s)',
+            min_api, args.arch)
+        api = min_api
+    elif api < min_api:
+        sys.exit('{} is less than minimum platform for {} ({})'.format(
+            api, args.arch, min_api))
+
+    host_tag = get_host_tag_or_die()
+    triple = get_triple(args.arch)
+    sysroot_path = get_sysroot_path_or_die(args.arch, api)
+    gcc_path = get_gcc_path_or_die(args.arch, host_tag)
+    clang_path = get_clang_path_or_die(host_tag)
+
+    if args.install_dir is not None:
+        install_path = args.install_dir
+        if os.path.exists(install_path):
+            if args.force:
+                logger().info('Cleaning installation directory %s',
+                              install_path)
+                shutil.rmtree(install_path)
+            else:
+                sys.exit('Installation directory already exists. Use --force.')
+    else:
+        tempdir = tempfile.mkdtemp()
+        atexit.register(shutil.rmtree, tempdir)
+        install_path = os.path.join(tempdir, triple)
+
+    create_toolchain(install_path, args.arch, api, gcc_path, clang_path,
+                     sysroot_path, args.stl, host_tag)
+
+    if args.install_dir is None:
+        if host_tag.startswith('windows'):
+            package_format = 'zip'
+        else:
+            package_format = 'bztar'
+
+        package_basename = os.path.join(args.package_dir, triple)
+        shutil.make_archive(
+            package_basename, package_format,
+            root_dir=os.path.dirname(install_path),
+            base_dir=os.path.basename(install_path))
+
+
+if __name__ == '__main__':
+    main()
diff --git a/build/tools/ndk-ccache-g++.sh b/build/tools/ndk-ccache-g++.sh
new file mode 100755
index 0000000..795fd4c
--- /dev/null
+++ b/build/tools/ndk-ccache-g++.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+$NDK_CCACHE $NDK_CCACHE_CXX "$@"
diff --git a/build/tools/ndk-ccache-gcc.sh b/build/tools/ndk-ccache-gcc.sh
new file mode 100755
index 0000000..a9f88ce
--- /dev/null
+++ b/build/tools/ndk-ccache-gcc.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+$NDK_CCACHE $NDK_CCACHE_CC "$@"
diff --git a/build/tools/ndk-common.sh b/build/tools/ndk-common.sh
new file mode 100644
index 0000000..737e0e4
--- /dev/null
+++ b/build/tools/ndk-common.sh
@@ -0,0 +1,805 @@
+# Copyright (C) 2009 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.
+#
+
+# A collection of shell function definitions used by various build scripts
+# in the Android NDK (Native Development Kit)
+#
+
+# Get current script name into PROGNAME
+PROGNAME=`basename $0`
+
+if [ -z "$TMPDIR" ]; then
+    export TMPDIR=/tmp/ndk-$USER
+fi
+
+OS=`uname -s`
+if [ "$OS" == "Darwin" -a -z "$MACOSX_DEPLOYMENT_TARGET" ]; then
+    export MACOSX_DEPLOYMENT_TARGET="10.8"
+fi
+
+# Find the Android NDK root, assuming we are invoked from a script
+# within its directory structure.
+#
+# $1: Variable name that will receive the path
+# $2: Path of invoking script
+find_ndk_root ()
+{
+    # Try to auto-detect the NDK root by walking up the directory
+    # path to the current script.
+    local PROGDIR="`dirname \"$2\"`"
+    while [ -n "1" ] ; do
+        if [ -d "$PROGDIR/build/core" ] ; then
+            break
+        fi
+        if [ -z "$PROGDIR" -o "$PROGDIR" = '/' ] ; then
+            return 1
+        fi
+        PROGDIR="`cd \"$PROGDIR/..\" && pwd`"
+    done
+    eval $1="$PROGDIR"
+}
+
+# Put location of Android NDK into ANDROID_NDK_ROOT and
+# perform a tiny amount of sanity check
+#
+if [ -z "$ANDROID_NDK_ROOT" ] ; then
+    find_ndk_root ANDROID_NDK_ROOT "$0"
+    if [ $? != 0 ]; then
+        echo "Please define ANDROID_NDK_ROOT to point to the root of your"
+        echo "Android NDK installation."
+        exit 1
+    fi
+fi
+
+echo "$ANDROID_NDK_ROOT" | grep -q -e " "
+if [ $? = 0 ] ; then
+    echo "ERROR: The Android NDK installation path contains a space !"
+    echo "Please install to a different location."
+    exit 1
+fi
+
+if [ ! -d $ANDROID_NDK_ROOT ] ; then
+    echo "ERROR: Your ANDROID_NDK_ROOT variable does not point to a directory."
+    echo "ANDROID_NDK_ROOT=$ANDROID_NDK_ROOT"
+    exit 1
+fi
+
+if [ ! -f $ANDROID_NDK_ROOT/build/tools/ndk-common.sh ] ; then
+    echo "ERROR: Your ANDROID_NDK_ROOT does not contain a valid NDK build system."
+    echo "ANDROID_NDK_ROOT=$ANDROID_NDK_ROOT"
+    exit 1
+fi
+
+## Use DRYRUN to find out top-level commands.
+DRYRUN=${DRYRUN-no}
+
+## Logging support
+##
+VERBOSE=${VERBOSE-yes}
+
+dump ()
+{
+    echo "$@"
+}
+
+dump_n ()
+{
+    printf %s "$@"
+}
+
+log ()
+{
+    if [ "$VERBOSE" = "yes" ] ; then
+        echo "$@"
+    fi
+}
+
+log_n ()
+{
+    if [ "$VERBOSE" = "yes" ] ; then
+        printf %s "$@"
+    fi
+}
+
+run ()
+{
+    if [ "$DRYRUN" = "yes" ] ; then
+        echo "## SKIP COMMAND: $@"
+    elif [ "$VERBOSE" = "yes" ] ; then
+        echo "## COMMAND: $@"
+        "$@" 2>&1
+    else
+        "$@" > /dev/null 2>&1
+    fi
+}
+
+panic ()
+{
+    dump "ERROR: $@"
+    exit 1
+}
+
+fail_panic ()
+{
+    if [ $? != 0 ] ; then
+        dump "ERROR: $@"
+        exit 1
+    fi
+}
+
+fail_warning ()
+{
+    if [ $? != 0 ] ; then
+        dump "WARNING: $@"
+    fi
+}
+
+
+## Utilities
+##
+
+# Return the value of a given named variable
+# $1: variable name
+#
+# example:
+#    FOO=BAR
+#    BAR=ZOO
+#    echo `var_value $FOO`
+#    will print 'ZOO'
+#
+var_value ()
+{
+    # find a better way to do that ?
+    eval echo "$`echo $1`"
+}
+
+# convert to uppercase
+# assumes tr is installed on the platform ?
+#
+to_uppercase ()
+{
+    echo $1 | tr "[:lower:]" "[:upper:]"
+}
+
+## First, we need to detect the HOST CPU, because proper HOST_ARCH detection
+## requires platform-specific tricks.
+##
+HOST_EXE=""
+HOST_OS=`uname -s`
+HOST_ARCH=x86_64
+case "$HOST_OS" in
+    Darwin)
+        HOST_OS=darwin
+        ;;
+    Linux)
+        # note that building  32-bit binaries on x86_64 is handled later
+        HOST_OS=linux
+        ;;
+    FreeBsd)  # note: this is not tested
+        HOST_OS=freebsd
+        ;;
+    CYGWIN*|*_NT-*)
+        HOST_OS=windows
+        HOST_EXE=.exe
+        HOST_ARCH=`uname -m`
+        if [ "x$OSTYPE" = xcygwin ] ; then
+            HOST_OS=cygwin
+        fi
+        ;;
+esac
+
+log "HOST_OS=$HOST_OS"
+log "HOST_EXE=$HOST_EXE"
+log "HOST_ARCH=$HOST_ARCH"
+
+# at this point, the supported values for HOST_ARCH are:
+#   x86
+#   x86_64
+#
+# other values may be possible but haven't been tested
+#
+# at this point, the value of HOST_OS should be one of the following:
+#   linux
+#   darwin
+#    windows (MSys)
+#    cygwin
+#
+# Note that cygwin is treated as a special case because it behaves very differently
+# for a few things. Other values may be possible but have not been tested
+#
+
+# define HOST_TAG as a unique tag used to identify both the host OS and CPU
+# supported values are:
+#
+#   linux-x86_64
+#   darwin-x86_64
+#   windows
+#   windows-x86_64
+#
+# other values are possible but were not tested.
+#
+compute_host_tag ()
+{
+    HOST_TAG=${HOST_OS}-${HOST_ARCH}
+    # Special case for windows-x86 => windows
+    case $HOST_TAG in
+        windows-x86|cygwin-x86)
+            HOST_TAG="windows"
+            ;;
+        cygwin-x86_64)
+            HOST_TAG="windows-x86_64"
+            ;;
+    esac
+    log "HOST_TAG=$HOST_TAG"
+}
+
+compute_host_tag
+
+# Compute the number of host CPU cores an HOST_NUM_CPUS
+#
+case "$HOST_OS" in
+    linux)
+        HOST_NUM_CPUS=`cat /proc/cpuinfo | grep processor | wc -l`
+        ;;
+    darwin|freebsd)
+        HOST_NUM_CPUS=`sysctl -n hw.ncpu`
+        ;;
+    windows|cygwin)
+        HOST_NUM_CPUS=$NUMBER_OF_PROCESSORS
+        ;;
+    *)  # let's play safe here
+        HOST_NUM_CPUS=1
+esac
+
+log "HOST_NUM_CPUS=$HOST_NUM_CPUS"
+
+# If BUILD_NUM_CPUS is not already defined in your environment,
+# define it as the double of HOST_NUM_CPUS. This is used to
+# run Make commands in parralles, as in 'make -j$BUILD_NUM_CPUS'
+#
+if [ -z "$BUILD_NUM_CPUS" ] ; then
+    BUILD_NUM_CPUS=`expr $HOST_NUM_CPUS \* 2`
+fi
+
+log "BUILD_NUM_CPUS=$BUILD_NUM_CPUS"
+
+
+##  HOST TOOLCHAIN SUPPORT
+##
+
+# force the generation of 32-bit binaries on 64-bit systems
+#
+FORCE_32BIT=no
+force_32bit_binaries ()
+{
+    if [ "$HOST_ARCH" = x86_64 ] ; then
+        log "Forcing generation of 32-bit host binaries on $HOST_ARCH"
+        FORCE_32BIT=yes
+        HOST_ARCH=x86
+        log "HOST_ARCH=$HOST_ARCH"
+        compute_host_tag
+    fi
+}
+
+# On Windows, cygwin binaries will be generated by default, but
+# you can force mingw ones that do not link to cygwin.dll if you
+# call this function.
+#
+disable_cygwin ()
+{
+    if [ $HOST_OS = cygwin ] ; then
+        log "Disabling cygwin binaries generation"
+        CFLAGS="$CFLAGS -mno-cygwin"
+        LDFLAGS="$LDFLAGS -mno-cygwin"
+        HOST_OS=windows
+        compute_host_tag
+    fi
+}
+
+# Various probes are going to need to run a small C program
+mkdir -p $TMPDIR/tmp/tests
+
+TMPC=$TMPDIR/tmp/tests/test-$$.c
+TMPO=$TMPDIR/tmp/tests/test-$$.o
+TMPE=$TMPDIR/tmp/tests/test-$$$EXE
+TMPL=$TMPDIR/tmp/tests/test-$$.log
+
+# cleanup temporary files
+clean_temp ()
+{
+    rm -f $TMPC $TMPO $TMPL $TMPE
+}
+
+# cleanup temp files then exit with an error
+clean_exit ()
+{
+    clean_temp
+    exit 1
+}
+
+# this function will setup the compiler and linker and check that they work as advertised
+# note that you should call 'force_32bit_binaries' before this one if you want it to
+# generate 32-bit binaries on 64-bit systems (that support it).
+#
+setup_toolchain ()
+{
+    if [ -z "$CC" ] ; then
+        CC=gcc
+    fi
+    if [ -z "$CXX" ] ; then
+        CXX=g++
+    fi
+    if [ -z "$CXXFLAGS" ] ; then
+        CXXFLAGS="$CFLAGS"
+    fi
+    if [ -z "$LD" ] ; then
+        LD="$CC"
+    fi
+
+    log "Using '$CC' as the C compiler"
+
+    # check that we can compile a trivial C program with this compiler
+    mkdir -p $(dirname "$TMPC")
+    cat > $TMPC <<EOF
+int main(void) {}
+EOF
+
+    if [ "$FORCE_32BIT" = yes ] ; then
+        CC="$CC -m32"
+        CXX="$CXX -m32"
+        LD="$LD -m32"
+        compile
+        if [ $? != 0 ] ; then
+            # sometimes, we need to also tell the assembler to generate 32-bit binaries
+            # this is highly dependent on your GCC installation (and no, we can't set
+            # this flag all the time)
+            CFLAGS="$CFLAGS -Wa,--32"
+            compile
+        fi
+    fi
+
+    compile
+    if [ $? != 0 ] ; then
+        echo "your C compiler doesn't seem to work:"
+        cat $TMPL
+        clean_exit
+    fi
+    log "CC         : compiler check ok ($CC)"
+
+    # check that we can link the trivial program into an executable
+    link
+    if [ $? != 0 ] ; then
+        OLD_LD="$LD"
+        LD="$CC"
+        compile
+        link
+        if [ $? != 0 ] ; then
+            LD="$OLD_LD"
+            echo "your linker doesn't seem to work:"
+            cat $TMPL
+            clean_exit
+        fi
+    fi
+    log "Using '$LD' as the linker"
+    log "LD         : linker check ok ($LD)"
+
+    # check the C++ compiler
+    log "Using '$CXX' as the C++ compiler"
+
+    cat > $TMPC <<EOF
+#include <iostream>
+using namespace std;
+int main()
+{
+  cout << "Hello World!" << endl;
+  return 0;
+}
+EOF
+
+    compile_cpp
+    if [ $? != 0 ] ; then
+        echo "your C++ compiler doesn't seem to work"
+        cat $TMPL
+        clean_exit
+    fi
+
+    log "CXX        : C++ compiler check ok ($CXX)"
+
+    # XXX: TODO perform AR checks
+    AR=ar
+    ARFLAGS=
+}
+
+# try to compile the current source file in $TMPC into an object
+# stores the error log into $TMPL
+#
+compile ()
+{
+    log "Object     : $CC -o $TMPO -c $CFLAGS $TMPC"
+    $CC -o $TMPO -c $CFLAGS $TMPC 2> $TMPL
+}
+
+compile_cpp ()
+{
+    log "Object     : $CXX -o $TMPO -c $CXXFLAGS $TMPC"
+    $CXX -o $TMPO -c $CXXFLAGS $TMPC 2> $TMPL
+}
+
+# try to link the recently built file into an executable. error log in $TMPL
+#
+link()
+{
+    log "Link      : $LD -o $TMPE $TMPO $LDFLAGS"
+    $LD -o $TMPE $TMPO $LDFLAGS 2> $TMPL
+}
+
+# run a command
+#
+execute()
+{
+    log "Running: $*"
+    $*
+}
+
+# perform a simple compile / link / run of the source file in $TMPC
+compile_exec_run()
+{
+    log "RunExec    : $CC -o $TMPE $CFLAGS $TMPC"
+    compile
+    if [ $? != 0 ] ; then
+        echo "Failure to compile test program"
+        cat $TMPC
+        cat $TMPL
+        clean_exit
+    fi
+    link
+    if [ $? != 0 ] ; then
+        echo "Failure to link test program"
+        cat $TMPC
+        echo "------"
+        cat $TMPL
+        clean_exit
+    fi
+    $TMPE
+}
+
+pattern_match ()
+{
+    echo "$2" | grep -q -E -e "$1"
+}
+
+# Let's check that we have a working md5sum here
+check_md5sum ()
+{
+    A_MD5=`echo "A" | md5sum | cut -d' ' -f1`
+    if [ "$A_MD5" != "bf072e9119077b4e76437a93986787ef" ] ; then
+        echo "Please install md5sum on this machine"
+        exit 2
+    fi
+}
+
+# Find if a given shell program is available.
+# We need to take care of the fact that the 'which <foo>' command
+# may return either an empty string (Linux) or something like
+# "no <foo> in ..." (Darwin). Also, we need to redirect stderr
+# to /dev/null for Cygwin
+#
+# $1: variable name
+# $2: program name
+#
+# Result: set $1 to the full path of the corresponding command
+#         or to the empty/undefined string if not available
+#
+find_program ()
+{
+    local PROG RET
+    PROG=`which $2 2>/dev/null`
+    RET=$?
+    if [ $RET != 0 ]; then
+        PROG=
+    fi
+    eval $1=\"$PROG\"
+    return $RET
+}
+
+prepare_download ()
+{
+    find_program CMD_WGET wget
+    find_program CMD_CURL curl
+    find_program CMD_SCRP scp
+}
+
+find_pbzip2 ()
+{
+    if [ -z "$_PBZIP2_initialized" ] ; then
+        find_program PBZIP2 pbzip2
+        _PBZIP2_initialized="yes"
+    fi
+}
+
+# Download a file with either 'curl', 'wget' or 'scp'
+#
+# $1: source URL (e.g. http://foo.com, ssh://blah, /some/path)
+# $2: target file
+download_file ()
+{
+    # Is this HTTP, HTTPS or FTP ?
+    if pattern_match "^(http|https|ftp):.*" "$1"; then
+        if [ -n "$CMD_WGET" ] ; then
+            run $CMD_WGET -O $2 $1
+        elif [ -n "$CMD_CURL" ] ; then
+            run $CMD_CURL -o $2 $1
+        else
+            echo "Please install wget or curl on this machine"
+            exit 1
+        fi
+        return
+    fi
+
+    # Is this SSH ?
+    # Accept both ssh://<path> or <machine>:<path>
+    #
+    if pattern_match "^(ssh|[^:]+):.*" "$1"; then
+        if [ -n "$CMD_SCP" ] ; then
+            scp_src=`echo $1 | sed -e s%ssh://%%g`
+            run $CMD_SCP $scp_src $2
+        else
+            echo "Please install scp on this machine"
+            exit 1
+        fi
+        return
+    fi
+
+    # Is this a file copy ?
+    # Accept both file://<path> or /<path>
+    #
+    if pattern_match "^(file://|/).*" "$1"; then
+        cp_src=`echo $1 | sed -e s%^file://%%g`
+        run cp -f $cp_src $2
+        return
+    fi
+}
+
+# Form the relative path between from one abs path to another
+#
+# $1 : start path
+# $2 : end path
+#
+# From:
+# http://stackoverflow.com/questions/2564634/bash-convert-absolute-path-into-relative-path-given-a-current-directory
+relpath ()
+{
+    [ $# -ge 1 ] && [ $# -le 2 ] || return 1
+    current="${2:+"$1"}"
+    target="${2:-"$1"}"
+    [ "$target" != . ] || target=/
+    target="/${target##/}"
+    [ "$current" != . ] || current=/
+    current="${current:="/"}"
+    current="/${current##/}"
+    appendix="${target##/}"
+    relative=''
+    while appendix="${target#"$current"/}"
+        [ "$current" != '/' ] && [ "$appendix" = "$target" ]; do
+        if [ "$current" = "$appendix" ]; then
+            relative="${relative:-.}"
+            echo "${relative#/}"
+            return 0
+        fi
+        current="${current%/*}"
+        relative="$relative${relative:+/}.."
+    done
+    relative="$relative${relative:+${appendix:+/}}${appendix#/}"
+    echo "$relative"
+}
+
+# Pack a given archive
+#
+# $1: archive file path (including extension)
+# $2: source directory for archive content
+# $3+: list of files (including patterns), all if empty
+pack_archive ()
+{
+    local ARCHIVE="$1"
+    local SRCDIR="$2"
+    local SRCFILES
+    local TARFLAGS ZIPFLAGS
+    shift; shift;
+    if [ -z "$1" ] ; then
+        SRCFILES="*"
+    else
+        SRCFILES="$@"
+    fi
+    if [ "`basename $ARCHIVE`" = "$ARCHIVE" ] ; then
+        ARCHIVE="`pwd`/$ARCHIVE"
+    fi
+    mkdir -p `dirname $ARCHIVE`
+
+    TARFLAGS="--exclude='*.py[cod]' --exclude='*.swp' --exclude=.git --exclude=.gitignore -cf"
+    ZIPFLAGS="-x *.git* -x *.pyc -x *.pyo -0qr"
+    # Ensure symlinks are stored as is in zip files. for toolchains
+    # this can save up to 7 MB in the size of the final archive
+    #ZIPFLAGS="$ZIPFLAGS --symlinks"
+    case "$ARCHIVE" in
+        *.zip)
+            rm -f $ARCHIVE
+            (cd $SRCDIR && run zip $ZIPFLAGS "$ARCHIVE" $SRCFILES)
+            ;;
+        *.tar.bz2)
+            find_pbzip2
+            if [ -n "$PBZIP2" ] ; then
+                (cd $SRCDIR && run tar --use-compress-prog=pbzip2 $TARFLAGS "$ARCHIVE" $SRCFILES)
+            else
+                (cd $SRCDIR && run tar -j $TARFLAGS "$ARCHIVE" $SRCFILES)
+            fi
+            ;;
+        *)
+            panic "Unsupported archive format: $ARCHIVE"
+            ;;
+    esac
+}
+
+# Copy a directory, create target location if needed
+#
+# $1: source directory
+# $2: target directory location
+#
+copy_directory ()
+{
+    local SRCDIR="$1"
+    local DSTDIR="$2"
+    if [ ! -d "$SRCDIR" ] ; then
+        panic "Can't copy from non-directory: $SRCDIR"
+    fi
+    log "Copying directory: "
+    log "  from $SRCDIR"
+    log "  to $DSTDIR"
+    mkdir -p "$DSTDIR" && (cd "$SRCDIR" && 2>/dev/null tar cf - *) | (tar xf - -C "$DSTDIR")
+    fail_panic "Cannot copy to directory: $DSTDIR"
+}
+
+# Move a directory, create target location if needed
+#
+# $1: source directory
+# $2: target directory location
+#
+move_directory ()
+{
+    local SRCDIR="$1"
+    local DSTDIR="$2"
+    if [ ! -d "$SRCDIR" ] ; then
+        panic "Can't move from non-directory: $SRCDIR"
+    fi
+    log "Move directory: "
+    log "  from $SRCDIR"
+    log "  to $DSTDIR"
+    mkdir -p "$DSTDIR" && (mv "$SRCDIR"/* "$DSTDIR")
+    fail_panic "Cannot move to directory: $DSTDIR"
+}
+
+# This is the same than copy_directory(), but symlinks will be replaced
+# by the file they actually point to instead.
+copy_directory_nolinks ()
+{
+    local SRCDIR="$1"
+    local DSTDIR="$2"
+    if [ ! -d "$SRCDIR" ] ; then
+        panic "Can't copy from non-directory: $SRCDIR"
+    fi
+    log "Copying directory (without symlinks): "
+    log "  from $SRCDIR"
+    log "  to $DSTDIR"
+    mkdir -p "$DSTDIR" && (cd "$SRCDIR" && tar chf - *) | (tar xf - -C "$DSTDIR")
+    fail_panic "Cannot copy to directory: $DSTDIR"
+}
+
+# Copy certain files from one directory to another one
+# $1: source directory
+# $2: target directory
+# $3+: file list (including patterns)
+copy_file_list ()
+{
+    local SRCDIR="$1"
+    local DSTDIR="$2"
+    shift; shift;
+    if [ ! -d "$SRCDIR" ] ; then
+        panic "Cant' copy from non-directory: $SRCDIR"
+    fi
+    log "Copying file: $@"
+    log "  from $SRCDIR"
+    log "  to $DSTDIR"
+    mkdir -p "$DSTDIR" && (cd "$SRCDIR" && (echo $@ | tr ' ' '\n' | tar hcf - -T -)) | (tar xf - -C "$DSTDIR")
+    fail_panic "Cannot copy files to directory: $DSTDIR"
+}
+
+# Rotate a log file
+# If the given log file exist, add a -1 to the end of the file.
+# If older log files exist, rename them to -<n+1>
+# $1: log file
+# $2: maximum version to retain [optional]
+rotate_log ()
+{
+    # Default Maximum versions to retain
+    local MAXVER="5"
+    local LOGFILE="$1"
+    shift;
+    if [ ! -z "$1" ] ; then
+        local tmpmax="$1"
+        shift;
+        tmpmax=`expr $tmpmax + 0`
+        if [ $tmpmax -lt 1 ] ; then
+            panic "Invalid maximum log file versions '$tmpmax' invalid; defaulting to $MAXVER"
+        else
+            MAXVER=$tmpmax;
+        fi
+    fi
+
+    # Do Nothing if the log file does not exist
+    if [ ! -f "${LOGFILE}" ] ; then
+        return
+    fi
+
+    # Rename existing older versions
+    ver=$MAXVER
+    while [ $ver -ge 1 ]
+    do
+        local prev=$(( $ver - 1 ))
+        local old="-$prev"
+
+        # Instead of old version 0; use the original filename
+        if [ $ver -eq 1 ] ; then
+            old=""
+        fi
+
+        if [ -f "${LOGFILE}${old}" ] ; then
+            mv -f "${LOGFILE}${old}" "${LOGFILE}-${ver}"
+        fi
+
+        ver=$prev
+    done
+}
+
+# Dereference symlink
+# $1+: directories
+dereference_symlink ()
+{
+    local DIRECTORY SYMLINKS DIR FILE LINK
+    for DIRECTORY in "$@"; do
+        if [ -d "$DIRECTORY" ]; then
+            while true; do
+                # Find all symlinks in this directory.
+                SYMLINKS=`find $DIRECTORY -type l`
+                if [ -z "$SYMLINKS" ]; then
+                    break;
+                fi
+                # Iterate symlinks
+                for SYMLINK in $SYMLINKS; do
+                    if [ -L "$SYMLINK" ]; then
+                        DIR=`dirname "$SYMLINK"`
+                        FILE=`basename "$SYMLINK"`
+                        # Note that if `readlink $FILE` is also a link, we want to deal
+                        # with it in the next iteration.  There is potential infinite-loop
+                        # situation for cicular link doesn't exist in our case, though.
+                        (cd "$DIR" && \
+                         LINK=`readlink "$FILE"` && \
+                         test ! -L "$LINK" && \
+                         rm -f "$FILE" && \
+                         cp -a "$LINK" "$FILE")
+                    fi
+                done
+            done
+        fi
+    done
+}
diff --git a/build/tools/prebuilt-common.sh b/build/tools/prebuilt-common.sh
new file mode 100644
index 0000000..8ca6cc1
--- /dev/null
+++ b/build/tools/prebuilt-common.sh
@@ -0,0 +1,1481 @@
+# Common functions for all prebuilt-related scripts
+# This is included/sourced by other scripts
+#
+
+# ensure stable sort order
+export LC_ALL=C
+
+# NDK_BUILDTOOLS_PATH should point to the directory containing
+# this script. If it is not defined, assume that this is one of
+# the scripts in the same directory that sourced this file.
+#
+if [ -z "$NDK_BUILDTOOLS_PATH" ]; then
+    NDK_BUILDTOOLS_PATH=$(dirname $0)
+    if [ ! -f "$NDK_BUILDTOOLS_PATH/prebuilt-common.sh" ]; then
+        echo "INTERNAL ERROR: Please define NDK_BUILDTOOLS_PATH to point to \$NDK/build/tools"
+        exit 1
+    fi
+fi
+
+# Warn if /bin/sh isn't bash.
+if [ -z "$BASH_VERSION" ] ; then
+    echo "WARNING: The shell running this script isn't bash.  Although we try to avoid bashism in scripts, things can happen."
+fi
+
+NDK_BUILDTOOLS_ABSPATH=$(cd $NDK_BUILDTOOLS_PATH && pwd)
+
+. $NDK_BUILDTOOLS_PATH/ndk-common.sh
+. $NDK_BUILDTOOLS_PATH/dev-defaults.sh
+
+
+# Given an input string of the form <foo>-<bar>-<version>, where
+# <version> can be <major>.<minor>, extract <major>
+extract_version ()
+{
+    echo $1 | tr '-' '\n' | tail -1
+}
+
+# $1: versioned name (e.g. arm-linux-androideabi-4.8)
+# Out: major version (e.g. 4)
+#
+# Examples:  arm-linux-androideabi-4.4.3 -> 4
+#            gmp-0.81 -> 0
+#
+extract_major_version ()
+{
+    local RET=$(extract_version $1 | cut -d . -f 1)
+    RET=${RET:-0}
+    echo $RET
+}
+
+# Same as extract_major_version, but for the minor version number
+# $1: versioned named
+# Out: minor version
+#
+extract_minor_version ()
+{
+    local RET=$(extract_version $1 | cut -d . -f 2)
+    RET=${RET:-0}
+    echo $RET
+}
+
+# Compare two version numbers and only succeeds if the first one is
+# greater than or equal to the second one.
+#
+# $1: first version (e.g. 4.9)
+# $2: second version (e.g. 4.8)
+#
+# Example: version_is_at_least 4.9 4.8 --> success
+#
+version_is_at_least ()
+{
+    local A_MAJOR A_MINOR B_MAJOR B_MINOR
+    A_MAJOR=$(extract_major_version $1)
+    B_MAJOR=$(extract_major_version $2)
+
+    if [ $A_MAJOR -lt $B_MAJOR ]; then
+        return 1
+    elif [ $A_MAJOR -gt $B_MAJOR ]; then
+        return 0
+    fi
+
+    # We have A_MAJOR == B_MAJOR here
+
+    A_MINOR=$(extract_minor_version $1)
+    B_MINOR=$(extract_minor_version $2)
+
+    if [ $A_MINOR -lt $B_MINOR ]; then
+        return 1
+    else
+        return 0
+    fi
+}
+
+#====================================================
+#
+#  UTILITY FUNCTIONS
+#
+#====================================================
+
+# Return the maximum length of a series of strings
+#
+# Usage:  len=`max_length <string1> <string2> ...`
+#
+max_length ()
+{
+    echo "$@" | tr ' ' '\n' | awk 'BEGIN {max=0} {len=length($1); if (len > max) max=len} END {print max}'
+}
+
+# Translate dashes to underscores
+# Usage:  str=`dashes_to_underscores <values>`
+dashes_to_underscores ()
+{
+    echo "$@" | tr '-' '_'
+}
+
+# Translate underscores to dashes
+# Usage: str=`underscores_to_dashes <values>`
+underscores_to_dashes ()
+{
+    echo "$@" | tr '_' '-'
+}
+
+# Translate commas to spaces
+# Usage: str=`commas_to_spaces <list>`
+commas_to_spaces ()
+{
+    echo "$@" | tr ',' ' '
+}
+
+# Translate spaces to commas
+# Usage: list=`spaces_to_commas <string>`
+spaces_to_commas ()
+{
+    echo "$@" | tr ' ' ','
+}
+
+# Remove trailing path of a path
+# $1: path
+remove_trailing_slash () {
+    echo ${1%%/}
+}
+
+# Reverse a file path directory
+# foo -> .
+# foo/bar -> ..
+# foo/bar/zoo -> ../..
+reverse_path ()
+{
+    local path cur item
+    path=${1%%/} # remove trailing slash
+    cur="."
+    if [ "$path" != "." ] ; then
+        for item in $(echo "$path" | tr '/' ' '); do
+            cur="../$cur"
+        done
+    fi
+    echo ${cur%%/.}
+}
+
+# test_reverse_path ()
+# {
+#     rr=`reverse_path $1`
+#     if [ "$rr" != "$2" ] ; then
+#         echo "ERROR: reverse_path '$1' -> '$rr' (expected '$2')"
+#     fi
+# }
+#
+# test_reverse_path . .
+# test_reverse_path ./ .
+# test_reverse_path foo ..
+# test_reverse_path foo/ ..
+# test_reverse_path foo/bar ../..
+# test_reverse_path foo/bar/ ../..
+# test_reverse_path foo/bar/zoo ../../..
+# test_reverse_path foo/bar/zoo/ ../../..
+
+# Sort a space-separated list and remove duplicates
+# $1+: slist
+# Output: new slist
+sort_uniq ()
+{
+    local RET
+    RET=$(echo "$@" | tr ' ' '\n' | sort -u)
+    echo $RET
+}
+
+# Return the list of all regular files under a given directory
+# $1: Directory path
+# Output: list of files, relative to $1
+list_files_under ()
+{
+    if [ -d "$1" ]; then
+        (cd $1 && find . -type f | sed -e "s!./!!" | sort -u)
+    else
+        echo ""
+    fi
+}
+
+# Returns all words in text that do not match any of the pattern
+# $1: pattern
+# $2: text
+filter_out ()
+{
+    local PATTERN="$1"
+    local TEXT="$2"
+    for pat in $PATTERN; do
+        pat=$"${pat//\//\\/}"
+        TEXT=$(echo $TEXT | sed -e 's/'$pat' //g' -e 's/'$pat'$//g')
+    done
+    echo $TEXT
+}
+
+# Assign a value to a variable
+# $1: Variable name
+# $2: Value
+var_assign ()
+{
+    eval $1=\"$2\"
+}
+
+#====================================================
+#
+#  OPTION PROCESSING
+#
+#====================================================
+
+# We recognize the following option formats:
+#
+#  -f
+#  --flag
+#
+#  -s<value>
+#  --setting=<value>
+#
+
+# NOTE: We translate '-' into '_' when storing the options in global variables
+#
+
+OPTIONS=""
+OPTION_FLAGS=""
+OPTION_SETTINGS=""
+
+# Set a given option attribute
+# $1: option name
+# $2: option attribute
+# $3: attribute value
+#
+option_set_attr ()
+{
+    eval OPTIONS_$1_$2=\"$3\"
+}
+
+# Get a given option attribute
+# $1: option name
+# $2: option attribute
+#
+option_get_attr ()
+{
+    echo `var_value OPTIONS_$1_$2`
+}
+
+# Register a new option
+# $1: option
+# $2: small abstract for the option
+# $3: optional. default value
+#
+register_option_internal ()
+{
+    optlabel=
+    optname=
+    optvalue=
+    opttype=
+    while [ -n "1" ] ; do
+        # Check for something like --setting=<value>
+        echo "$1" | grep -q -E -e '^--[^=]+=<.+>$'
+        if [ $? = 0 ] ; then
+            optlabel=`expr -- "$1" : '\(--[^=]*\)=.*'`
+            optvalue=`expr -- "$1" : '--[^=]*=\(<.*>\)'`
+            opttype="long_setting"
+            break
+        fi
+
+        # Check for something like --flag
+        echo "$1" | grep -q -E -e '^--[^=]+$'
+        if [ $? = 0 ] ; then
+            optlabel="$1"
+            opttype="long_flag"
+            break
+        fi
+
+        # Check for something like -f<value>
+        echo "$1" | grep -q -E -e '^-[A-Za-z0-9]<.+>$'
+        if [ $? = 0 ] ; then
+            optlabel=`expr -- "$1" : '\(-.\).*'`
+            optvalue=`expr -- "$1" : '-.\(<.+>\)'`
+            opttype="short_setting"
+            break
+        fi
+
+        # Check for something like -f
+        echo "$1" | grep -q -E -e '^-.$'
+        if [ $? = 0 ] ; then
+            optlabel="$1"
+            opttype="short_flag"
+            break
+        fi
+
+        echo "ERROR: Invalid option format: $1"
+        echo "       Check register_option call"
+        exit 1
+    done
+
+    log "new option: type='$opttype' name='$optlabel' value='$optvalue'"
+
+    optname=`dashes_to_underscores $optlabel`
+    OPTIONS="$OPTIONS $optname"
+    OPTIONS_TEXT="$OPTIONS_TEXT $1"
+    option_set_attr $optname label "$optlabel"
+    option_set_attr $optname otype "$opttype"
+    option_set_attr $optname value "$optvalue"
+    option_set_attr $optname text "$1"
+    option_set_attr $optname abstract "$2"
+    option_set_attr $optname default "$3"
+}
+
+# Register a new option with a function callback.
+#
+# $1: option
+# $2: name of function that will be called when the option is parsed
+# $3: small abstract for the option
+# $4: optional. default value
+#
+register_option ()
+{
+    local optname optvalue opttype optlabel
+    register_option_internal "$1" "$3" "$4"
+    option_set_attr $optname funcname "$2"
+}
+
+# Register a new option with a variable store
+#
+# $1: option
+# $2: name of variable that will be set by this option
+# $3: small abstract for the option
+#
+# NOTE: The current value of $2 is used as the default
+#
+register_var_option ()
+{
+    local optname optvalue opttype optlabel
+    register_option_internal "$1" "$3" "`var_value $2`"
+    option_set_attr $optname varname "$2"
+}
+
+
+MINGW=no
+DARWIN=no
+do_mingw_option ()
+{
+    if [ "$DARWIN" = "yes" ]; then
+        echo "Can not have both --mingw and --darwin"
+        exit 1
+    fi
+    MINGW=yes;
+}
+do_darwin_option ()
+{
+    if [ "$MINGW" = "yes" ]; then
+        echo "Can not have both --mingw and --darwin"
+        exit 1
+    fi
+    DARWIN=yes; 
+}
+
+register_canadian_option ()
+{
+    if [ "$HOST_OS" = "linux" ] ; then
+        register_option "--mingw" do_mingw_option "Generate windows binaries on Linux."
+        register_option "--darwin" do_darwin_option "Generate darwin binaries on Linux."
+    fi
+}
+
+TRY64=no
+do_try64_option () { TRY64=yes; }
+
+register_try64_option ()
+{
+    register_option "--try-64" do_try64_option "Generate 64-bit only binaries."
+}
+
+
+register_jobs_option ()
+{
+    NUM_JOBS=$BUILD_NUM_CPUS
+    register_var_option "-j<number>" NUM_JOBS "Use <number> parallel build jobs"
+}
+
+# Print the help, including a list of registered options for this program
+# Note: Assumes PROGRAM_PARAMETERS and PROGRAM_DESCRIPTION exist and
+#       correspond to the parameters list and the program description
+#
+print_help ()
+{
+    local opt text abstract default
+
+    echo "Usage: $PROGNAME [options] $PROGRAM_PARAMETERS"
+    echo ""
+    if [ -n "$PROGRAM_DESCRIPTION" ] ; then
+        echo "$PROGRAM_DESCRIPTION"
+        echo ""
+    fi
+    echo "Valid options (defaults are in brackets):"
+    echo ""
+
+    maxw=`max_length "$OPTIONS_TEXT"`
+    AWK_SCRIPT=`echo "{ printf \"%-${maxw}s\", \\$1 }"`
+    for opt in $OPTIONS; do
+        text=`option_get_attr $opt text | awk "$AWK_SCRIPT"`
+        abstract=`option_get_attr $opt abstract`
+        default=`option_get_attr $opt default`
+        if [ -n "$default" ] ; then
+            echo "  $text     $abstract [$default]"
+        else
+            echo "  $text     $abstract"
+        fi
+    done
+    echo ""
+}
+
+option_panic_no_args ()
+{
+    echo "ERROR: Option '$1' does not take arguments. See --help for usage."
+    exit 1
+}
+
+option_panic_missing_arg ()
+{
+    echo "ERROR: Option '$1' requires an argument. See --help for usage."
+    exit 1
+}
+
+extract_parameters ()
+{
+    local opt optname otype value name fin funcname
+    PARAMETERS=""
+    while [ -n "$1" ] ; do
+        # If the parameter does not begin with a dash
+        # it is not an option.
+        param=`expr -- "$1" : '^\([^\-].*\)$'`
+        if [ -n "$param" ] ; then
+            if [ -z "$PARAMETERS" ] ; then
+                PARAMETERS="$1"
+            else
+                PARAMETERS="$PARAMETERS $1"
+            fi
+            shift
+            continue
+        fi
+
+        while [ -n "1" ] ; do
+            # Try to match a long setting, i.e. --option=value
+            opt=`expr -- "$1" : '^\(--[^=]*\)=.*$'`
+            if [ -n "$opt" ] ; then
+                otype="long_setting"
+                value=`expr -- "$1" : '^--[^=]*=\(.*\)$'`
+                break
+            fi
+
+            # Try to match a long flag, i.e. --option
+            opt=`expr -- "$1" : '^\(--.*\)$'`
+            if [ -n "$opt" ] ; then
+                otype="long_flag"
+                value="yes"
+                break
+            fi
+
+            # Try to match a short setting, i.e. -o<value>
+            opt=`expr -- "$1" : '^\(-[A-Za-z0-9]\)..*$'`
+            if [ -n "$opt" ] ; then
+                otype="short_setting"
+                value=`expr -- "$1" : '^-.\(.*\)$'`
+                break
+            fi
+
+            # Try to match a short flag, i.e. -o
+            opt=`expr -- "$1" : '^\(-.\)$'`
+            if [ -n "$opt" ] ; then
+                otype="short_flag"
+                value="yes"
+                break
+            fi
+
+            echo "ERROR: Unknown option '$1'. Use --help for list of valid values."
+            exit 1
+        done
+
+        #echo "Found opt='$opt' otype='$otype' value='$value'"
+
+        name=`dashes_to_underscores $opt`
+        found=0
+        for xopt in $OPTIONS; do
+            if [ "$name" != "$xopt" ] ; then
+                continue
+            fi
+            # Check that the type is correct here
+            #
+            # This also allows us to handle -o <value> as -o<value>
+            #
+            xotype=`option_get_attr $name otype`
+            if [ "$otype" != "$xotype" ] ; then
+                case "$xotype" in
+                "short_flag")
+                    option_panic_no_args $opt
+                    ;;
+                "short_setting")
+                    if [ -z "$2" ] ; then
+                        option_panic_missing_arg $opt
+                    fi
+                    value="$2"
+                    shift
+                    ;;
+                "long_flag")
+                    option_panic_no_args $opt
+                    ;;
+                "long_setting")
+                    option_panic_missing_arg $opt
+                    ;;
+                esac
+            fi
+            found=1
+            break
+            break
+        done
+        if [ "$found" = "0" ] ; then
+            echo "ERROR: Unknown option '$opt'. See --help for usage."
+            exit 1
+        fi
+        # Set variable or launch option-specific function.
+        varname=`option_get_attr $name varname`
+        if [ -n "$varname" ] ; then
+            eval ${varname}=\"$value\"
+        else
+            eval `option_get_attr $name funcname` \"$value\"
+        fi
+        shift
+    done
+}
+
+do_option_help ()
+{
+    print_help
+    exit 0
+}
+
+VERBOSE=no
+do_option_verbose ()
+{
+    VERBOSE=yes
+}
+
+DRYRUN=no
+do_option_dryrun ()
+{
+    DRYRUN=yes
+}
+
+register_option "--help"          do_option_help     "Print this help."
+register_option "--verbose"       do_option_verbose  "Enable verbose mode."
+register_option "--dryrun"        do_option_dryrun   "Set to dryrun mode."
+
+#====================================================
+#
+#  TOOLCHAIN AND ABI PROCESSING
+#
+#====================================================
+
+# Determine optional variable value
+# $1: final variable name
+# $2: option variable name
+# $3: small description for the option
+fix_option ()
+{
+    if [ -n "$2" ] ; then
+        eval $1="$2"
+        log "Using specific $3: $2"
+    else
+        log "Using default $3: `var_value $1`"
+    fi
+}
+
+
+# If SYSROOT is empty, check that $1/$2 contains a sysroot
+# and set the variable to it.
+#
+# $1: sysroot path
+# $2: platform/arch suffix
+check_sysroot ()
+{
+    if [ -z "$SYSROOT" ] ; then
+        log "Probing directory for sysroot: $1/$2"
+        if [ -d $1/$2 ] ; then
+            SYSROOT=$1/$2
+        fi
+    fi
+}
+
+# Determine sysroot
+# $1: Option value (or empty)
+#
+fix_sysroot ()
+{
+    if [ -n "$1" ] ; then
+        eval SYSROOT="$1"
+        log "Using specified sysroot: $1"
+    else
+        SYSROOT_SUFFIX=$PLATFORM/arch-$ARCH
+        SYSROOT=
+        check_sysroot $ANDROID_BUILD_TOP/prebuilts/ndk/current/platforms $SYSROOT_SUFFIX
+        check_sysroot $ANDROID_NDK_ROOT/platforms $SYSROOT_SUFFIX
+        check_sysroot `dirname $ANDROID_NDK_ROOT`/development/ndk/platforms $SYSROOT_SUFFIX
+
+        if [ -z "$SYSROOT" ] ; then
+            echo "ERROR: Could not find NDK sysroot path for $SYSROOT_SUFFIX."
+            echo "       Use --sysroot=<path> to specify one."
+            exit 1
+        fi
+    fi
+
+    if [ ! -f $SYSROOT/usr/include/stdlib.h ] ; then
+        echo "ERROR: Invalid sysroot path: $SYSROOT"
+        echo "       Use --sysroot=<path> to indicate a valid one."
+        exit 1
+    fi
+}
+
+# Check for the availability of a compatibility SDK in Darwin
+# this can be used to generate binaries compatible with either Tiger or
+# Leopard.
+#
+# $1: SDK root path
+# $2: Optional MacOS X minimum version (e.g. 10.5)
+DARWIN_MINVER=10.6
+check_darwin_sdk ()
+{
+    local MACSDK="$1"
+    local MINVER=$2
+
+    if [ -z "$MINVER" ] ; then
+        # expect SDK root path ended up with either MacOSX##.#.sdk or MacOSX##.#u.sdk
+        MINVER=${MACSDK##*MacOSX}
+        MINVER=${MINVER%%.sdk*}
+        if [ "$MINVER" = "10.4u" ]; then
+            MINVER=10.4
+        fi
+    fi
+    if [ -d "$MACSDK" ] ; then
+        HOST_CFLAGS=$HOST_CFLAGS" -isysroot $MACSDK -mmacosx-version-min=$MINVER -DMAXOSX_DEPLOYEMENT_TARGET=$MINVER"
+        HOST_LDFLAGS=$HOST_LDFLAGS" -Wl,-syslibroot,$MACSDK -mmacosx-version-min=$MINVER"
+        DARWIN_MINVER=$MINVER
+        return 0  # success
+    fi
+    return 1
+}
+
+# Probe Darwin SDK in specified diectory $DARWIN_SYSROOT, or
+# /Developer/SDKs/MacOSX10.6.sdk
+#
+probe_darwin_sdk ()
+{
+    if [ -n "$DARWIN_SYSROOT" ]; then
+        if check_darwin_sdk "$DARWIN_SYSROOT"; then
+            log "Use darwin sysroot $DARWIN_SYSROOT"
+        else
+            echo "darwin sysroot $DARWIN_SYSROOT is not valid"
+            exit 1
+        fi
+    elif check_darwin_sdk /Developer/SDKs/MacOSX10.6.sdk 10.6; then
+        log "Generating Snow Leopard-compatible binaries!"
+    else
+        local version=`sw_vers -productVersion`
+        log "Generating $version-compatible binaries!"
+    fi
+}
+
+handle_canadian_build ()
+{
+    HOST_EXE=
+    if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then
+        case $HOST_TAG in
+            linux-*)
+                ;;
+            *)
+                echo "ERROR: Can only enable --mingw or --darwin on Linux platforms !"
+                exit 1
+                ;;
+        esac
+        if [ "$MINGW" = "yes" ] ; then
+            if [ "$TRY64" = "yes" ]; then
+                ABI_CONFIGURE_HOST=x86_64-w64-mingw32
+                HOST_TAG=windows-x86_64
+            else
+                # NOTE: A wrapper is generated for i686-w64-mingw32.
+                ABI_CONFIGURE_HOST=i686-w64-mingw32
+                HOST_TAG=windows
+            fi
+            HOST_OS=windows
+            HOST_EXE=.exe
+        else
+            if [ "$TRY64" = "yes" ]; then
+                ABI_CONFIGURE_HOST=x86_64-apple-darwin
+                HOST_TAG=darwin-x86_64
+            else
+                ABI_CONFIGURE_HOST=i686-apple-darwin
+                HOST_TAG=darwin-x86
+            fi
+            HOST_OS=darwin
+        fi
+    fi
+}
+
+# Find mingw toolchain
+#
+# Set MINGW_GCC to the found mingw toolchain
+#
+find_mingw_toolchain ()
+{
+    local LINUX_GCC_PREBUILTS=$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86
+    local MINGW_ROOT=$LINUX_GCC_PREBUILTS/host/x86_64-w64-mingw32-4.8/
+    BINPREFIX=x86_64-w64-mingw32-
+    MINGW_GCC=$MINGW_ROOT/bin/${BINPREFIX}gcc
+    if [ ! -e "$MINGW_GCC" ]; then
+        panic "$MINGW_GCC does not exist"
+    fi
+
+    if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then
+        DEBIAN_NAME=mingw-w64
+    else
+        # we are trying 32 bit anyway, so forcing it to avoid build issues
+        force_32bit_binaries
+        DEBIAN_NAME=mingw-w64
+    fi
+}
+
+# Check there is a working cross-toolchain installed.
+#
+# $1: install directory for mingw/darwin wrapper toolchain
+#
+# NOTE: Build scripts need to call this function to create MinGW wrappers,
+# even if they aren't doing a "Canadian" cross-compile with different build,
+# host, and target systems.
+#
+prepare_canadian_toolchain ()
+{
+    if [ "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then
+        return
+    fi
+    CROSS_GCC=
+    if [ "$MINGW" = "yes" ]; then
+        find_mingw_toolchain
+        CROSS_GCC=$MINGW_GCC
+    else
+        if [ -z "$DARWIN_TOOLCHAIN" ]; then
+            echo "Please set DARWIN_TOOLCHAIN to darwin cross-toolchain"
+            exit 1
+        fi
+        if [ ! -f "${DARWIN_TOOLCHAIN}-gcc" ]; then
+            echo "darwin cross-toolchain $DARWIN_TOOLCHAIN-gcc doesn't exist"
+            exit 1
+        fi
+        if [ "$HOST_ARCH" = "x86_64" -a "$TRY64" = "yes" ]; then
+            BINPREFIX=x86_64-apple-darwin-
+            DEBIAN_NAME=darwin64
+            HOST_CFLAGS=$HOST_CFLAGS" -m64"
+        else
+            force_32bit_binaries
+            BINPREFIX=i686-apple-darwin-
+            DEBIAN_NAME=darwin32
+            HOST_CFLAGS=$HOST_CFLAGS" -m32"
+        fi
+        CROSS_GCC=${DARWIN_TOOLCHAIN}-gcc
+        probe_darwin_sdk
+    fi
+
+    # Create a wrapper toolchain, and prepend its dir to our PATH
+    CROSS_WRAP_DIR="$1"/$DEBIAN_NAME-wrapper
+    rm -rf "$CROSS_WRAP_DIR"
+    mkdir -p "$CROSS_WRAP_DIR"
+
+    if [ "$DARWIN" = "yes" ] ; then
+        cat > "$CROSS_WRAP_DIR/sw_vers" <<EOF
+#!/bin/sh
+# Tiny utility for the real sw_vers some Makefiles need
+case \$1 in
+    -productVersion)
+        echo $DARWIN_MINVER
+        ;;
+    *)
+        echo "ERROR: Unknown switch \$1"
+        exit 1
+esac
+EOF
+    chmod 0755 "$CROSS_WRAP_DIR/sw_vers"
+    fi
+
+    DST_PREFIX=${CROSS_GCC%gcc}
+    if [ "$NDK_CCACHE" ]; then
+        DST_PREFIX="$NDK_CCACHE $DST_PREFIX"
+    fi
+    $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=$BINPREFIX --dst-prefix="$DST_PREFIX" "$CROSS_WRAP_DIR" \
+        --cflags="$HOST_CFLAGS" --cxxflags="$HOST_CFLAGS" --ldflags="$HOST_LDFLAGS"
+    # generate wrappers for BUILD toolchain
+    # this is required for mingw/darwin build to avoid tools canadian cross configuration issues
+    # 32-bit BUILD toolchain
+    LEGACY_TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8"
+    $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-linux-gnu- \
+            --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \
+            --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR"
+    $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i386-pc-linux-gnu- \
+            --cflags="-m32" --cxxflags="-m32" --ldflags="-m elf_i386" --asflags="--32" \
+            --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR"
+    # 64-bit BUILD toolchain.  libbfd is still built in 32-bit.
+    $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-linux-gnu- \
+            --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR"
+    $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=x86_64-pc-linux-gnu- \
+            --dst-prefix="$LEGACY_TOOLCHAIN_DIR/bin/x86_64-linux-" "$CROSS_WRAP_DIR"
+    fail_panic "Could not create $DEBIAN_NAME wrapper toolchain in $CROSS_WRAP_DIR"
+
+    # 32-bit Windows toolchain (i686-w64-mingw32 -> x86_64-w64-mingw32 -m32)
+    local MINGW_TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8"
+    $NDK_BUILDTOOLS_PATH/gen-toolchain-wrapper.sh --src-prefix=i686-w64-mingw32- \
+            --cflags="-m32" --cxxflags="-m32" --ldflags="-m i386pe" --asflags="--32" \
+            --windres-flags="-F pe-i386" \
+            --dst-prefix="$MINGW_TOOLCHAIN_DIR/bin/x86_64-w64-mingw32-" "$CROSS_WRAP_DIR"
+
+    export PATH=$CROSS_WRAP_DIR:$PATH
+    dump "Using $DEBIAN_NAME wrapper: $CROSS_WRAP_DIR/${BINPREFIX}gcc"
+}
+
+handle_host ()
+{
+    if [ "$TRY64" != "yes" ]; then
+        force_32bit_binaries  # to modify HOST_TAG and others
+        HOST_BITS=32
+    fi
+    handle_canadian_build
+}
+
+setup_ccache ()
+{
+    # Support for ccache compilation
+    # We can't use this here when building Windows/darwin binaries on Linux with
+    # binutils 2.21, because defining CC/CXX in the environment makes the
+    # configure script fail later
+    #
+    if [ "$NDK_CCACHE" -a "$MINGW" != "yes" -a "$DARWIN" != "yes" ]; then
+        NDK_CCACHE_CC=$CC
+        NDK_CCACHE_CXX=$CXX
+        # Unfortunately, we can just do CC="$NDK_CCACHE $CC" because some
+        # configure scripts are not capable of dealing with this properly
+        # E.g. the ones used to rebuild the GCC toolchain from scratch.
+        # So instead, use a wrapper script
+        CC=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-gcc.sh
+        CXX=$NDK_BUILDTOOLS_ABSPATH/ndk-ccache-g++.sh
+        export NDK_CCACHE_CC NDK_CCACHE_CXX
+        log "Using ccache compilation"
+        log "NDK_CCACHE_CC=$NDK_CCACHE_CC"
+        log "NDK_CCACHE_CXX=$NDK_CCACHE_CXX"
+    fi
+}
+
+prepare_common_build ()
+{
+    if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then
+        if [ "$TRY64" = "yes" ]; then
+            HOST_BITS=64
+        else
+            HOST_BITS=32
+        fi
+        if [ "$MINGW" = "yes" ]; then
+            log "Generating $HOST_BITS-bit Windows binaries"
+        else
+            log "Generating $HOST_BITS-bit Darwin binaries"
+        fi
+        # Do *not* set CC and CXX when building the Windows/Darwin binaries in canadian build.
+        # Otherwise, the GCC configure/build script will mess that Canadian cross
+        # build in weird ways. Instead we rely on the toolchain detected or generated
+        # previously in prepare_canadian_toolchain.
+        unset CC CXX
+        return
+    fi
+
+    # On Linux, detect our legacy-compatible toolchain when in the Android
+    # source tree, and use it to force the generation of glibc-2.7 compatible
+    # binaries.
+    #
+    # We only do this if the CC variable is not defined to a given value
+    if [ -z "$CC" ]; then
+        LEGACY_TOOLCHAIN_DIR=
+        if [ "$HOST_OS" = "linux" ]; then
+            LEGACY_TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8/bin"
+            LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/x86_64-linux-"
+        elif [ "$HOST_OS" = "darwin" ]; then
+            LEGACY_TOOLCHAIN_DIR="$ANDROID_BUILD_TOP/prebuilts/gcc/darwin-x86/host/i686-apple-darwin-4.2.1/bin"
+            LEGACY_TOOLCHAIN_PREFIX="$LEGACY_TOOLCHAIN_DIR/i686-apple-darwin10-"
+        fi
+        if [ -d "$LEGACY_TOOLCHAIN_DIR" ] ; then
+            log "Forcing generation of $HOST_OS binaries with legacy toolchain"
+            CC="${LEGACY_TOOLCHAIN_PREFIX}gcc"
+            CXX="${LEGACY_TOOLCHAIN_PREFIX}g++"
+        fi
+    fi
+
+    CC=${CC:-gcc}
+    CXX=${CXX:-g++}
+    STRIP=${STRIP:-strip}
+    case $HOST_TAG in
+        darwin-*)
+            probe_darwin_sdk
+            ;;
+    esac
+
+    # Force generation of 32-bit binaries on 64-bit systems.
+    # We used to test the value of $HOST_TAG for *-x86_64, but this is
+    # not sufficient on certain systems.
+    #
+    # For example, Snow Leopard can be booted with a 32-bit kernel, running
+    # a 64-bit userland, with a compiler that generates 64-bit binaries by
+    # default *even* though "gcc -v" will report --target=i686-apple-darwin10!
+    #
+    # So know, simply probe for the size of void* by performing a small runtime
+    # compilation test.
+    #
+    cat > $TMPC <<EOF
+    /* this test should fail if the compiler generates 64-bit machine code */
+    int test_array[1-2*(sizeof(void*) != 4)];
+EOF
+    log_n "Checking whether the compiler generates 32-bit binaries..."
+    log $CC $HOST_CFLAGS -c -o $TMPO $TMPC
+    $NDK_CCACHE $CC $HOST_CFLAGS -c -o $TMPO $TMPC >$TMPL 2>&1
+    if [ $? != 0 ] ; then
+        log "no"
+        if [ "$TRY64" != "yes" ]; then
+            # NOTE: We need to modify the definitions of CC and CXX directly
+            #        here. Just changing the value of CFLAGS / HOST_CFLAGS
+            #        will not work well with the GCC toolchain scripts.
+            CC="$CC -m32"
+            CXX="$CXX -m32"
+        fi
+    else
+        log "yes"
+        if [ "$TRY64" = "yes" ]; then
+            CC="$CC -m64"
+            CXX="$CXX -m64"
+        fi
+    fi
+
+    if [ "$TRY64" = "yes" ]; then
+        HOST_BITS=64
+    else
+        force_32bit_binaries  # to modify HOST_TAG and others
+        HOST_BITS=32
+    fi
+}
+
+prepare_host_build ()
+{
+    prepare_common_build
+
+    # Now deal with mingw or darwin
+    if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ]; then
+        handle_canadian_build
+        CC=$ABI_CONFIGURE_HOST-gcc
+        CXX=$ABI_CONFIGURE_HOST-g++
+        CPP=$ABI_CONFIGURE_HOST-cpp
+        LD=$ABI_CONFIGURE_HOST-ld
+        AR=$ABI_CONFIGURE_HOST-ar
+        AS=$ABI_CONFIGURE_HOST-as
+        RANLIB=$ABI_CONFIGURE_HOST-ranlib
+        STRIP=$ABI_CONFIGURE_HOST-strip
+        export CC CXX CPP LD AR AS RANLIB STRIP
+    fi
+
+    setup_ccache
+}
+
+prepare_abi_configure_build ()
+{
+    # detect build tag
+    case $HOST_TAG in
+        linux-x86)
+            ABI_CONFIGURE_BUILD=i386-linux-gnu
+            ;;
+        linux-x86_64)
+            ABI_CONFIGURE_BUILD=x86_64-linux-gnu
+            ;;
+        darwin-x86)
+            ABI_CONFIGURE_BUILD=i686-apple-darwin
+            ;;
+        darwin-x86_64)
+            ABI_CONFIGURE_BUILD=x86_64-apple-darwin
+            ;;
+        windows)
+            ABI_CONFIGURE_BUILD=i686-pc-cygwin
+            ;;
+        *)
+            echo "ERROR: Unsupported HOST_TAG: $HOST_TAG"
+            echo "Please update 'prepare_host_flags' in build/tools/prebuilt-common.sh"
+            ;;
+    esac
+}
+
+prepare_target_build ()
+{
+    prepare_abi_configure_build
+
+    # By default, assume host == build
+    ABI_CONFIGURE_HOST="$ABI_CONFIGURE_BUILD"
+
+    prepare_common_build
+    HOST_GMP_ABI=$HOST_BITS
+
+    # Now handle the --mingw/--darwin flag
+    if [ "$MINGW" = "yes" -o "$DARWIN" = "yes" ] ; then
+        handle_canadian_build
+        STRIP=$ABI_CONFIGURE_HOST-strip
+        if [ "$MINGW" = "yes" ] ; then
+            # It turns out that we need to undefine this to be able to
+            # perform a canadian-cross build with mingw. Otherwise, the
+            # GMP configure scripts will not be called with the right options
+            HOST_GMP_ABI=
+        fi
+    fi
+
+    setup_ccache
+}
+
+# $1: Toolchain name
+#
+parse_toolchain_name ()
+{
+    TOOLCHAIN=$1
+    if [ -z "$TOOLCHAIN" ] ; then
+        echo "ERROR: Missing toolchain name!"
+        exit 1
+    fi
+
+    ABI_CFLAGS_FOR_TARGET=
+    ABI_CXXFLAGS_FOR_TARGET=
+
+    # Determine ABI based on toolchain name
+    #
+    case "$TOOLCHAIN" in
+    arm-linux-androideabi-*)
+        ARCH="arm"
+        ABI="armeabi"
+        ABI_CONFIGURE_TARGET="arm-linux-androideabi"
+        ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te"
+        ;;
+    arm-eabi-*)
+        ARCH="arm"
+        ABI="armeabi"
+        ABI_CONFIGURE_TARGET="arm-eabi"
+        ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=armv5te --disable-gold --disable-libgomp"
+        ;;
+    aarch64-linux-android-*)
+        ARCH="arm64"
+        ABI="arm64-v8a"
+        ABI_CONFIGURE_TARGET="aarch64-linux-android"
+        ;;
+    x86-*)
+        ARCH="x86"
+        ABI=$ARCH
+        ABI_INSTALL_NAME="x86"
+        ABI_CONFIGURE_TARGET="i686-linux-android"
+        # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
+        # You can't really build these separately at the moment.
+        ABI_CFLAGS_FOR_TARGET="-fPIC"
+        ;;
+    x86_64-*)
+        ARCH="x86_64"
+        ABI=$ARCH
+        ABI_INSTALL_NAME="x86_64"
+        ABI_CONFIGURE_TARGET="x86_64-linux-android"
+        # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
+        # You can't really build these separately at the moment.
+        ABI_CFLAGS_FOR_TARGET="-fPIC"
+        ;;
+    mipsel*)
+        ARCH="mips"
+        ABI=$ARCH
+        ABI_INSTALL_NAME="mips"
+        ABI_CONFIGURE_TARGET="mipsel-linux-android"
+        # Set default to mips32
+        ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips32"
+        # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
+        # You can't really build these separately at the moment.
+        # Add -fpic, because MIPS NDK will need to link .a into .so.
+        ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic"
+        ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic"
+        # Add --disable-fixed-point to disable fixed-point support
+        ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point"
+        ;;
+    mips64el*)
+        ARCH="mips64"
+        ABI=$ARCH
+        ABI_INSTALL_NAME="mips64"
+        ABI_CONFIGURE_TARGET="mips64el-linux-android"
+        # Set default to mips64r6
+        ABI_CONFIGURE_EXTRA_FLAGS="--with-arch=mips64r6"
+        # Enable C++ exceptions, RTTI and GNU libstdc++ at the same time
+        # You can't really build these separately at the moment.
+        # Add -fpic, because MIPS NDK will need to link .a into .so.
+        ABI_CFLAGS_FOR_TARGET="-fexceptions -fpic"
+        ABI_CXXFLAGS_FOR_TARGET="-frtti -fpic"
+        # Add --disable-fixed-point to disable fixed-point support
+        ABI_CONFIGURE_EXTRA_FLAGS="$ABI_CONFIGURE_EXTRA_FLAGS --disable-fixed-point"
+        ;;
+    * )
+        echo "Invalid toolchain specified. Expected (arm-linux-androideabi-*|arm-eabi-*|x86-*|mipsel*|mips64el*)"
+        echo ""
+        print_help
+        exit 1
+        ;;
+    esac
+
+    log "Targetting CPU: $ARCH"
+
+    GCC_VERSION=`expr -- "$TOOLCHAIN" : '.*-\([0-9x\.]*\)'`
+    log "Using GCC version: $GCC_VERSION"
+}
+
+# Return the host "tag" used to identify prebuilt host binaries.
+# NOTE: Handles the case where '$MINGW = true' or '$DARWIN = true'
+# For now, valid values are: linux-x86, darwin-x86 and windows
+get_prebuilt_host_tag ()
+{
+    local RET=$HOST_TAG
+    if [ "$MINGW" = "yes" ]; then
+        if [ "$TRY64" = "no" ]; then
+            RET=windows
+        else
+            RET=windows-x86_64
+        fi
+    fi
+    if [ "$DARWIN" = "yes" ]; then
+        RET=darwin-x86_64  # let the following handles 32-bit case
+    fi
+    case $RET in
+        linux-*)
+            RET=linux-x86_64
+            ;;
+        darwin-*)
+            RET=darwin-x86_64
+            ;;
+    esac
+    echo $RET
+}
+
+# Return the executable suffix corresponding to host executables
+get_prebuilt_host_exe_ext ()
+{
+    if [ "$MINGW" = "yes" ]; then
+        echo ".exe"
+    else
+        echo ""
+    fi
+}
+
+# Get library suffix for given ABI
+# $1: ABI
+# Return: .so or .bc
+get_lib_suffix_for_abi ()
+{
+    local ABI=$1
+    echo ".so"
+}
+
+# Convert an ABI name into an Architecture name
+# $1: ABI name
+# Result: Arch name
+convert_abi_to_arch ()
+{
+    local RET
+    local ABI=$1
+    case $ABI in
+        armeabi|armeabi-v7a)
+            RET=arm
+            ;;
+        x86|mips|x86_64|mips64)
+            RET=$ABI
+            ;;
+        mips32r6)
+            RET=mips
+            ;;
+        arm64-v8a)
+            RET=arm64
+            ;;
+        *)
+            >&2 echo "ERROR: Unsupported ABI name: $ABI, use one of: armeabi, armeabi-v7a, x86, mips, arm64-v8a, x86_64 or mips64"
+            exit 1
+            ;;
+    esac
+    echo "$RET"
+}
+
+# Take architecture name as input, and output the list of corresponding ABIs
+# Inverse for convert_abi_to_arch
+# $1: ARCH name
+# Out: ABI names list (comma-separated)
+convert_arch_to_abi ()
+{
+    local RET
+    local ARCH=$1
+    case $ARCH in
+        arm)
+            RET=armeabi,armeabi-v7a
+            ;;
+        x86|x86_64|mips|mips64)
+            RET=$ARCH
+            ;;
+        arm64)
+            RET=arm64-v8a
+            ;;
+        *)
+            >&2 echo "ERROR: Unsupported ARCH name: $ARCH, use one of: arm, x86, mips"
+            exit 1
+            ;;
+    esac
+    echo "$RET"
+}
+
+# Take a list of architecture names as input, and output the list of corresponding ABIs
+# $1: ARCH names list (separated by spaces or commas)
+# Out: ABI names list (comma-separated)
+convert_archs_to_abis ()
+{
+    local RET
+    for ARCH in $(commas_to_spaces $@); do
+       ABI=$(convert_arch_to_abi $ARCH)
+       if [ -n "$ABI" ]; then
+          if [ -n "$RET" ]; then
+             RET=$RET",$ABI"
+          else
+             RET=$ABI
+          fi
+       else   # Error message is printed by convert_arch_to_abi
+          exit 1
+       fi
+    done
+    echo "$RET"
+}
+
+# Return the default toolchain binary path prefix for given architecture and gcc version
+# For example: arm 4.8 -> toolchains/<system>/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-
+# $1: Architecture name
+# $2: GCC version
+# $3: optional, system name, defaults to $HOST_TAG
+get_toolchain_binprefix_for_arch ()
+{
+    local NAME PREFIX DIR BINPREFIX
+    local SYSTEM=${3:-$(get_prebuilt_host_tag)}
+    NAME=$(get_toolchain_name_for_arch $1 $2)
+    PREFIX=$(get_default_toolchain_prefix_for_arch $1)
+    DIR=$(get_toolchain_install . $NAME $SYSTEM)
+    BINPREFIX=${DIR#./}/bin/$PREFIX-
+    echo "$BINPREFIX"
+}
+
+# Return llvm toolchain binary path prefix for given llvm version
+# $1: optional, system name, defaults to $HOST_TAG
+get_llvm_toolchain_binprefix ()
+{
+    local NAME DIR BINPREFIX
+    local SYSTEM=${1:-$(get_prebuilt_host_tag)}
+    local VERSION=4691093
+    SYSTEM=${SYSTEM%_64} # Trim _64 suffix. We only have one LLVM.
+    BINPREFIX=$ANDROID_BUILD_TOP/prebuilts/clang/host/$SYSTEM/clang-$VERSION/bin
+    echo "$BINPREFIX"
+}
+
+# Return default API level for a given arch
+# This is the level used to build the toolchains.
+#
+# $1: Architecture name
+get_default_api_level_for_arch ()
+{
+    # For now, always build the toolchain against API level 14 for 32-bit arch
+    # and API level $FIRST_API64_LEVEL for 64-bit arch
+    case $1 in
+        *64) echo $FIRST_API64_LEVEL ;;
+        *) echo 14 ;;
+    esac
+}
+
+# Return the default platform sysroot corresponding to a given architecture
+# This is the sysroot used to build the toolchain and other binaries like
+# the STLport libraries.
+# $1: Architecture name
+get_default_platform_sysroot_for_arch ()
+{
+    local ARCH=$1
+    local LEVEL=$(get_default_api_level_for_arch $ARCH)
+
+    if [ "$ARCH" != "${ARCH%%64*}" ] ; then
+        LEVEL=$FIRST_API64_LEVEL
+    fi
+    echo "platforms/android-$LEVEL/arch-$ARCH"
+}
+
+# Return the default platform sysroot corresponding to a given abi
+# $1: ABI
+get_default_platform_sysroot_for_abi ()
+{
+    local ARCH=$(convert_abi_to_arch $1)
+    $(get_default_platform_sysroot_for_arch $ARCH)
+}
+
+# Return the default libs dir corresponding to a given architecture
+# $1: Architecture name
+get_default_libdir_for_arch ()
+{
+    case $1 in
+      x86_64|mips64) echo "lib64" ;;
+      arm64) echo "lib" ;; # return "lib" until aarch64 is built to look for sysroot/usr/lib64
+      *) echo "lib" ;;
+    esac
+}
+
+# Return the default libs dir corresponding to a given abi
+# $1: ABI
+get_default_libdir_for_abi ()
+{
+    local ARCH
+
+    case $1 in
+      mips32r6) echo "libr6" ;;
+      *)
+        local ARCH=$(convert_abi_to_arch $1)
+        echo "$(get_default_libdir_for_arch $ARCH)"
+        ;;
+    esac
+}
+
+# Return the host/build specific path for prebuilt toolchain binaries
+# relative to $1.
+#
+# $1: target root NDK directory
+# $2: toolchain name
+# $3: optional, host system name
+#
+get_toolchain_install ()
+{
+    local NDK="$1"
+    shift
+    echo "$NDK/$(get_toolchain_install_subdir "$@")"
+}
+
+# $1: toolchain name
+# $2: optional, host system name
+get_toolchain_install_subdir ()
+{
+    local SYSTEM=${2:-$(get_prebuilt_host_tag)}
+    echo "toolchains/$SYSTEM/$1"
+}
+
+# Return the relative install prefix for prebuilt host
+# executables (relative to the NDK top directory).
+#
+# Out: relative path to prebuilt install prefix
+get_prebuilt_install_prefix ()
+{
+    echo "host-tools"
+}
+
+# Return the relative path of an installed prebuilt host
+# executable.
+#
+# $1: executable name
+# Out: path to prebuilt host executable, relative
+get_prebuilt_host_exec ()
+{
+    local PREFIX EXE
+    PREFIX=$(get_prebuilt_install_prefix)
+    EXE=$(get_prebuilt_host_exe_ext)
+    echo "$PREFIX/bin/$1$EXE"
+}
+
+# Return the name of a given host executable
+# $1: executable base name
+# Out: executable name, with optional suffix (e.g. .exe for windows)
+get_host_exec_name ()
+{
+    local EXE=$(get_prebuilt_host_exe_ext)
+    echo "$1$EXE"
+}
+
+# Return the directory where host-specific binaries are installed.
+# $1: target root NDK directory
+get_host_install ()
+{
+    echo "$1/$(get_prebuilt_install_prefix)"
+}
+
+# Set the toolchain target NDK location.
+# this sets TOOLCHAIN_PATH and TOOLCHAIN_PREFIX
+# $1: target NDK path
+# $2: toolchain name
+set_toolchain_ndk ()
+{
+    TOOLCHAIN_PATH=`get_toolchain_install "$1" $2`
+    log "Using toolchain path: $TOOLCHAIN_PATH"
+
+    TOOLCHAIN_PREFIX=$TOOLCHAIN_PATH/bin/$ABI_CONFIGURE_TARGET
+    log "Using toolchain prefix: $TOOLCHAIN_PREFIX"
+}
+
+# Check that a toolchain is properly installed at a target NDK location
+#
+# $1: target root NDK directory
+# $2: toolchain name
+#
+check_toolchain_install ()
+{
+    TOOLCHAIN_PATH=`get_toolchain_install "$1" $2`
+    if [ ! -d "$TOOLCHAIN_PATH" ] ; then
+        echo "ERROR: Cannot find directory '$TOOLCHAIN_PATH'!"
+        echo "       Toolchain '$2' not installed in '$NDK_DIR'!"
+        echo "       Ensure that the toolchain has been installed there before."
+        exit 1
+    fi
+
+    set_toolchain_ndk $1 $2
+}
+
+# $1: toolchain source directory
+check_toolchain_src_dir ()
+{
+    local SRC_DIR="$1"
+    if [ -z "$SRC_DIR" ]; then
+        echo "ERROR: Please provide the path to the toolchain source tree. See --help"
+        exit 1
+    fi
+
+    if [ ! -d "$SRC_DIR" ]; then
+        echo "ERROR: Not a directory: '$SRC_DIR'"
+        exit 1
+    fi
+
+    if [ ! -f "$SRC_DIR/build/configure" -o ! -d "$SRC_DIR/gcc" ]; then
+        echo "ERROR: Either the file $SRC_DIR/build/configure or"
+        echo "       the directory $SRC_DIR/gcc does not exist."
+        echo "This is not the top of a toolchain tree: $SRC_DIR"
+        exit 1
+    fi
+}
+
+make_repo_prop () {
+    local OUT_PATH="$1/repo.prop"
+
+    # The build server generates a repo.prop file that contains the current SHAs
+    # of each project.
+    if [ -f $DIST_DIR/repo.prop ]; then
+        cp $DIST_DIR/repo.prop $OUT_PATH
+    else
+        # Generate our own if we're building locally.
+        pushd $ANDROID_NDK_ROOT
+        repo forall \
+            -c 'echo $REPO_PROJECT $(git rev-parse HEAD)' > $OUT_PATH
+        popd
+    fi
+}
+
+#
+# Define HOST_TAG32, as the 32-bit version of HOST_TAG
+# We do this by replacing an -x86_64 suffix by -x86
+HOST_TAG32=$HOST_TAG
+case $HOST_TAG32 in
+    *-x86_64)
+        HOST_TAG32=${HOST_TAG%%_64}
+        ;;
+esac
diff --git a/build/tools/pylintrc b/build/tools/pylintrc
new file mode 100644
index 0000000..182bfba
--- /dev/null
+++ b/build/tools/pylintrc
@@ -0,0 +1,284 @@
+[MASTER]
+
+# Specify a configuration file.
+#rcfile=
+
+# Python code to execute, usually for sys.path manipulation such as
+# pygtk.require().
+#init-hook=
+
+# Profiled execution.
+profile=no
+
+# Add files or directories to the blacklist. They should be base names, not
+# paths.
+ignore=CVS
+
+# Pickle collected data for later comparisons.
+persistent=yes
+
+# List of plugins (as comma separated values of python modules names) to load,
+# usually to register additional checkers.
+load-plugins=
+
+
+[MESSAGES CONTROL]
+
+# Enable the message, report, category or checker with the given id(s). You can
+# either give multiple identifier separated by comma (,) or put this option
+# multiple time. See also the "--disable" option for examples.
+#enable=
+
+# Disable the message, report, category or checker with the given id(s). You
+# can either give multiple identifiers separated by comma (,) or put this
+# option multiple times (only on the command line, not in the configuration
+# file where it should appear only once).You can also use "--disable=all" to
+# disable everything first and then reenable specific checks. For example, if
+# you want to run only the similarities checker, you can use "--disable=all
+# --enable=similarities". If you want to run only the classes checker, but have
+# no Warning level messages displayed, use"--disable=all --enable=classes
+# --disable=W"
+
+# Some of these should be cleaned up, but disable them for now so I can check
+# this in. The too-many-* refactoring warnings will probably remain on for all
+# time, but naming and docstrings can and should be fixed.
+disable=missing-docstring,invalid-name,fixme,design,locally-disabled,too-many-lines,no-else-return,len-as-condition
+
+
+[REPORTS]
+
+# Set the output format. Available formats are text, parseable, colorized, msvs
+# (visual studio) and html. You can also give a reporter class, eg
+# mypackage.mymodule.MyReporterClass.
+output-format=text
+
+# Put messages in a separate file for each module / package specified on the
+# command line instead of printing them on stdout. Reports (if any) will be
+# written in a file name "pylint_global.[txt|html]".
+files-output=no
+
+# Tells whether to display a full report or only the messages
+reports=no
+
+# Python expression which should return a note less than 10 (10 is the highest
+# note). You have access to the variables errors warning, statement which
+# respectively contain the number of errors / warnings messages and the total
+# number of statements analyzed. This is used by the global evaluation report
+# (RP0004).
+evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
+
+# Add a comment according to your evaluation note. This is used by the global
+# evaluation report (RP0004).
+comment=no
+
+# Template used to display messages. This is a python new-style format string
+# used to format the message information. See doc for all details
+#msg-template=
+
+
+[BASIC]
+
+# Required attributes for module, separated by a comma
+required-attributes=
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=map,filter,apply,input
+
+# Regular expression which should only match correct module names
+module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
+
+# Regular expression which should only match correct module level names
+const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
+
+# Regular expression which should only match correct class names
+class-rgx=[A-Z_][a-zA-Z0-9]+$
+
+# Regular expression which should only match correct function names
+function-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct method names
+method-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct argument names
+argument-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct variable names
+variable-rgx=[a-z_][a-z0-9_]{2,30}$
+
+# Regular expression which should only match correct attribute names in class
+# bodies
+class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=i,j,k,ex,Run,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=foo,bar,baz,toto,tutu,tata
+
+# Regular expression which should only match function or class names that do
+# not require a docstring.
+no-docstring-rgx=__.*__
+
+# Minimum line length for functions/classes that require docstrings, shorter
+# ones are exempt.
+docstring-min-length=-1
+
+
+[TYPECHECK]
+
+# Tells whether missing members accessed in mixin class should be ignored. A
+# mixin class is detected if its name ends with "mixin" (case insensitive).
+ignore-mixin-members=yes
+
+# List of classes names for which member attributes should not be checked
+# (useful for classes with attributes dynamically set).
+ignored-classes=SQLObject,SyncManager
+
+# When zope mode is activated, add a predefined set of Zope acquired attributes
+# to generated-members.
+zope=no
+
+# List of members which are set dynamically and missed by pylint inference
+# system, and so shouldn't trigger E0201 when accessed. Python regular
+# expressions are accepted.
+generated-members=REQUEST,acl_users,aq_parent
+
+
+[MISCELLANEOUS]
+
+# List of note tags to take in consideration, separated by a comma.
+notes=FIXME,XXX,TODO
+
+
+[SIMILARITIES]
+
+# Minimum lines number of a similarity.
+min-similarity-lines=4
+
+# Ignore comments when computing similarities.
+ignore-comments=yes
+
+# Ignore docstrings when computing similarities.
+ignore-docstrings=yes
+
+# Ignore imports when computing similarities.
+ignore-imports=no
+
+
+[VARIABLES]
+
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching the beginning of the name of dummy variables
+# (i.e. not used).
+dummy-variables-rgx=_|dummy
+
+# List of additional names supposed to be defined in builtins. Remember that
+# you should avoid to define new builtins when possible.
+additional-builtins=
+
+
+[FORMAT]
+
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Regexp for a line that is allowed to be longer than the limit.
+ignore-long-lines=^\s*(# )?<?https?://\S+>?$
+
+# Allow the body of an if to be on the same line as the test if there is no
+# else.
+single-line-if-stmt=no
+
+# List of optional constructs for which whitespace checking is disabled
+no-space-check=trailing-comma,dict-separator
+
+# Maximum number of lines in a module
+max-module-lines=1000
+
+# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
+# tab).
+indent-string='    '
+
+
+[IMPORTS]
+
+# Deprecated modules which should not be used, separated by a comma
+deprecated-modules=regsub,TERMIOS,Bastion,rexec
+
+# Create a graph of every (i.e. internal and external) dependencies in the
+# given file (report RP0402 must not be disabled)
+import-graph=
+
+# Create a graph of external dependencies in the given file (report RP0402 must
+# not be disabled)
+ext-import-graph=
+
+# Create a graph of internal dependencies in the given file (report RP0402 must
+# not be disabled)
+int-import-graph=
+
+
+[DESIGN]
+
+# Maximum number of arguments for function / method
+max-args=5
+
+# Argument names that match this expression will be ignored. Default to name
+# with leading underscore
+ignored-argument-names=_.*
+
+# Maximum number of locals for function / method body
+max-locals=15
+
+# Maximum number of return / yield for function / method body
+max-returns=6
+
+# Maximum number of branch for function / method body
+max-branches=12
+
+# Maximum number of statements in function / method body
+max-statements=50
+
+# Maximum number of parents for a class (see R0901).
+max-parents=7
+
+# Maximum number of attributes for a class (see R0902).
+max-attributes=7
+
+# Minimum number of public methods for a class (see R0903).
+min-public-methods=2
+
+# Maximum number of public methods for a class (see R0904).
+max-public-methods=20
+
+
+[CLASSES]
+
+# List of interface methods to ignore, separated by a comma. This is used for
+# instance to not check methods defines in Zope's Interface base class.
+ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
+
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# List of valid names for the first argument in a class method.
+valid-classmethod-first-arg=cls
+
+# List of valid names for the first argument in a metaclass class method.
+valid-metaclass-classmethod-first-arg=mcs
+
+
+[EXCEPTIONS]
+
+# Exceptions that will emit a warning when being caught. Defaults to
+# "Exception"
+overgeneral-exceptions=Exception
diff --git a/build/tools/toolchain-licenses/COPYING b/build/tools/toolchain-licenses/COPYING
new file mode 100644
index 0000000..623b625
--- /dev/null
+++ b/build/tools/toolchain-licenses/COPYING
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/build/tools/toolchain-licenses/COPYING.LIB b/build/tools/toolchain-licenses/COPYING.LIB
new file mode 100644
index 0000000..2d2d780
--- /dev/null
+++ b/build/tools/toolchain-licenses/COPYING.LIB
@@ -0,0 +1,510 @@
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+	51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+                            Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software--to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages--typically libraries--of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations
+below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it
+becomes a de-facto standard.  To achieve this, non-free programs must
+be allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+                  GNU LESSER GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control
+compilation and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at least
+    three years, to give the same user the materials specified in
+    Subsection 6a, above, for a charge no more than the cost of
+    performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply, and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License
+may add an explicit geographical distribution limitation excluding those
+countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+                            NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+                     END OF TERMS AND CONDITIONS
+
+           How to Apply These Terms to Your New Libraries
+
+  If you develop a new library, and you want it to be of the greatest
+possible use to the public, we recommend making it free software that
+everyone can redistribute and change.  You can do so by permitting
+redistribution under these terms (or, alternatively, under the terms
+of the ordinary General Public License).
+
+  To apply these terms, attach the following notices to the library.
+It is safest to attach them to the start of each source file to most
+effectively convey the exclusion of warranty; and each file should
+have at least the "copyright" line and a pointer to where the full
+notice is found.
+
+
+    <one line to give the library's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Lesser General Public
+    License as published by the Free Software Foundation; either
+    version 2.1 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Lesser General Public License for more details.
+
+    You should have received a copy of the GNU Lesser General Public
+    License along with this library; if not, write to the Free Software
+    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+Also add information on how to contact you by electronic and paper mail.
+
+You should also get your employer (if you work as a programmer) or
+your school, if any, to sign a "copyright disclaimer" for the library,
+if necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the
+  library `Frob' (a library for tweaking knobs) written by James
+  Random Hacker.
+
+  <signature of Ty Coon>, 1 April 1990
+  Ty Coon, President of Vice
+
+That's all there is to it!
+
+
diff --git a/build/tools/toolchain-licenses/COPYING.RUNTIME b/build/tools/toolchain-licenses/COPYING.RUNTIME
new file mode 100644
index 0000000..e1b3c69
--- /dev/null
+++ b/build/tools/toolchain-licenses/COPYING.RUNTIME
@@ -0,0 +1,73 @@
+GCC RUNTIME LIBRARY EXCEPTION
+
+Version 3.1, 31 March 2009
+
+Copyright (C) 2009 Free Software Foundation, Inc. <http://fsf.org/>
+
+Everyone is permitted to copy and distribute verbatim copies of this
+license document, but changing it is not allowed.
+
+This GCC Runtime Library Exception ("Exception") is an additional
+permission under section 7 of the GNU General Public License, version
+3 ("GPLv3"). It applies to a given file (the "Runtime Library") that
+bears a notice placed by the copyright holder of the file stating that
+the file is governed by GPLv3 along with this Exception.
+
+When you use GCC to compile a program, GCC may combine portions of
+certain GCC header files and runtime libraries with the compiled
+program. The purpose of this Exception is to allow compilation of
+non-GPL (including proprietary) programs to use, in this way, the
+header files and runtime libraries covered by this Exception.
+
+0. Definitions.
+
+A file is an "Independent Module" if it either requires the Runtime
+Library for execution after a Compilation Process, or makes use of an
+interface provided by the Runtime Library, but is not otherwise based
+on the Runtime Library.
+
+"GCC" means a version of the GNU Compiler Collection, with or without
+modifications, governed by version 3 (or a specified later version) of
+the GNU General Public License (GPL) with the option of using any
+subsequent versions published by the FSF.
+
+"GPL-compatible Software" is software whose conditions of propagation,
+modification and use would permit combination with GCC in accord with
+the license of GCC.
+
+"Target Code" refers to output from any compiler for a real or virtual
+target processor architecture, in executable form or suitable for
+input to an assembler, loader, linker and/or execution
+phase. Notwithstanding that, Target Code does not include data in any
+format that is used as a compiler intermediate representation, or used
+for producing a compiler intermediate representation.
+
+The "Compilation Process" transforms code entirely represented in
+non-intermediate languages designed for human-written code, and/or in
+Java Virtual Machine byte code, into Target Code. Thus, for example,
+use of source code generators and preprocessors need not be considered
+part of the Compilation Process, since the Compilation Process can be
+understood as starting with the output of the generators or
+preprocessors.
+
+A Compilation Process is "Eligible" if it is done using GCC, alone or
+with other GPL-compatible software, or if it is done without using any
+work based on GCC. For example, using non-GPL-compatible Software to
+optimize any GCC intermediate representations would not qualify as an
+Eligible Compilation Process.
+
+1. Grant of Additional Permission.
+
+You have permission to propagate a work of Target Code formed by
+combining the Runtime Library with Independent Modules, even if such
+propagation would otherwise violate the terms of GPLv3, provided that
+all Target Code was generated by Eligible Compilation Processes. You
+may then convey such a combination under terms of your choice,
+consistent with the licensing of the Independent Modules.
+
+2. No Weakening of GCC Copyleft.
+
+The availability of this Exception does not imply any general
+presumption that third-party software is unaffected by the copyleft
+requirements of the license of GCC.
+
diff --git a/build/tools/toolchain-licenses/COPYING3 b/build/tools/toolchain-licenses/COPYING3
new file mode 100644
index 0000000..94a9ed0
--- /dev/null
+++ b/build/tools/toolchain-licenses/COPYING3
@@ -0,0 +1,674 @@
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/build/tools/toolchain-licenses/COPYING3.LIB b/build/tools/toolchain-licenses/COPYING3.LIB
new file mode 100644
index 0000000..fc8a5de
--- /dev/null
+++ b/build/tools/toolchain-licenses/COPYING3.LIB
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions. 
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version. 
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.