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. 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>. 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>. 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. 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). 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: 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: 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: 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: 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: 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: 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: 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>
+ 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: 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: 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: 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: 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>
+ 2: List to
+iterate over calling the function in 1<br>
+Returns: 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>
+ 2: List to
+iterate over calling the function in 1<br>
+ 3: Second
+list to iterate over calling the function in 1<br>
+Returns: 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>
+ 2: ...this
+list<br>
+Returns: 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>
+ 2: ...this
+list<br>
+Returns: 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: 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: 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: 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>
+ 2: ...this
+string<br>
+Returns: 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>
+ 2: ...this
+string<br>
+Returns: 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: Returns the length of the string<br>
+</span>
+<hr><b>substr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+ 2: Start offset (first character is 1)<br>
+ 3: Ending offset (inclusive)<br>Returns: Returns a substring<br>
+</span>
+<hr><b>split</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+split on<br>
+ 2: A
+string to split<br>
+Returns: Splits a string into a list separated by
+spaces at the split<br>
+ 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>
+ 2: A list
+to merge into a string<br>
+Returns: Merges a list into a single string, list
+elements are separated<br>
+ 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>
+ 2: The
+list of characters to translate to<br>
+ 3: The
+text to translate<br>
+Returns: 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: 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: 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: 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>
+ 2: A set<br>
+Returns: 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>
+ 2: A set<br>
+Returns: 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>
+ 2: A set<br>
+Returns: 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>
+ 2: Another set<br>
+Returns: 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>
+ 2: Another set<br>
+Returns: 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>
+ 2: Another set<br>
+Returns: 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>
+ 2: Another set<br>
+Returns: 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. For example the number 4 is x x x x. 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>). 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. 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. 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: Returns the integer for human consumption
+that is represented<br>
+ 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: 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>
+ 2: Another
+number in x's represntation<br>
+Returns: 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>
+ 2: Another
+integer<br>
+Returns: 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>
+ 2: Another
+number in x's represntation<br>
+Returns: Returns the difference of the two numbers in
+x's representation,<br>
+ 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>
+ 2: Another
+integer<br>
+Returns: Returns the difference of the two integers,<br>
+ 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>
+ 2: Another
+number in x's represntation<br>
+Returns: 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>
+ 2: Another
+integer<br>
+Returns: 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>
+ 2: Another
+number in x's represntation<br>
+Returns: Returns the result of integer division of
+argument 1 divided<br>
+ 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>
+ 2: Another
+integer<br>
+Returns: 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>
+ 2: Another
+number in x's represntation<br>
+Returns: Returns the maximum or minimum of its
+arguments in x's<br>
+
+representation<br>
+</span>
+<hr><b>max, min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+ 2: Another
+integer<br>
+Returns: 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: $(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: $(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: 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: 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: 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: 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: 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: 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: 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: 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). <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>
+ 2: The key
+value to associate<br>
+ 3: The
+value associated with the key<br>
+Returns: None<br>
+</span>
+<hr><b>get</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+ 2: The key
+to retrieve<br>
+Returns: 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: 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>
+ 2: The key
+to test<br>
+Returns: 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>
+ 2: Value
+to push onto the top of the stack (must not contain<br>
+ a space)<br>
+Returns: None<br>
+</span>
+<hr><b>pop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns: 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: 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: 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 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:
+$(true) if this version of the library is compatible<br>
+</span><span style="font-family: monospace;">
+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>
+ wish to
+print out.<br>
+Action: Echos the name of the variable that matches
+the % and its value.<br>
+ For
+example, 'make gmsl-print-SHELL' will output the value of<br>
+ 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>
+ 2: The
+message to print with the assertion<br>
+Returns: 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>
+ will be
+generated<br>
+Returns: 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. 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&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.