Check in r13b.

Test: None
Bug: http://b/32778419
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..8654169
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,52 @@
+Changelog
+=========
+
+Report issues to [GitHub].
+
+For Android Studio issues, follow the docs on the [Android Studio site].
+
+[GitHub]: https://github.com/android-ndk/ndk/issues
+[Android Studio site]: http://tools.android.com/filing-bugs
+
+Announcements
+-------------
+
+* GCC is no longer supported. It will not be removed from the NDK just yet, but
+  is no longer receiving backports. It cannot be removed until after libc++ has
+  become stable enough to be the default, as some parts of gnustl are still
+  incompatible with Clang. It will likely be removed after that point.
+
+NDK
+---
+
+ * `NDK_TOOLCHAIN_VERSION` now defaults to Clang.
+ * libc++ has been updated to r263688.
+     * We've reset to a (nearly) clean upstream. This should remove a number of
+       bugs, but we still need to clean up `libandroid_support` before we will
+       recommend it as the default.
+ * `make-standalone-toolchain.sh` is now simply a wrapper around the Python
+   version of the tool. There are a few behavioral differences. See
+   https://android-review.googlesource.com/#/c/245453/
+ * Some libraries for unsupported ABIs have been removed (mips64r2, mips32r6,
+   mips32r2, and x32). There might still be some stragglers.
+ * Issues with `crtbegin_static.o` that resulted in missing `atexit` at link
+   time when building a static executable for ARM android-21+ have been
+   resolved: https://github.com/android-ndk/ndk/issues/132
+ * Added CMake toolchain file in build/cmake/android.toolchain.cmake.
+
+Known Issues
+------------
+
+ * This is not intended to be a comprehensive list of all outstanding bugs.
+ * Standlone toolchains using libc++ and GCC do not work. This seems to be a bug
+   in GCC. See the following commit message for more details:
+   https://android-review.googlesource.com/#/c/247498
+ * x86 ASAN still doesn't work. See discussion on
+   https://android-review.googlesource.com/#/c/186276/
+ * Exception unwinding with `c++_shared` still does not work for ARM on
+   Gingerbread or Ice Cream Sandwich.
+ * Bionic headers and libraries for Marshmallow and N are not yet exposed
+   despite the presence of android-24. Those platforms are still the Lollipop
+   headers and libraries (not a regression from r11).
+ * RenderScript tools are not present (not a regression from r11):
+   https://github.com/android-ndk/ndk/issues/7.
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/awk/check-awk.awk b/build/awk/check-awk.awk
new file mode 100644
index 0000000..a3a0bc8
--- /dev/null
+++ b/build/awk/check-awk.awk
@@ -0,0 +1,40 @@
+# 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 script is used to check that a given awk executable
+# implements the match() and substr() functions appropriately.
+#
+# These were introduced in nawk/gawk, but the original awk
+# does not have them.
+#
+BEGIN {
+    RSTART=0
+    RLENGTH=0
+    s1="A real world example"
+    if (! match(s1,"world")) {
+        print "Fail match"
+    } else if (RSTART != 8) {
+        print "Fail RSTART ="RSTART
+    } else if (RLENGTH != 5) {
+        print "Fail RLENGTH ="RLENGTH
+    } else {
+        s2=substr(s1,RSTART,RLENGTH)
+        if (s2 != "world") {
+            print "Fail substr="s2
+        } else {
+            print "Pass"
+        }
+    }
+}
diff --git a/build/awk/extract-debuggable.awk b/build/awk/extract-debuggable.awk
new file mode 100644
index 0000000..c0993e6
--- /dev/null
+++ b/build/awk/extract-debuggable.awk
@@ -0,0 +1,136 @@
+# 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.
+#
+# A nawk/gawk script used to extract the debuggable flag from an
+# application's manifest (i.e. AndroidManifest.xml). Usage:
+#
+#   awk -f <this-script> AndroidManifest.xml
+#
+
+BEGIN {
+    DEBUGGABLE = "";
+    while ( xml_event() ) {
+        # simply extract the 'android:debuggable' attribute value from
+        # the first <manifest><application> element we find.
+        if ( XML_TYPE == "BEGIN" && XML_TAG == "APPLICATION" &&
+             XML_RPATH == "APPLICATION/MANIFEST/" ) {
+            DEBUGGABLE = XML_ATTR["android:debuggable"];
+            break;
+        }
+    }
+    # ensure the value is either "true" or "false"
+    if ( DEBUGGABLE != "true" )
+        DEBUGGABLE = "false";
+
+    print DEBUGGABLE;
+}
+
+#
+# the following is copied directly from xml.awk - see this file for
+# usage and implementation details.
+#
+function xml_event () {
+    RS=">";
+    XML_TAG=XML_TYPE="";
+    split("", XML_ATTR);
+    while ( 1 ) {
+        if (_xml_closing) { # delayed direct tag closure
+            XML_TAG = _xml_closing;
+            XML_TYPE = "END";
+            _xml_closing = "";
+            _xml_exit(XML_TAG);
+            return 1;
+        }
+        if (getline <= 0) return 0; # read new input line
+        _xml_p = index($0, "<"); # get start marker
+        if (_xml_p == 0) return 0; # end of file (or malformed input)
+        $0 = substr($0, _xml_p) # remove anything before '<'
+        # ignore CData / Comments / Processing instructions / Declarations
+        if (_xml_in_section("<!\\[[Cc][Dd][Aa][Tt][Aa]\\[", "]]") ||
+            _xml_in_section("<!--", "--") ||
+            _xml_in_section("<\\?", "\\?") ||
+            _xml_in_section("<!", "")) {
+            continue;
+        }
+        if (substr($0, 1, 2) == "</") { # is it a closing tag ?
+            XML_TYPE = "END";
+            $0 = substr($0, 3);
+        } else { # nope, it's an opening one
+            XML_TYPE = "BEGIN";
+            $0 = substr($0, 2);
+        }
+        XML_TAG = $0
+        sub("[ \r\n\t/].*$", "", XML_TAG);  # extract tag name
+        XML_TAG = toupper(XML_TAG);       # uppercase it
+        if ( XML_TAG !~ /^[A-Z][-+_.:0-9A-Z]*$/ )  # validate it
+            _xml_panic("Invalid tag name: " XML_TAG);
+        if (XML_TYPE == "BEGIN") {  # update reverse path
+            _xml_enter(XML_TAG);
+        } else {
+            _xml_exit(XML_TAG);
+        }
+        sub("[^ \r\n\t]*[ \r\n\t]*", "", $0); # get rid of tag and spaces
+        while ($0) { # process attributes
+            if ($0 == "/") {  # deal with direct closing tag, e.g. </foo>
+                _xml_closing = XML_TAG; # record delayed tag closure.
+                break
+            }
+            _xml_attrib = $0;
+            sub(/=.*$/,"",_xml_attrib);  # extract attribute name
+            sub(/^[^=]*/,"",$0);         # remove it from record
+            _xml_attrib = tolower(_xml_attrib);
+            if ( _xml_attrib !~ /^[a-z][-+_0-9a-z:]*$/ ) # validate it
+                _xml_panic("Invalid attribute name: " _xml_attrib);
+            if (substr($0,1,2) == "=\"") { # value is ="something"
+                _xml_value = substr($0,3);
+                sub(/".*$/,"",_xml_value);
+                sub(/^="[^"]*"/,"",$0);
+            } else if (substr($0,1,2) == "='") { # value is ='something'
+                _xml_value = substr($0,3);
+                sub(/'.*$/,"",_xml_value);
+                sub(/^='[^']*'/,"",$0);
+            } else {
+                _xml_panic("Invalid attribute value syntax for " _xml_attrib ": " $0);
+            }
+            XML_ATTR[_xml_attrib] = _xml_value;  # store attribute name/value
+            sub(/^[ \t\r\n]*/,"",$0); # get rid of remaining leading spaces
+        }
+        return 1; # now return, XML_TYPE/TAG/ATTR/RPATH are set
+    }
+}
+
+function _xml_panic (msg) {
+    print msg > "/dev/stderr"
+    exit(1)
+}
+
+function _xml_in_section (sec_begin, sec_end) {
+    if (!match( $0, "^" sec_begin )) return 0;
+    while (!match($0, sec_end "$")) {
+        if (getline <= 0) _xml_panic("Unexpected EOF: " ERRNO);
+    }
+    return 1;
+}
+
+function _xml_enter (tag) {
+    XML_RPATH = tag "/" XML_RPATH;
+}
+
+function _xml_exit (tag) {
+    _xml_p = index(XML_RPATH, "/");
+    _xml_expected = substr(XML_RPATH, 1, _xml_p-1);
+    if (_xml_expected != XML_TAG)
+        _xml_panic("Unexpected close tag: " XML_TAG ", expecting " _xml_expected);
+    XML_RPATH = substr(XML_RPATH, _xml_p+1);
+}
diff --git a/build/awk/extract-launchable.awk b/build/awk/extract-launchable.awk
new file mode 100644
index 0000000..803fc7e
--- /dev/null
+++ b/build/awk/extract-launchable.awk
@@ -0,0 +1,195 @@
+# 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.
+#
+# A nawk/gawk script used to extract the list of launchable activities
+# from an application's manifest (i.e. AndroidManifest.xml). Usage:
+#
+#   awk -f <this-script> AndroidManifest.xml
+#
+
+#
+# Explanation:
+#
+# A given application can have several activities, and each activity
+# can have several intent filters. We want to only list, in the final
+# output, the activities which have a intent-filter that contains the
+# following elements:
+#
+#   <action android:name="android.intent.action.MAIN" />
+#   <category android:name="android.intent.category.LAUNCHER" />
+#
+# To do this, we need hooks called when entering and exiting <activity>
+# and <intent-filter> elements.
+#
+
+BEGIN {
+    while ( xml_event() ) {
+        # concat xml event type and tag for simpler comparisons
+        event = XML_TYPE "-" XML_TAG;
+        # When entering a new <activity>, extract its name and set
+        # the 'launchable' flag to false.
+        if ( event == "BEGIN-ACTIVITY" && 
+             XML_RPATH == "ACTIVITY/APPLICATION/MANIFEST/" ) {
+            name = XML_ATTR["android:name"];
+            launchable = 0;
+        }
+        # When exiting an <activity>, check that it has a name and
+        # is launchable. If so, print its name to the output
+        else if ( event == "END-ACTIVITY" &&
+                  XML_RPATH == "APPLICATION/MANIFEST/" ) {
+            if ( name && launchable ) {
+                # If the name doesn't contain any dot, we consider
+                # that it is just missing the initial one.
+                if (index(name, ".") == 0) {
+                    name = "." name
+                }
+                print name;
+            }
+        }
+        # When entering an <intent-filter> inside an <activity>, clear
+        # the 'action' and 'category' variables. They are updated when
+        # we enter the corresponding elements within the intent-filter.
+        else if ( event == "BEGIN-INTENT-FILTER" &&
+                 XML_RPATH == "INTENT-FILTER/ACTIVITY/APPLICATION/MANIFEST/" ) {
+            action_main = 0;
+            category_launcher = 0;
+        }
+        # When exiting an <intent-filter>, set the 'launchable' flag to true
+        # for the current activity if both 'action' and 'category' have the
+        # correct name.
+        else if ( event == "END-INTENT-FILTER" &&
+                  XML_RPATH == "ACTIVITY/APPLICATION/MANIFEST/" ) {
+            if ( category_launcher ) {
+                launchable = 1;
+            }
+        }
+        # When entering an <action> element inside an <intent-filter>, record
+        # its name.
+        else if ( event == "BEGIN-ACTION" &&
+                  XML_RPATH == "ACTION/INTENT-FILTER/ACTIVITY/APPLICATION/MANIFEST/" ) {
+            action_main = 0;
+            if ( XML_ATTR["android:name"] == "android.intent.action.MAIN" ) {
+                action_main = 1;
+            }
+        }
+        # When entering a <category> element inside an <intent-filter>, record
+        # its name.
+        else if ( event == "BEGIN-CATEGORY" &&
+                  XML_RPATH == "CATEGORY/INTENT-FILTER/ACTIVITY/APPLICATION/MANIFEST/" ) {
+            if ( action_main && XML_ATTR["android:name"] == "android.intent.category.LAUNCHER" ) {
+                category_launcher = 1;
+            }
+        }
+    }
+}
+
+
+#
+# the following is copied directly from xml.awk - see this file for
+# usage and implementation details.
+#
+function xml_event () {
+    RS=">";
+    XML_TAG=XML_TYPE="";
+    split("", XML_ATTR);
+    while ( 1 ) {
+        if (_xml_closing) { # delayed direct tag closure
+            XML_TAG = _xml_closing;
+            XML_TYPE = "END";
+            _xml_closing = "";
+            _xml_exit(XML_TAG);
+            return 1;
+        }
+        if (getline <= 0) return 0; # read new input line
+        _xml_p = index($0, "<"); # get start marker
+        if (_xml_p == 0) return 0; # end of file (or malformed input)
+        $0 = substr($0, _xml_p) # remove anything before '<'
+        # ignore CData / Comments / Processing instructions / Declarations
+        if (_xml_in_section("<!\\[[Cc][Dd][Aa][Tt][Aa]\\[", "]]") ||
+            _xml_in_section("<!--", "--") ||
+            _xml_in_section("<\\?", "\\?") ||
+            _xml_in_section("<!", "")) {
+            continue;
+        }
+        if (substr($0, 1, 2) == "</") { # is it a closing tag ?
+            XML_TYPE = "END";
+            $0 = substr($0, 3);
+        } else { # nope, it's an opening one
+            XML_TYPE = "BEGIN";
+            $0 = substr($0, 2);
+        }
+        XML_TAG = $0
+        sub("[ \r\n\t/].*$", "", XML_TAG);  # extract tag name
+        XML_TAG = toupper(XML_TAG);       # uppercase it
+        if ( XML_TAG !~ /^[A-Z][-+_.:0-9A-Z]*$/ )  # validate it
+            _xml_panic("Invalid tag name: " XML_TAG);
+        if (XML_TYPE == "BEGIN") {  # update reverse path
+            _xml_enter(XML_TAG);
+        } else {
+            _xml_exit(XML_TAG);
+        }
+        sub("[^ \r\n\t]*[ \r\n\t]*", "", $0); # get rid of tag and spaces
+        while ($0) { # process attributes
+            if ($0 == "/") {  # deal with direct closing tag, e.g. </foo>
+                _xml_closing = XML_TAG; # record delayed tag closure.
+                break
+            }
+            _xml_attrib = $0;
+            sub(/=.*$/,"",_xml_attrib);  # extract attribute name
+            sub(/^[^=]*/,"",$0);         # remove it from record
+            _xml_attrib = tolower(_xml_attrib);
+            if ( _xml_attrib !~ /^[a-z][-+_0-9a-z:]*$/ ) # validate it
+                _xml_panic("Invalid attribute name: " _xml_attrib);
+            if (substr($0,1,2) == "=\"") { # value is ="something"
+                _xml_value = substr($0,3);
+                sub(/".*$/,"",_xml_value);
+                sub(/^="[^"]*"/,"",$0);
+            } else if (substr($0,1,2) == "='") { # value is ='something'
+                _xml_value = substr($0,3);
+                sub(/'.*$/,"",_xml_value);
+                sub(/^='[^']*'/,"",$0);
+            } else {
+                _xml_panic("Invalid attribute value syntax for " _xml_attrib ": " $0);
+            }
+            XML_ATTR[_xml_attrib] = _xml_value;  # store attribute name/value
+            sub(/^[ \t\r\n]*/,"",$0); # get rid of remaining leading spaces
+        }
+        return 1; # now return, XML_TYPE/TAG/ATTR/RPATH are set
+    }
+}
+
+function _xml_panic (msg) {
+    print msg > "/dev/stderr"
+    exit(1)
+}
+
+function _xml_in_section (sec_begin, sec_end) {
+    if (!match( $0, "^" sec_begin )) return 0;
+    while (!match($0, sec_end "$")) {
+        if (getline <= 0) _xml_panic("Unexpected EOF: " ERRNO);
+    }
+    return 1;
+}
+
+function _xml_enter (tag) {
+    XML_RPATH = tag "/" XML_RPATH;
+}
+
+function _xml_exit (tag) {
+    _xml_p = index(XML_RPATH, "/");
+    _xml_expected = substr(XML_RPATH, 1, _xml_p-1);
+    if (_xml_expected != XML_TAG)
+        _xml_panic("Unexpected close tag: " XML_TAG ", expecting " _xml_expected);
+    XML_RPATH = substr(XML_RPATH, _xml_p+1);
+}
diff --git a/build/awk/extract-minsdkversion.awk b/build/awk/extract-minsdkversion.awk
new file mode 100644
index 0000000..b6f4129
--- /dev/null
+++ b/build/awk/extract-minsdkversion.awk
@@ -0,0 +1,133 @@
+# 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.
+#
+# A nawk/gawk script used to extract the value of min. SDK version from an
+# application's manifest (i.e. AndroidManifest.xml). Usage:
+#
+#   awk -f <this-script> AndroidManifest.xml
+#
+
+BEGIN {
+    MIN_SDK_VERSION = "";
+    while ( xml_event() ) {
+        # simply extract the 'android:minSdkVersion' attribute value from
+        # the first <manifest><uses-sdk> element we find.
+        if ( XML_TYPE == "BEGIN" && XML_TAG == "USES-SDK" &&
+             XML_RPATH == "USES-SDK/MANIFEST/" ) {
+            MIN_SDK_VERSION = XML_ATTR["android:minsdkversion"];
+            break;
+        }
+    }
+
+    print MIN_SDK_VERSION;
+}
+
+#
+# the following is copied directly from xml.awk - see this file for
+# usage and implementation details.
+#
+function xml_event () {
+    RS=">";
+    XML_TAG=XML_TYPE="";
+    split("", XML_ATTR);
+    while ( 1 ) {
+        if (_xml_closing) { # delayed direct tag closure
+            XML_TAG = _xml_closing;
+            XML_TYPE = "END";
+            _xml_closing = "";
+            _xml_exit(XML_TAG);
+            return 1;
+        }
+        if (getline <= 0) return 0; # read new input line
+        _xml_p = index($0, "<"); # get start marker
+        if (_xml_p == 0) return 0; # end of file (or malformed input)
+        $0 = substr($0, _xml_p) # remove anything before '<'
+        # ignore CData / Comments / Processing instructions / Declarations
+        if (_xml_in_section("<!\\[[Cc][Dd][Aa][Tt][Aa]\\[", "]]") ||
+            _xml_in_section("<!--", "--") ||
+            _xml_in_section("<\\?", "\\?") ||
+            _xml_in_section("<!", "")) {
+            continue;
+        }
+        if (substr($0, 1, 2) == "</") { # is it a closing tag ?
+            XML_TYPE = "END";
+            $0 = substr($0, 3);
+        } else { # nope, it's an opening one
+            XML_TYPE = "BEGIN";
+            $0 = substr($0, 2);
+        }
+        XML_TAG = $0
+        sub("[ \r\n\t/].*$", "", XML_TAG);  # extract tag name
+        XML_TAG = toupper(XML_TAG);       # uppercase it
+        if ( XML_TAG !~ /^[A-Z][-+_.:0-9A-Z]*$/ )  # validate it
+            _xml_panic("Invalid tag name: " XML_TAG);
+        if (XML_TYPE == "BEGIN") {  # update reverse path
+            _xml_enter(XML_TAG);
+        } else {
+            _xml_exit(XML_TAG);
+        }
+        sub("[^ \r\n\t]*[ \r\n\t]*", "", $0); # get rid of tag and spaces
+        while ($0) { # process attributes
+            if ($0 == "/") {  # deal with direct closing tag, e.g. </foo>
+                _xml_closing = XML_TAG; # record delayed tag closure.
+                break
+            }
+            _xml_attrib = $0;
+            sub(/=.*$/,"",_xml_attrib);  # extract attribute name
+            sub(/^[^=]*/,"",$0);         # remove it from record
+            _xml_attrib = tolower(_xml_attrib);
+            if ( _xml_attrib !~ /^[a-z][-+_0-9a-z:]*$/ ) # validate it
+                _xml_panic("Invalid attribute name: " _xml_attrib);
+            if (substr($0,1,2) == "=\"") { # value is ="something"
+                _xml_value = substr($0,3);
+                sub(/".*$/,"",_xml_value);
+                sub(/^="[^"]*"/,"",$0);
+            } else if (substr($0,1,2) == "='") { # value is ='something'
+                _xml_value = substr($0,3);
+                sub(/'.*$/,"",_xml_value);
+                sub(/^='[^']*'/,"",$0);
+            } else {
+                _xml_panic("Invalid attribute value syntax for " _xml_attrib ": " $0);
+            }
+            XML_ATTR[_xml_attrib] = _xml_value;  # store attribute name/value
+            sub(/^[ \t\r\n]*/,"",$0); # get rid of remaining leading spaces
+        }
+        return 1; # now return, XML_TYPE/TAG/ATTR/RPATH are set
+    }
+}
+
+function _xml_panic (msg) {
+    print msg > "/dev/stderr"
+    exit(1)
+}
+
+function _xml_in_section (sec_begin, sec_end) {
+    if (!match( $0, "^" sec_begin )) return 0;
+    while (!match($0, sec_end "$")) {
+        if (getline <= 0) _xml_panic("Unexpected EOF: " ERRNO);
+    }
+    return 1;
+}
+
+function _xml_enter (tag) {
+    XML_RPATH = tag "/" XML_RPATH;
+}
+
+function _xml_exit (tag) {
+    _xml_p = index(XML_RPATH, "/");
+    _xml_expected = substr(XML_RPATH, 1, _xml_p-1);
+    if (_xml_expected != XML_TAG)
+        _xml_panic("Unexpected close tag: " XML_TAG ", expecting " _xml_expected);
+    XML_RPATH = substr(XML_RPATH, _xml_p+1);
+}
diff --git a/build/awk/extract-package-name.awk b/build/awk/extract-package-name.awk
new file mode 100644
index 0000000..8d436e4
--- /dev/null
+++ b/build/awk/extract-package-name.awk
@@ -0,0 +1,137 @@
+# 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.
+#
+# A nawk/gawk script used to extract the package name from an application's
+# manifest (i.e. AndroidManifest.xml). Usage is:
+#
+#   awk -f <this-script> AndroidManifest.xml
+#
+# The name itself is the value of the 'package' attribute in the
+# 'manifest' element.
+#
+
+BEGIN {
+    PACKAGE="";
+    while (xml_event()) {
+        # Simply extract the value of the 'name' attribute from
+        # the top-level <manifest> element.
+        if ( XML_TYPE == "BEGIN" && XML_RPATH == "MANIFEST/" ) {
+            PACKAGE = XML_ATTR["package"];
+            break;
+        }
+    }
+    if (!PACKAGE)
+        PACKAGE = "<none>";
+
+    print PACKAGE;
+}
+
+#
+# the following is copied directly from xml.awk - see this file for
+# usage and implementation details.
+#
+function xml_event () {
+    RS=">";
+    XML_TAG=XML_TYPE="";
+    split("", XML_ATTR);
+    while ( 1 ) {
+        if (_xml_closing) { # delayed direct tag closure
+            XML_TAG = _xml_closing;
+            XML_TYPE = "END";
+            _xml_closing = "";
+            _xml_exit(XML_TAG);
+            return 1;
+        }
+        if (getline <= 0) return 0; # read new input line
+        _xml_p = index($0, "<"); # get start marker
+        if (_xml_p == 0) return 0; # end of file (or malformed input)
+        $0 = substr($0, _xml_p) # remove anything before '<'
+        # ignore CData / Comments / Processing instructions / Declarations
+        if (_xml_in_section("<!\\[[Cc][Dd][Aa][Tt][Aa]\\[", "]]") ||
+            _xml_in_section("<!--", "--") ||
+            _xml_in_section("<\\?", "\\?") ||
+            _xml_in_section("<!", "")) {
+            continue;
+        }
+        if (substr($0, 1, 2) == "</") { # is it a closing tag ?
+            XML_TYPE = "END";
+            $0 = substr($0, 3);
+        } else { # nope, it's an opening one
+            XML_TYPE = "BEGIN";
+            $0 = substr($0, 2);
+        }
+        XML_TAG = $0
+        sub("[ \r\n\t/].*$", "", XML_TAG);  # extract tag name
+        XML_TAG = toupper(XML_TAG);       # uppercase it
+        if ( XML_TAG !~ /^[A-Z][-+_.:0-9A-Z]*$/ )  # validate it
+            _xml_panic("Invalid tag name: " XML_TAG);
+        if (XML_TYPE == "BEGIN") {  # update reverse path
+            _xml_enter(XML_TAG);
+        } else {
+            _xml_exit(XML_TAG);
+        }
+        sub("[^ \r\n\t]*[ \r\n\t]*", "", $0); # get rid of tag and spaces
+        while ($0) { # process attributes
+            if ($0 == "/") {  # deal with direct closing tag, e.g. </foo>
+                _xml_closing = XML_TAG; # record delayed tag closure.
+                break
+            }
+            _xml_attrib = $0;
+            sub(/=.*$/,"",_xml_attrib);  # extract attribute name
+            sub(/^[^=]*/,"",$0);         # remove it from record
+            _xml_attrib = tolower(_xml_attrib);
+            if ( _xml_attrib !~ /^[a-z][-+_0-9a-z:]*$/ ) # validate it
+                _xml_panic("Invalid attribute name: " _xml_attrib);
+            if (substr($0,1,2) == "=\"") { # value is ="something"
+                _xml_value = substr($0,3);
+                sub(/".*$/,"",_xml_value);
+                sub(/^="[^"]*"/,"",$0);
+            } else if (substr($0,1,2) == "='") { # value is ='something'
+                _xml_value = substr($0,3);
+                sub(/'.*$/,"",_xml_value);
+                sub(/^='[^']*'/,"",$0);
+            } else {
+                _xml_panic("Invalid attribute value syntax for " _xml_attrib ": " $0);
+            }
+            XML_ATTR[_xml_attrib] = _xml_value;  # store attribute name/value
+            sub(/^[ \t\r\n]*/,"",$0); # get rid of remaining leading spaces
+        }
+        return 1; # now return, XML_TYPE/TAG/ATTR/RPATH are set
+    }
+}
+
+function _xml_panic (msg) {
+    print msg > "/dev/stderr"
+    exit(1)
+}
+
+function _xml_in_section (sec_begin, sec_end) {
+    if (!match( $0, "^" sec_begin )) return 0;
+    while (!match($0, sec_end "$")) {
+        if (getline <= 0) _xml_panic("Unexpected EOF: " ERRNO);
+    }
+    return 1;
+}
+
+function _xml_enter (tag) {
+    XML_RPATH = tag "/" XML_RPATH;
+}
+
+function _xml_exit (tag) {
+    _xml_p = index(XML_RPATH, "/");
+    _xml_expected = substr(XML_RPATH, 1, _xml_p-1);
+    if (_xml_expected != XML_TAG)
+        _xml_panic("Unexpected close tag: " XML_TAG ", expecting " _xml_expected);
+    XML_RPATH = substr(XML_RPATH, _xml_p+1);
+}
diff --git a/build/awk/extract-platform.awk b/build/awk/extract-platform.awk
new file mode 100644
index 0000000..d628694
--- /dev/null
+++ b/build/awk/extract-platform.awk
@@ -0,0 +1,43 @@
+# 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 nawk/gawk script used to extract the application's platform name from
+# its project.properties file. It is called from build/core/add-application.mk
+#
+
+# we look for a line that looks like one of:
+#    target=android-<api>
+#    target=<vendor>:<name>:<api>
+#
+# <api> is a number, but can also be "Donut" for the first form,
+# as a special case.
+#
+BEGIN {
+    android_regex="android-[0-9A-Za-z_-]+"
+    vendor_regex=":[0-9]+\\s*$"
+    API=unknown
+}
+
+/^target\s*=\s*.*/ {
+    if (match($0,android_regex)) {
+        API=substr($0,RSTART,RLENGTH)
+    }
+    else if (match($0,vendor_regex)) {
+        API="android-" substr($0,RSTART+1,RLENGTH)
+    }
+}
+
+END {
+    printf("%s", API)
+}
diff --git a/build/awk/gen-cygwin-deps-converter.awk b/build/awk/gen-cygwin-deps-converter.awk
new file mode 100644
index 0000000..d59812d
--- /dev/null
+++ b/build/awk/gen-cygwin-deps-converter.awk
@@ -0,0 +1,201 @@
+# 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 script is used to generate a shell script that will be
+# run by the NDK build system to process dependency files generated by
+# GCC on Windows, and convert them to a format that is suitable for
+# Cygwin's GNU Make.
+#
+# The main issue to solve here is that the dependency files generated
+# by GCC use native windows path names, as in:
+#
+#    C:/Foo/foo.o: \
+#      C:/Foo/src/foo.h \
+#      C:/Foo/src/foo.c \
+#      D:/Bar/bar/bar.h
+#
+# And the file needs to be processed to convert each such path into
+# a Cygwin-specific one, as in:
+#
+#    /cygdrive/c/Foo/foo.o: \
+#      /cygdrive/c/Foo/src/foo.h \
+#      /cygdrive/c/Foo/src/foo.c \
+#      /cygdrive/d/Bar/bar/bar.h
+#
+# Previously, this conversion was done with an awk script that assumed
+# that the cygwin drive prefix was always 'cygdrive'. This didn't work
+# well when this was not the case, or when using drive-less mounts
+# (e.g. when  /home/mnt would map to //server/subdir)
+#
+# To solve the issue correctly, we need to parse the output of the
+# Cygwin mount table (i.e. the output of the 'mount' command), and
+# build a sed script that will properly replace host paths into the
+# corresponding cygwin equivalent.
+#
+# NOTE: The sed script will be run during command execution, not during the
+# parse phase.
+#
+# This awk script expects its input to be the output of the Cygwin "mount" command
+# as in:
+#
+#  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)
+#  //server/subdir on /home/mnt.2$ type ....
+#
+# It first builds a sed script that convert all windows path in the
+# an input file into the cygwin equivalent. For example, this would look
+# like the following (but all on a single line):
+#
+#  s!^//server/subdir!/home/mnt\.2\$!ig;
+#  s! //server/subdir! /home/mnt\.2\$!ig;
+#  s!^C:/cygwin/bin!/usr/bin!ig;
+#  s! C:/cygwin/bin! /usr/bin!ig;
+#  s!^C:/cygwin/lib!/usr/lib!ig;
+#  s! C:/cygwin/lib! /usr/lib!ig;
+#  s!^C:/cygwin/!/!ig;
+#  s! C:/cygwin/! /!ig;
+#  s!^C:!/cygdrive/c!ig;
+#  s! C:! /cygdrive/c!ig;
+#  s!^D:!/cygdrive/d!ig;
+#  s! D:! /cygdrive/d!ig;
+#
+# Note that we properly escape regex meta characters like . or $
+# to avoid confusing sed. Also deal with the cases where the path
+# is the first in the line, or prefixed with a space in the deps file.
+#
+# After this, the sed invokation is hard-coded into a generated shell
+# script that can be invoked directly at build time.
+#
+BEGIN {
+  # setup our count
+  count = 0
+}
+
+$2 == "on" {
+    # record a new (host-path,cygwin-path) pair
+    count ++
+
+    # Convert backwards slashes into forward ones in the host path.
+    # This is to support MSys' mount command, which outputs Windows-style
+    # separators, unlike Cygwin's version of the same tool.
+    gsub("\\\\","/",$1)
+
+    host[count] = $1
+    cygwin[count] = $3
+}
+
+END {
+    # We have recorded all (host,cygwin) path pairs,
+    # now try to sort them so that the ones with the longest host path
+    # appear first
+    for (ii = 2; ii <= count; ii++) {
+        for (jj = ii-1; jj > 0; jj--) {
+            if (length(host[jj]) > length(host[jj+1])) {
+                break;
+            }
+            if (length(host[jj]) == length(host[jj+1]) &&
+                host[jj] > host[jj+1]) {
+                break
+            }
+            tmp = cygwin[jj]
+            cygwin[jj] = cygwin[jj+1]
+            cygwin[jj+1] = tmp
+            tmp = host[jj]
+            host[jj] = host[jj+1]
+            host[jj+1] = tmp
+        }
+    }
+
+    # build/core/init.mk defines VERBOSE to 1 when it needs to dump the
+    # list of substitutions in a human-friendly format, generally when
+    # NDK_LOG is defined in the environment
+    #
+    # Otherwise, just generate the corresponding sed script
+    #
+    if (VERBOSE == 1) {
+        for (nn = 1; nn <= count; nn++) {
+            printf( "$(info %s => %s)", cygwin[nn], host[nn]);
+        }
+    } else {
+        RESULT = ""
+        for (nn = 1; nn <= count; nn++) {
+            add_drive_rule(host[nn], cygwin[nn])
+        }
+
+        # Note: the role of the generated shell script is to first check
+        #       that $1.org exists. If this is not the case, this simply
+        #       means that GCC didn't generate a depedency file (e.g. when
+        #       compiling an assembler file).
+        #
+        #       If the file exists, it is processed with our sed script,
+        #       the output is written to $1, and we remove the original $1.org
+        #
+        print "#!/bin/sh"
+        print "# AUTO-GENERATED FILE, DO NOT EDIT!"
+        print "if [ -f $1.org ]; then"
+        print "  sed -e '" RESULT "' $1.org > $1 && rm -f $1.org"
+        print "fi"
+    }
+}
+
+# We need to quote some characters so that 'sed' doesn't
+# believe they are regex operators. For example, if a path
+# contains a dot (.), we need to escape it into "\."
+#
+function sed_quote_path (str)
+{
+    # Windows path names cannot contain any of: <>:"|?*
+    # see msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx
+    #
+    # Anything else is valid. The regex meta characters are: ^.[]$()|*+?{}\
+    #
+    # This means we need to escape these when they appear in path names: ^.[]$()+{}\
+    #
+    gsub("\\^","\\^",str)
+    gsub("\\.","\\.",str)
+    gsub("\\[","\\[",str)
+    gsub("\\]","\\]",str)
+    gsub("\\$","\\$",str)
+    gsub("\\(","\\(",str)
+    gsub("\\)","\\)",str)
+    gsub("\\+","\\+",str)
+    gsub("\\{","\\{",str)
+    gsub("\\}","\\}",str)
+
+    return str
+}
+
+function add_drive_rule (hostpath,cygpath)
+{
+    hostpath = sed_quote_path(hostpath)
+	cygpath = sed_quote_path(cygpath)
+	
+    # The root directory is a special case, because we need
+	# to add a slash at the end of the corresponding host path
+	# otherwise c:/cygwin/foo will be translated into //foo
+	# instead of /foo.
+	#
+    if (cygpath == "/") {
+        hostpath = hostpath "/"
+    }
+	# when the hostpath starts the line
+    RESULT = RESULT "s!^" hostpath "!" cygpath "!ig;"
+
+	# when the hostpath does not start the line (it will always be after a space)
+	RESULT = RESULT "s! " hostpath "! " cygpath "!ig;"
+}
diff --git a/build/awk/gen-windows-host-path.awk b/build/awk/gen-windows-host-path.awk
new file mode 100644
index 0000000..b72f4b7
--- /dev/null
+++ b/build/awk/gen-windows-host-path.awk
@@ -0,0 +1,149 @@
+# 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 script is used to generate a Makefile fragment that will be evaluated
+# at runtime by the NDK build system during its initialization pass.
+#
+# The purpose of this generated fragment is to define a function, named
+# 'cygwin-to-host-path' that will transform a Cygwin-specific path into the
+# corresponding Windows specific one, i.e. calling
+#
+#   $(call cygwin-to-host-path,/cygdrive/c/Stuff/)  --> c:/Stuff
+#
+# A naive implementation of this function would be the following:
+#
+#   cygwin-to-host-path = $(shell cygpath -m $1)
+#
+# Unfortunately, calling 'cygpath -m' from GNU Make is horridly slow and people
+# have complained that this was adding several minutes to their builds, even in
+# the case where there is nothing to do.
+#
+# The script expects its input to be the output of the Cygwin "mount" command
+# as in:
+#
+#  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)
+#
+# The script's output will be passed to the GNU Make 'eval' function
+# and will look like:
+#
+#  $(patsubst /%,C:/cygwin/,
+#  $(patsubst /usr/bin/%,C:/cygwin/bin/,
+#  $(patsubst /usr/lib/%,C:/cygwin/lib/,
+#  $(patsubst /cygdrive/C/%,C:/,
+#  $(patsubst /cygdrive/D/%,D:/,
+#  $(patsubst /cygdrive/c/%,C:/,
+#  $(patsubst /cygdrive/d/%,D:/,$1)))))
+#
+BEGIN {
+  # setup our count
+  count = 0
+}
+
+$2 == "on" {
+    # record a new (host-path,cygwin-path) pair
+    count ++
+    host[count] = $1
+    cygwin[count] = $3
+}
+
+END {
+    # Drive letters are special cases because we must match both
+    # the upper and lower case versions to the same drive, i.e.
+    # if "mount" lists that /cygdrive/c maps to C:, we need to
+    # map both /cygdrive/c and /cygdrive/C to C: in our final rules.
+    #
+    count1 = count
+    for (nn = 1; nn <= count1; nn++) {
+        if (!match(host[nn],"^[A-Za-z]:$")) {
+            # not a driver letter mapping, skip this pair
+            continue
+        }
+        letter = substr(host[nn],1,1)
+        lo     = tolower(letter)
+        up     = toupper(letter)
+
+        # If the cygwin path ends in /<lo>, then substitute it with /<up>
+        # to create a new pair.
+        if (match(cygwin[nn],"/"lo"$")) {
+            count++
+            host[count] = host[nn]
+            cygwin[count] = substr(cygwin[nn],1,length(cygwin[nn])-1) up
+            continue
+        }
+
+        # If the cygwin path ends in /<up>, then substitute it with /<lo>
+        # to create a new pair.
+        if (match(cygwin[nn],"/"up"$")) {
+            count++
+            host[count] = host[nn]
+            cygwin[count] = substr(cygwin[nn],1,length(cygwin[nn])-1) lo
+            continue
+        }
+    }
+
+    # We have recorded all (host,cygwin) path pairs,
+    # now try to sort them so that the ones with the longest cygwin path
+    # appear first
+    for (ii = 2; ii <= count; ii++) {
+        for (jj = ii-1; jj > 0; jj--) {
+            if (length(cygwin[jj]) > length(cygwin[jj+1])) {
+                break;
+            }
+            if (length(cygwin[jj]) == length(cygwin[jj+1]) &&
+                cygwin[jj] > cygwin[jj+1]) {
+                break
+            }
+            tmp = cygwin[jj]
+            cygwin[jj] = cygwin[jj+1]
+            cygwin[jj+1] = tmp
+            tmp = host[jj]
+            host[jj] = host[jj+1]
+            host[jj+1] = tmp
+        }
+    }
+
+    # build/core/init.mk defines VERBOSE to 1 when it needs to dump the
+    # list of substitutions in a human-friendly format, generally when
+    # NDK_LOG is defined in the environment
+    #
+    # Otherwise, just generate the corresponding Make function definition
+    #
+    if (VERBOSE == 1) {
+        for (nn = 1; nn <= count; nn++) {
+            printf( "$(info %s => %s)", cygwin[nn], host[nn]);
+        }
+    } else {
+        RESULT = "$1"
+        for (nn = 1; nn <= count; nn++) {
+            add_drive_rule(host[nn], cygwin[nn])
+        }
+        print RESULT
+    }
+}
+
+function add_drive_rule (hostpath,cygpath)
+{
+    if (cygpath == "/") {
+        # Special case for /
+        RESULT = "$(patsubst /%," hostpath "/%,\n" RESULT ")"
+        return
+    }
+    # default rule otherwise
+    RESULT = "$(patsubst " cygpath "/%," hostpath "/%,\n" RESULT ")"
+}
diff --git a/build/awk/xml.awk b/build/awk/xml.awk
new file mode 100644
index 0000000..ae1f21d
--- /dev/null
+++ b/build/awk/xml.awk
@@ -0,0 +1,327 @@
+# 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.
+#
+
+# Tiny XML parser implementation in awk.
+#
+# This file is not meant to be used directly, instead copy the
+# functions it defines here into your own script then specialize
+# it appropriately.
+#
+
+# See further below for usage instructions and implementation details.
+#
+
+# ---------------------------- cut here ---------------------------
+
+function xml_event () {
+    RS=">";
+    XML_TAG=XML_TYPE="";
+    split("", XML_ATTR);
+    while ( 1 ) {
+        if (_xml_closing) { # delayed direct tag closure
+            XML_TAG = _xml_closing;
+            XML_TYPE = "END";
+            _xml_closing = "";
+            _xml_exit(XML_TAG);
+            return 1;
+        }
+        if (getline <= 0) return 0; # read new input line
+        _xml_p = index($0, "<"); # get start marker
+        if (_xml_p == 0) return 0; # end of file (or malformed input)
+        $0 = substr($0, _xml_p) # remove anything before '<'
+        # ignore CData / Comments / Processing instructions / Declarations
+        if (_xml_in_section("<!\\[[Cc][Dd][Aa][Tt][Aa]\\[", "]]") ||
+            _xml_in_section("<!--", "--") ||
+            _xml_in_section("<\\?", "\\?") ||
+            _xml_in_section("<!", "")) {
+            continue;
+        }
+        if (substr($0, 1, 2) == "</") { # is it a closing tag ?
+            XML_TYPE = "END";
+            $0 = substr($0, 3);
+        } else { # nope, it's an opening one
+            XML_TYPE = "BEGIN";
+            $0 = substr($0, 2);
+        }
+        XML_TAG = $0
+        sub("[ \r\n\t/].*$", "", XML_TAG);  # extract tag name
+        XML_TAG = toupper(XML_TAG);       # uppercase it
+        if ( XML_TAG !~ /^[A-Z][-+_.:0-9A-Z]*$/ )  # validate it
+            _xml_panic("Invalid tag name: " XML_TAG);
+        if (XML_TYPE == "BEGIN") {  # update reverse path
+            _xml_enter(XML_TAG);
+        } else {
+            _xml_exit(XML_TAG);
+        }
+        sub("[^ \r\n\t]*[ \r\n\t]*", "", $0); # get rid of tag and spaces
+        while ($0) { # process attributes
+            if ($0 == "/") {  # deal with direct closing tag, e.g. </foo>
+                _xml_closing = XML_TAG; # record delayed tag closure.
+                break
+            }
+            _xml_attrib = $0;
+            sub(/=.*$/,"",_xml_attrib);  # extract attribute name
+            sub(/^[^=]*/,"",$0);         # remove it from record
+            _xml_attrib = tolower(_xml_attrib);
+            if ( _xml_attrib !~ /^[a-z][-+_0-9a-z:]*$/ ) # validate it
+                _xml_panic("Invalid attribute name: " _xml_attrib);
+            if (substr($0,1,2) == "=\"") { # value is ="something"
+                _xml_value = substr($0,3);
+                sub(/".*$/,"",_xml_value);
+                sub(/^="[^"]*"/,"",$0);
+            } else if (substr($0,1,2) == "='") { # value is ='something'
+                _xml_value = substr($0,3);
+                sub(/'.*$/,"",_xml_value);
+                sub(/^='[^']*'/,"",$0);
+            } else {
+                _xml_panic("Invalid attribute value syntax for " _xml_attrib ": " $0);
+            }
+            XML_ATTR[_xml_attrib] = _xml_value;  # store attribute name/value
+            sub(/^[ \t\r\n]*/,"",$0); # get rid of remaining leading spaces
+        }
+        return 1; # now return, XML_TYPE/TAG/ATTR/RPATH are set
+    }
+}
+
+function _xml_panic (msg) {
+    print msg > "/dev/stderr"
+    exit(1)
+}
+
+function _xml_in_section (sec_begin, sec_end) {
+    if (!match( $0, "^" sec_begin )) return 0;
+    while (!match($0, sec_end "$")) {
+        if (getline <= 0) _xml_panic("Unexpected EOF: " ERRNO);
+    }
+    return 1;
+}
+
+function _xml_enter (tag) {
+    XML_RPATH = tag "/" XML_RPATH;
+}
+
+function _xml_exit (tag) {
+    _xml_p = index(XML_RPATH, "/");
+    _xml_expected = substr(XML_RPATH, 1, _xml_p-1);
+    if (_xml_expected != XML_TAG)
+        _xml_panic("Unexpected close tag: " XML_TAG ", expecting " _xml_expected);
+    XML_RPATH = substr(XML_RPATH, _xml_p+1);
+}
+
+# ---------------------------- cut here ---------------------------
+
+# USAGE:
+#
+# The functions provided here are used to extract the tags and attributes of a
+# given XML file. They do not support extraction of data, CDATA, comments,
+# processing instructions and declarations at all.
+#
+# You should use this from the BEGIN {} action of your awk script (it will
+# not work from an END {} action).
+#
+# Call xml_event() in a while loop. This functions returns 1 for each XML
+# 'event' encountered, or 0 when the end of input is reached. Note that in
+# case of malformed output, an error will be printed and the script will
+# force an exit(1)
+#
+# After each succesful xml_event() call, the following variables will be set:
+#
+#    XML_TYPE:  type of event: "BEGIN" -> mean an opening tag, "END" a
+#               closing one.
+#
+#    XML_TAG:   name of the tag, always in UPPERCASE!
+#
+#    XML_ATTR:  a map of attributes for the type. Only set for "BEGIN" types.
+#               all attribute names are in lowercase.
+#
+#               beware: values are *not* unescaped !
+#
+#    XML_RPATH: the _reversed_ element path, using "/" as a separator.
+#               if you are within the <manifest><application> tag, then
+#               it will be set to "APPLICATION/MANIFEST/"
+#               (note the trailing slash).
+#
+
+# This is a simple example that dumps the output of the parsing.
+#
+BEGIN {
+    while ( xml_event() ) {
+        printf "XML_TYPE=%s XML_TAG=%s XML_RPATH=%s", XML_TYPE, XML_TAG, XML_RPATH;
+        if (XML_TYPE == "BEGIN") {
+            for (attr in XML_ATTR) {
+                printf " %s='%s'", attr, XML_ATTR[attr];
+            }
+        }
+        printf "\n";
+    }
+}
+
+# IMPLEMENTATION DETAILS:
+#
+# 1. '>' as the record separator:
+#
+# RS is set to '>' to use this character as the record separator, instead of
+# the default '\n'. This means that something like the following:
+#
+#   <foo><bar attrib="value">stuff</bar></foo>
+#
+# will be translated into the following successive 'records':
+#
+#  <foo
+#  <bar attrib="value"
+#  stuff</bar
+#  </foo
+#
+# Note that the '>' is never part of the records and thus will not be matched.
+# If the record does not contain a single '<', the input is either
+# malformed XML, or we reached the end of file with data after the last
+# '>'.
+#
+# Newlines in the original input are kept in the records as-is.
+#
+# 2. Getting rid of unwanted stuff:
+#
+# We don't need any of the data within elements, so we get rid of them by
+# simply ignoring anything before the '<' in the current record. This is
+# done with code like this:
+#
+#     p = index($0, "<");       # get index of '<'
+#     if (p == 0) -> return 0;  # malformed input or end of file
+#     $0 = substr($0, p+1);     # remove anything before the '<' in record
+#
+# We also want to ignore certain sections like CDATA, comments, declarations,
+# etc.. These begin with a certain pattern and end with another one, e.g.
+# "<!--" and "-->" for comments. This is handled by the _xml_in_section()
+# function that accepts two patterns as input:
+#
+#    sec_begin: is the pattern for the start of the record.
+#    sec_end:   is the pattern for the end of the record (minus trailing '>').
+#
+# The function deals with the fact that these section can embed a valid '>'
+# and will then span multiple records, i.e. something like:
+#
+#  <!-- A comment with an embedded > right here ! -->
+#
+# will be decomposed into two records:
+#
+#   "<!-- A comment with an embedded "
+#   " right here ! --"
+#
+# The function deals with this case, and exits when such a section is not
+# properly terminated in the input.
+#
+# _xml_in_section() returns 1 if an ignorable section was found, or 0 otherwise.
+#
+# 3. Extracting the tag name:
+#
+# </foo> is a closing tag, and <foo> an opening tag, this is handled
+# by the following code:
+#
+#       if (substr($0, 1, 2) == "</") {
+#           XML_TYPE = "END";
+#           $0 = substr($0, 3);
+#       } else {
+#           XML_TYPE = "BEGIN";
+#           $0 = substr($0, 2);
+#       }
+#
+# which defines XML_TYPE, and removes the leading "</" or "<" from the record.
+# The tag is later extracted and converted to uppercase with:
+#
+#       XML_TAG = $0                        # copy record
+#       sub("[ \r\n\t/].*$", "", XML_TAG);  # remove anything after tag name
+#       XML_TAG = toupper(XML_TAG);         # conver to uppercase
+#       # validate tag
+#       if ( XML_TAG !~ /^[A-Z][-+_.:0-9A-Z]*$/ ) -> panic
+#
+# Then the record is purged from the tag name and the spaces after it:
+#
+#       # get rid of tag and spaces after it in $0
+#       sub("[^ \r\n\t]*[ \r\n\t]*", "", $0);
+#
+# 4. Maintaining XML_RPATH:
+#
+# The _xml_enter() and _xml_exit() functions are called to maintain the
+# XML_RPATH variable when entering and exiting specific tags. _xml_exit()
+# will also validate the input, checking proper tag enclosure (or exit(1)
+# in case of error).
+#
+#       if (XML_TYPE == "BEGIN") {
+#           _xml_enter(XML_TAG);
+#       } else {
+#           _xml_exit(XML_TAG);
+#       }
+#
+# 5. Extracting attributes:
+#
+# A loop is implemented to parse attributes, the idea is to get the attribute
+# name, which is always followed by a '=' character:
+#
+#           _xml_attrib = $0;              # copy record.
+#           sub(/=.*$/,"",_xml_attrib);    # get rid of '=' and anything after.
+#           sub(/^[^=]*/,"",$0);           # remove attribute name from $0
+#           _xml_attrib = tolower(_xml_attrib);
+#           if ( _xml_attrib !~ /^[a-z][-+_0-9a-z:]*$/ )
+#               _xml_panic("Invalid attribute name: " _xml_attrib);
+#
+# Now get the value, which is enclosed by either (") or (')
+#
+#          if (substr($0,1,2) == "=\"") {        # if $0 begins with ="
+#               _xml_value = substr($0,3);       # extract value
+#               sub(/".*$/,"",_xml_value);  
+#               sub(/^="[^"]*"/,"",$0);          # remove it from $0
+#           } else if (substr($0,1,2) == "='") { # if $0 begins with ='
+#               _xml_value = substr($0,3);       # extract value
+#               sub(/'.*$/,"",_xml_value);
+#               sub(/^='[^']*'/,"",$0);          # remove it from $0
+#           } else {
+#               -> panic (malformed input)
+#           }
+#
+# After that, we simply store the value into the XML_ATTR associative
+# array, and cleanup $0 from leading spaces:
+#
+#           XML_ATTR[_xml_attrib] = _xml_value;
+#           sub(/^[ \t\r\n]*/,"",$0);
+#
+#
+# 6. Handling direct tag closure:
+#
+# When a tag is closed directly (as in <foo/>), A single '/' will be
+# parsed in the attribute parsing loop. We need to record this for the
+# next call to xml_event(), since the current one should return a"BEGIN"
+# for the "FOO" tag instead.
+#
+# We do this by setting the special _xml_closing variable, as in:
+#
+#          if ($0 == "/") {
+#               # record a delayed tag closure for the next call
+#               _xml_closing = XML_TAG;
+#               break
+#           }
+#
+# This variable is checked at the start of xml_event() like this:
+#
+#       # delayed tag closure - see below
+#       if (_xml_closing) {
+#           XML_TAG = _xml_closing;
+#           XML_TYPE = "END";
+#           _xml_closing = "";
+#           _xml_exit(XML_TAG);
+#           return 1;
+#       }
+#
+# Note the call to _xml_exit() to update XML_RPATH here.
+#
diff --git a/build/cmake/android.toolchain.cmake b/build/cmake/android.toolchain.cmake
new file mode 100644
index 0000000..c2a9227
--- /dev/null
+++ b/build/cmake/android.toolchain.cmake
@@ -0,0 +1,633 @@
+# 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)
+
+# Android NDK
+get_filename_component(ANDROID_NDK "${CMAKE_CURRENT_LIST_DIR}/../.." ABSOLUTE)
+file(TO_CMAKE_PATH "${ANDROID_NDK}" ANDROID_NDK)
+
+# Android NDK revision
+file(READ "${ANDROID_NDK}/source.properties" ANDROID_NDK_SOURCE_PROPERTIES)
+set(ANDROID_NDK_SOURCE_PROPERTIES_REGEX
+	"^Pkg\\.Desc = Android NDK\nPkg\\.Revision = ([0-9]+)\\.")
+if(NOT ANDROID_NDK_SOURCE_PROPERTIES MATCHES "${ANDROID_NDK_SOURCE_PROPERTIES_REGEX}")
+	message(SEND_ERROR "Failed to parse Android NDK revision: ${ANDROID_NDK}/source.properties.\n${ANDROID_NDK_SOURCE_PROPERTIES}")
+endif()
+string(REGEX REPLACE "${ANDROID_NDK_SOURCE_PROPERTIES_REGEX}" "\\1"
+	ANDROID_NDK_REVISION "${ANDROID_NDK_SOURCE_PROPERTIES}")
+
+# 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)
+endif()
+if(NOT ANDROID_ABI)
+	set(ANDROID_ABI armeabi-v7a)
+endif()
+if(ANDROID_PLATFORM MATCHES "^android-([0-8]|10|11)$")
+	set(ANDROID_PLATFORM android-9)
+elseif(ANDROID_PLATFORM STREQUAL android-20)
+	set(ANDROID_PLATFORM android-19)
+elseif(NOT ANDROID_PLATFORM)
+	set(ANDROID_PLATFORM android-9)
+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 gnustl_static)
+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)
+set(CMAKE_SYSTEM_VERSION ${ANDROID_PLATFORM_LEVEL})
+set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
+set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
+set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
+
+# ABI.
+set(CMAKE_ANDROID_ARCH_ABI ${ANDROID_ABI})
+if(ANDROID_ABI MATCHES "^armeabi(-v7a)?$")
+	set(ANDROID_SYSROOT_ABI arm)
+	set(ANDROID_TOOLCHAIN_NAME arm-linux-androideabi)
+	set(ANDROID_TOOLCHAIN_ROOT ${ANDROID_TOOLCHAIN_NAME})
+	if(ANDROID_ABI STREQUAL armeabi)
+		set(CMAKE_SYSTEM_PROCESSOR armv5te)
+		set(ANDROID_LLVM_TRIPLE armv5te-none-linux-androideabi)
+	elseif(ANDROID_ABI STREQUAL armeabi-v7a)
+		set(CMAKE_SYSTEM_PROCESSOR armv7-a)
+		set(ANDROID_LLVM_TRIPLE armv7-none-linux-androideabi)
+	endif()
+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)
+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)
+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)
+elseif(ANDROID_ABI STREQUAL mips)
+	set(ANDROID_SYSROOT_ABI mips)
+	set(CMAKE_SYSTEM_PROCESSOR mips)
+	set(ANDROID_TOOLCHAIN_NAME mipsel-linux-android)
+	set(ANDROID_TOOLCHAIN_ROOT ${ANDROID_TOOLCHAIN_NAME})
+	set(ANDROID_LLVM_TRIPLE mipsel-none-linux-android)
+elseif(ANDROID_ABI STREQUAL mips64)
+	set(ANDROID_SYSROOT_ABI mips64)
+	set(CMAKE_SYSTEM_PROCESSOR mips64)
+	set(ANDROID_TOOLCHAIN_NAME mips64el-linux-android)
+	set(ANDROID_TOOLCHAIN_ROOT ${ANDROID_TOOLCHAIN_NAME})
+	set(ANDROID_LLVM_TRIPLE mips64el-none-linux-android)
+else()
+	message(FATAL_ERROR "Invalid Android ABI: ${ANDROID_ABI}.")
+endif()
+
+# STL.
+set(ANDROID_STL_STATIC_LIBRARIES)
+set(ANDROID_STL_SHARED_LIBRARIES)
+if(ANDROID_STL STREQUAL system)
+	set(ANDROID_STL_STATIC_LIBRARIES
+		supc++)
+elseif(ANDROID_STL STREQUAL stlport_static)
+	set(ANDROID_STL_STATIC_LIBRARIES
+		stlport_static)
+elseif(ANDROID_STL STREQUAL stlport_shared)
+	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)
+	set(ANDROID_STL_STATIC_LIBRARIES
+		c++_static
+		c++abi
+		unwind
+		android_support)
+elseif(ANDROID_STL STREQUAL c++_shared)
+	set(ANDROID_STL_STATIC_LIBRARIES
+		unwind)
+	set(ANDROID_STL_SHARED_LIBRARIES
+		c++_shared)
+elseif(ANDROID_STL STREQUAL none)
+else()
+	message(FATAL_ERROR "Invalid Android STL: ${ANDROID_STL}.")
+endif()
+
+# Sysroot.
+set(CMAKE_SYSROOT "${ANDROID_NDK}/platforms/${ANDROID_PLATFORM}/arch-${ANDROID_SYSROOT_ABI}")
+
+# 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()
+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}")
+	# 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_TARGET   ${ANDROID_LLVM_TRIPLE})
+	set(CMAKE_CXX_COMPILER_TARGET ${ANDROID_LLVM_TRIPLE})
+	set(CMAKE_C_COMPILER_EXTERNAL_TOOLCHAIN   "${ANDROID_TOOLCHAIN_ROOT}")
+	set(CMAKE_CXX_COMPILER_EXTERNAL_TOOLCHAIN "${ANDROID_TOOLCHAIN_ROOT}")
+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}")
+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()
+
+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)
+
+# Generic flags.
+list(APPEND ANDROID_COMPILER_FLAGS
+	-g
+	-DANDROID
+	-ffunction-sections
+	-funwind-tables
+	-fstack-protector-strong
+	-no-canonical-prefixes)
+list(APPEND ANDROID_COMPILER_FLAGS_CXX
+	-fno-exceptions
+	-fno-rtti)
+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 MATCHES "^armeabi" AND ANDROID_TOOLCHAIN STREQUAL clang)
+	# Disable integrated-as for better compatibility.
+	list(APPEND ANDROID_COMPILER_FLAGS
+		-fno-integrated-as)
+endif()
+if(ANDROID_ABI STREQUAL mips AND ANDROID_TOOLCHAIN STREQUAL clang)
+	list(APPEND ANDROID_COMPILER_FLAGS
+		-mips32)
+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)
+	else()
+		list(REMOVE_ITEM ANDROID_STL_STATIC_LIBRARIES
+			unwind)
+	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()
+	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()
+if(ANDROID_ABI STREQUAL armeabi AND NOT ANDROID_STL MATCHES "^(none|system)$")
+	list(APPEND ANDROID_CXX_STANDARD_LIBRARIES
+		-latomic)
+endif()
+set(CMAKE_C_STANDARD_LIBRARIES_INIT "-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.
+if(ANDROID_PIE)
+	set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)
+	list(APPEND ANDROID_LINKER_FLAGS_EXE
+		-pie
+		-fPIE)
+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_TOOLCHAIN_PREFIX "${ANDROID_TOOLCHAIN_PREFIX}")
+
+# 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_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_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_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_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_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_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()
diff --git a/build/core/add-application.mk b/build/core/add-application.mk
new file mode 100644
index 0000000..d6a00c9
--- /dev/null
+++ b/build/core/add-application.mk
@@ -0,0 +1,305 @@
+# 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
+
+ifeq (null,$(APP_PROJECT_PATH))
+
+ifndef APP_PLATFORM
+    APP_PLATFORM := android-9
+    $(call ndk_log,  Defaulted to APP_PLATFORM=$(APP_PLATFORM))
+endif
+
+else
+
+# check whether APP_PLATFORM is defined. If not, look for project.properties in
+# the $(APP_PROJECT_PATH) and extract the value with awk's help. If nothing is here,
+# revert to the default value (i.e. "android-3").
+#
+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_AWK) -f $(BUILD_AWK)/extract-platform.awk $(call host-path,$(_local_props))))
+        $(call ndk_log,  Found APP_PLATFORM=$(APP_PLATFORM) in $(_local_props))
+    else
+        APP_PLATFORM := android-9
+        $(call ndk_log,  Defaulted to APP_PLATFORM=$(APP_PLATFORM))
+    endif
+endif
+
+ifeq ($(APP_PLATFORM),android-L)
+$(call __ndk_warning,WARNING: android-L is renamed as android-21)
+override APP_PLATFORM := android-21
+endif
+
+endif # APP_PROJECT_PATH == null
+
+# SPECIAL CASES:
+# 1) android-6 and android-7 are the same thing as android-5
+# 2) android-10 and android-11 are the same thing as android-9
+# 3) android-20 is the same thing as android-19
+# ADDITIONAL CASES for remote server where total number of files is limited
+# 5) android-13 is the same thing as android-12
+# 6) android-15 is the same thing as android-14
+# 7) android-17 is the same thing as android-16
+APP_PLATFORM_LEVEL := $(strip $(subst android-,,$(APP_PLATFORM)))
+ifneq (,$(filter 6 7,$(APP_PLATFORM_LEVEL)))
+    override APP_PLATFORM := android-5
+endif
+ifneq (,$(filter 10 11,$(APP_PLATFORM_LEVEL)))
+    override APP_PLATFORM := android-9
+endif
+ifneq (,$(filter 20,$(APP_PLATFORM_LEVEL)))
+    override APP_PLATFORM := android-19
+endif
+
+ifneq ($(strip $(subst android-,,$(APP_PLATFORM))),$(APP_PLATFORM_LEVEL))
+    $(call ndk_log,  Adjusting APP_PLATFORM android-$(APP_PLATFORM_LEVEL) to $(APP_PLATFORM))
+endif
+
+# 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_PLATFORM corresponds to a known platform
+# If not, we're going to use the max supported platform value.
+#
+_bad_platform := $(strip $(filter-out $(NDK_ALL_PLATFORMS),$(APP_PLATFORM)))
+ifdef _bad_platform
+    $(call ndk_log,Application $(_app) targets unknown platform '$(_bad_platform)')
+    override APP_PLATFORM := android-$(NDK_MAX_PLATFORM_LEVEL)
+    $(call ndk_log,Switching to $(APP_PLATFORM))
+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
+  APP_MIN_PLATFORM_LEVEL := $(strip $(shell $(HOST_AWK) -f $(BUILD_AWK)/extract-minsdkversion.awk $(call host-path,$(APP_MANIFEST))))
+  ifdef APP_MIN_PLATFORM_LEVEL
+    ifneq (,$(call gt,$(APP_PLATFORM_LEVEL),$(APP_MIN_PLATFORM_LEVEL)))
+      $(call __ndk_info,WARNING: APP_PLATFORM $(APP_PLATFORM) is larger than android:minSdkVersion $(APP_MIN_PLATFORM_LEVEL) in $(APP_MANIFEST))
+    endif
+  endif
+endif
+
+endif # APP_PROJECT_PATH == null
+
+# 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
+ifneq ($(APP_ABI),all)
+    _bad_abis := $(strip $(filter-out $(NDK_ALL_ABIS),$(APP_ABIS)))
+    ifdef _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)
+        endif
+        $(call __ndk_info,Application $(_app) targets unknown ABI '$(_bad_abis)')
+        $(call __ndk_info,Please fix the APP_ABI definition in $(_application_mk))
+        $(call __ndk_info,to use a set of the following values: $(NDK_ALL_ABIS))
+        $(call __ndk_error,Aborting)
+    endif
+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_AWK) -f $(BUILD_AWK)/extract-debuggable.awk $(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
+
+$(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..2215667
--- /dev/null
+++ b/build/core/add-toolchain.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 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)
+
+# Plug in the undefined
+ifeq ($(TOOLCHAIN_ABIS)$(TOOLCHAIN_ARCH),)
+ifeq (1,$(words $(filter-out $(NDK_KNOWN_ARCHS),$(NDK_FOUND_ARCHS))))
+TOOLCHAIN_ARCH := $(filter-out $(NDK_KNOWN_ARCHS),$(NDK_FOUND_ARCHS))
+TOOLCHAIN_ABIS := $(TOOLCHAIN_ARCH) $(NDK_KNOWN_ABIS:%=$(TOOLCHAIN_ARCH)%) $(NDK_KNOWN_ABIS:%=$(TOOLCHAIN_ARCH)bc%)
+endif
+endif
+
+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..b684e51
--- /dev/null
+++ b/build/core/build-all.mk
@@ -0,0 +1,152 @@
+# 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
+
+# On Cygwin, we generate a temporary shell script that is capable of
+# process GCC-generated dependency files to convert all path references
+# in them from the Windows to the corresponding Cygwin convention.
+# (e.g. C:/Foo/foo -> /cygdrive/c/Foo/foo)
+#
+# This shell script is generated by passing the output of the cygwin
+# 'mount' command to a special Awk script.
+#
+ifeq ($(HOST_OS),cygwin)
+  GEN_CYGWIN_DEPS_CONVERTER := mount | tr '\\' '/' | awk -f $(BUILD_AWK)/gen-cygwin-deps-converter.awk
+  ifeq ($(NDK_LOG),1)
+    $(call __ndk_info,Cygwin dependency file conversion script:)
+    $(info ----- start of script ----)
+    $(info $(shell $(GEN_CYGWIN_DEPS_CONVERTER)))
+    $(info ------ end of script -----)
+  endif
+$(NDK_DEPENDENCIES_CONVERTER):
+	$(call host-echo-build-step,$(NDK_APP_ABI),Cygwin) Generating dependency file converter script
+	$(hide) mkdir -p $(dir $@)
+	$(hide) $(GEN_CYGWIN_DEPS_CONVERTER) > $@ && chmod +x $@
+
+clean-dependency-converter:
+	$(hide) $(call host-rm,$(NDK_DEPENDENCIES_CONVERTER))
+
+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))
+
+ifeq ($(HOST_OS),cygwin)
+clean: clean-dependency-converter
+endif
+	
+# 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..4610338
--- /dev/null
+++ b/build/core/build-binary.mk
@@ -0,0 +1,753 @@
+# 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))
+
+# 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 := \
+    android \
+    c \
+    dl \
+    jnigraphics \
+    log \
+    m \
+    m_hard \
+    stdc++ \
+    z \
+    EGL \
+    GLESv1_CM \
+    GLESv2 \
+    GLESv3 \
+    vulkan \
+    OpenSLES \
+    OpenMAXAL \
+    mediandk \
+    atomic
+
+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)
+
+#
+# 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
+
+#
+# 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)))
+      LOCAL_CFLAGS += -fPIE
+      LOCAL_LDFLAGS += -fPIE -pie
+    endif
+  endif
+endif
+
+# http://b.android.com/222239
+# Older x86 devices had stack alignment issues.
+ifneq (,$(call lt,$(APP_PLATFORM_LEVEL),21))
+    ifeq ($(TARGET_ARCH_ABI),x86)
+        LOCAL_CFLAGS += -mstackrealign
+    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
+
+# If we're using the 'system' STL and use rtti or exceptions, then
+# automatically link against the GNU libsupc++ for now.
+#
+ifneq (,$(call module-has-c++-features,$(LOCAL_MODULE),rtti exceptions))
+    ifeq (system,$(NDK_APP_STL))
+      LOCAL_LDLIBS := $(LOCAL_LDLIBS) $(call host-path,$(NDK_ROOT)/sources/cxx-stl/gnu-libstdc++/4.9/libs/$(TARGET_ARCH_ABI)/libsupc++$(TARGET_LIB_EXTENSION))
+    endif
+endif
+
+# Set include patch for renderscript
+
+
+ifneq ($(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE),)
+    LOCAL_RENDERSCRIPT_INCLUDES := $(LOCAL_RENDERSCRIPT_INCLUDES_OVERRIDE)
+else
+    LOCAL_RENDERSCRIPT_INCLUDES := \
+        $(RENDERSCRIPT_TOOLCHAIN_HEADER) \
+        $(LOCAL_RENDERSCRIPT_INCLUDES)
+endif
+
+RS_COMPAT :=
+ifneq ($(call module-is-shared-library,$(LOCAL_MODULE)),)
+    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
+#
+
+$(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_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,$(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)
+$(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))
+
+$(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..aac5be4
--- /dev/null
+++ b/build/core/build-local.mk
@@ -0,0 +1,231 @@
+# 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
+
+# For cygwin, put generated dependency conversion script here
+# Do not define this variable for other host platforms
+#
+ifeq ($(HOST_OS),cygwin)
+NDK_DEPENDENCIES_CONVERTER := $(NDK_APP_OUT)/convert-dependencies.sh
+endif
+
+# 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)\
+)
+
+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..d0ab95d
--- /dev/null
+++ b/build/core/build-module.mk
@@ -0,0 +1,34 @@
+# 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))
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..08c3b19
--- /dev/null
+++ b/build/core/clear-vars.mk
@@ -0,0 +1,25 @@
+# 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,
+
+$(call clear-src-tags)
+
+# 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..49f1bb2
--- /dev/null
+++ b/build/core/default-build-commands.mk
@@ -0,0 +1,167 @@
+# 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) $(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
+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.
+#
+
+ifneq ($(findstring ccc-analyzer,$(CC)),)
+TARGET_CC       = $(CC)
+else
+TARGET_CC       = $(TOOLCHAIN_PREFIX)gcc
+endif
+TARGET_CFLAGS   =
+TARGET_CONLYFLAGS =
+
+ifneq ($(findstring c++-analyzer,$(CXX)),)
+TARGET_CXX      = $(CXX)
+else
+TARGET_CXX      = $(TOOLCHAIN_PREFIX)g++
+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, except for
+# gcc4.6 which doesn't have gcc-ar
+ifneq (clang,$(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..a86cd10
--- /dev/null
+++ b/build/core/definitions-utils.mk
@@ -0,0 +1,265 @@
+# 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 := :
+
+# -----------------------------------------------------------------------------
+# 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))\
+
diff --git a/build/core/definitions.mk b/build/core/definitions.mk
new file mode 100644
index 0000000..8304a6e
--- /dev/null
+++ b/build/core/definitions.mk
@@ -0,0 +1,2136 @@
+# 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,$$@.tmp,$$@)
+	$$(hide) $$(call host-rm,$$@.tmp)
+
+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 \
+    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_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)
+
+# -----------------------------------------------------------------------------
+# 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))\
+    )
+
+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))\
+
+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))
+
+
+# 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),\
+        )\
+    )
+
+
+# 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 \
+
+# 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)
+
+# cmd-convert-deps
+#
+# On Cygwin, we need to convert the .d dependency file generated by
+# the gcc toolchain by transforming any Windows paths inside it into
+# Cygwin paths that GNU Make can understand (i.e. C:/Foo => /cygdrive/c/Foo)
+#
+# To do that, we will force the compiler to write the dependency file to
+# <foo>.d.org, which will will later convert through a clever sed script
+# that is auto-generated by our build system.
+#
+# The script is invoked with:
+#
+#    $(NDK_DEPENDENCIES_CONVERTER) foo.d
+#
+# It will look if foo.d.org exists, and if so, process it
+# to generate foo.d, then remove the original foo.d.org.
+#
+# On other systems, we simply tell the compiler to write to the .d file directly.
+#
+# NOTE: In certain cases, no dependency file will be generated by the
+#       compiler (e.g. when compiling an assembly file as foo.s)
+#
+# convert-deps is used to compute the name of the compiler-generated dependency file
+# cmd-convert-deps is a command used to convert it to a Cygwin-specific path
+#
+ifeq ($(HOST_OS),cygwin)
+convert-deps = $1.org
+cmd-convert-deps = && $(NDK_DEPENDENCIES_CONVERTER) $1
+else
+convert-deps = $1
+cmd-convert-deps =
+endif
+
+# 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) $$(NDK_DEPENDENCIES_CONVERTER) $(LOCAL_RS_OBJECTS)
+	$$(call host-echo-build-step,$$(PRIVATE_ABI),$$(PRIVATE_TEXT)) "$$(PRIVATE_MODULE) <= $$(notdir $$(PRIVATE_SRC))"
+	$$(hide) $$(PRIVATE_CC) -MMD -MP -MF $$(call convert-deps,$$(PRIVATE_DEPS)) $$(PRIVATE_CFLAGS) $$(call host-path,$$(PRIVATE_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ)) \
+	$$(call cmd-convert-deps,$$(PRIVATE_DEPS))
+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_LDFLAGS   := $$(_LD_FLAGS)
+$$(_OBJ): PRIVATE_OUT       := $$(NDK_APP_DST_DIR)
+$$(_OBJ): PRIVATE_RS_TRIPLE := $$(RS_TRIPLE)
+$$(_OBJ): PRIVATE_COMPAT    := $$(_COMPAT)
+
+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
+
+# 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)
+$$(_OBJ): $$(_RS_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) $$(NDK_DEPENDENCIES_CONVERTER)
+	$$(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 $$(call host-path,$(SYSROOT_LINK)/usr/lib/rs/libclcore.bc) -mtriple $$(PRIVATE_RS_TRIPLE) $$(call host-path,$$(PRIVATE_BC_SRC)) && \
+	$$(PRIVATE_CXX) -shared -Wl,-soname,librs.$$(PRIVATE_BC_SO) -nostdlib $$(call host-path,$$(PRIVATE_BC_OBJ)) $$(call host-path,$(SYSROOT_LINK)/usr/lib/rs/libcompiler_rt.a) -o $$(call host-path,$$(PRIVATE_OUT)/librs.$$(PRIVATE_BC_SO)) -L $$(call host-path,$(SYSROOT_LINK)/usr/lib) -L $$(call host-path,$(SYSROOT_LINK)/usr/lib/rs) $$(PRIVATE_LDFLAGS) -lRSSupport -lm -lc && \
+	$$(PRIVATE_CXX) -MMD -MP -MF $$(call convert-deps,$$(PRIVATE_DEPS)) $$(PRIVATE_CPPFLAGS) $$(call host-path,$$(PRIVATE_CPP_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ)) \
+	$$(call cmd-convert-deps,$$(PRIVATE_DEPS))
+else
+$$(_OBJ): $$(_RS_SRC) $$(LOCAL_MAKEFILE) $$(NDK_APP_APPLICATION_MK) $$(NDK_DEPENDENCIES_CONVERTER)
+	$$(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 $$(call convert-deps,$$(PRIVATE_DEPS)) $$(PRIVATE_CPPFLAGS) $$(call host-path,$$(PRIVATE_CPP_SRC)) -o $$(call host-path,$$(PRIVATE_OBJ)) \
+	$$(call cmd-convert-deps,$$(PRIVATE_DEPS))
+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)) \
+          $$(LOCAL_CFLAGS) \
+          $$(LOCAL_CONLYFLAGS) \
+          $$(NDK_APP_CFLAGS) \
+          $$(NDK_APP_CONLYFLAGS) \
+          -isystem $$(call host-path,$$(SYSROOT_INC)/usr/include) \
+          -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)) \
+          $$(LOCAL_CFLAGS) \
+          $$(LOCAL_ASFLAGS) \
+          $$(NDK_APP_CFLAGS) \
+          $$(NDK_APP_ASFLAGS) \
+          -isystem $$(call host-path,$$(SYSROOT_INC)/usr/include) \
+          -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) \
+          -isystem $$(call host-path,$$(SYSROOT_INC)/usr/include) \
+          $$(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) $$(NDK_DEPENDENCIES_CONVERTER) $(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)) \
+          $$(LOCAL_CFLAGS) \
+          $$(LOCAL_CPPFLAGS) \
+          $$(LOCAL_CXXFLAGS) \
+          $$(NDK_APP_CFLAGS) \
+          $$(NDK_APP_CPPFLAGS) \
+          $$(NDK_APP_CXXFLAGS) \
+          -isystem $$(call host-path,$$(SYSROOT_INC)/usr/include) \
+          -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)) \
+          $$(LOCAL_CFLAGS) \
+          $$(LOCAL_CPPFLAGS) \
+          $$(LOCAL_CXXFLAGS) \
+          $$(NDK_APP_CFLAGS) \
+          $$(NDK_APP_CPPFLAGS) \
+          $$(NDK_APP_CXXFLAGS) \
+          -isystem $$(call host-path,$$(SYSROOT_INC)/usr/include) \
+          -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 name (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: list of ldlibs to be exported to all modules
+#
+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).EXPORT_LDLIBS := $(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))
+
+# 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 libc++abi libunwind android_support,\
+    ,\
+    -ldl\
+    )
+
+# Register the 'c++_shared' STL implementation
+#
+$(call ndk-stl-register,\
+    c++_shared,\
+    cxx-stl/llvm-libc++,\
+    libandroid_support libunwind,\
+    c++_shared,\
+    \
+    )
+
+# 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/import-locals.mk b/build/core/import-locals.mk
new file mode 100644
index 0000000..5b9973d
--- /dev/null
+++ b/build/core/import-locals.mk
@@ -0,0 +1,77 @@
+# 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,$(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)
+
+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 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))
+
+#
+# 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..fad5240
--- /dev/null
+++ b/build/core/init.mk
@@ -0,0 +1,650 @@
+# 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
+
+# Always use /usr/bin/file on Darwin to avoid relying on broken Ports
+# version. See http://b.android.com/53769 .
+HOST_FILE_PROGRAM := file
+ifeq ($(HOST_OS),darwin)
+HOST_FILE_PROGRAM := /usr/bin/file
+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
+    else # HOST_OS_BASE != windows
+        UNAME := $(shell uname -m)
+        ifneq (,$(findstring 86,$(UNAME)))
+            HOST_ARCH := x86
+            ifneq (,$(shell $(HOST_FILE_PROGRAM) -L $(SHELL) | grep 'x86[_-]64'))
+                HOST_ARCH64 := x86_64
+            endif
+        endif
+        # We should probably should not care at all
+        ifneq (,$(findstring Power,$(UNAME)))
+            HOST_ARCH := ppc
+        endif
+        ifeq ($(HOST_ARCH),)
+            $(call __ndk_info,Unsupported host architecture: $(UNAME))
+            $(call __ndk_error,Aborting)
+        endif
+    endif # HOST_OS_BASE != windows
+    $(call ndk_log,Host CPU was auto-detected: $(HOST_ARCH))
+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_AWK := $(strip $(NDK_HOST_AWK))
+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_AWK
+            HOST_AWK := $(wildcard $(HOST_PREBUILT)/awk$(HOST_EXEEXT))
+        endif
+        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
+
+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))
+
+#
+# Verify that the 'awk' tool has the features we need.
+# Both Nawk and Gawk do.
+#
+HOST_AWK := $(strip $(HOST_AWK))
+ifndef HOST_AWK
+    HOST_AWK := awk
+endif
+$(call ndk_log,Host 'awk' tool: $(HOST_AWK))
+
+# Location of all awk scripts we use
+BUILD_AWK := $(NDK_ROOT)/build/awk
+
+AWK_TEST := $(shell $(HOST_AWK) -f $(BUILD_AWK)/check-awk.awk)
+$(call ndk_log,Host 'awk' test returned: $(AWK_TEST))
+ifneq ($(AWK_TEST),Pass)
+    $(call __ndk_info,Host 'awk' tool is outdated. Please define NDK_HOST_AWK to point to Gawk or Nawk !)
+    $(call __ndk_error,Aborting.)
+endif
+
+#
+# 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 an awk script to generate a Makefile fragment used to define a function
+        WINDOWS_HOST_PATH_FRAGMENT := $(shell mount | tr '\\' '/' | $(HOST_AWK) -f $(BUILD_AWK)/gen-windows-host-path.awk)
+        ifeq ($(NDK_LOG),1)
+            $(info Using cygwin substitution rules:)
+            $(eval $(shell mount | tr '\\' '/' | $(HOST_AWK) -f $(BUILD_AWK)/gen-windows-host-path.awk -vVERBOSE=1))
+        endif
+        $(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_info,Please run build/tools/gen-platforms.sh to build the corresponding 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_PREVIEW_LEVEL := L
+NDK_ALL_PLATFORM_LEVELS := $(filter android-%,$(NDK_ALL_PLATFORMS))
+NDK_ALL_PLATFORM_LEVELS := $(patsubst android-%,%,$(NDK_ALL_PLATFORM_LEVELS))
+ifneq (,$(filter $(NDK_PREVIEW_LEVEL),$(NDK_ALL_PLATFORM_LEVELS)))
+    $(call __ndk_info,Please remove stale preview platforms/android-$(NDK_PREVIEW_LEVEL))
+    $(call __ndk_info,API level android-L is renamed as android-21.)
+    $(call __ndk_error,Aborting)
+endif
+$(call ndk_log,Found stable platform levels: $(NDK_ALL_PLATFORM_LEVELS))
+
+NDK_MAX_PLATFORM_LEVEL := 3
+$(foreach level,$(NDK_ALL_PLATFORM_LEVELS),\
+  $(eval NDK_MAX_PLATFORM_LEVEL := $$(call max,$$(NDK_MAX_PLATFORM_LEVEL),$$(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
+
+# the list of known abis and archs
+NDK_KNOWN_DEVICE_ABI64S := arm64-v8a x86_64 mips64
+NDK_KNOWN_DEVICE_ABI32S := armeabi-v7a armeabi x86 mips
+NDK_KNOWN_DEVICE_ABIS := $(NDK_KNOWN_DEVICE_ABI64S) $(NDK_KNOWN_DEVICE_ABI32S)
+NDK_KNOWN_ABIS     := $(NDK_KNOWN_DEVICE_ABIS)
+NDK_KNOWN_ABI32S   := $(NDK_KNOWN_DEVICE_ABI32S)
+NDK_KNOWN_ARCHS    := arm x86 mips arm64 x86_64 mips64
+_archs := $(sort $(strip $(notdir $(wildcard $(NDK_PLATFORMS_ROOT)/android-*/arch-*))))
+NDK_FOUND_ARCHS    := $(_archs:arch-%=%)
+
+# the list of abis 'APP_ABI=all' is expanded to
+ifneq (,$(filter yes all all32 all64,$(_NDK_TESTING_ALL_)))
+NDK_APP_ABI_ALL_EXPANDED := $(NDK_KNOWN_ABIS)
+NDK_APP_ABI_ALL32_EXPANDED := $(NDK_KNOWN_ABI32S)
+else
+NDK_APP_ABI_ALL_EXPANDED := $(NDK_KNOWN_DEVICE_ABIS)
+NDK_APP_ABI_ALL32_EXPANDED := $(NDK_KNOWN_DEVICE_ABI32S)
+endif
+NDK_APP_ABI_ALL64_EXPANDED := $(NDK_KNOWN_DEVICE_ABI64S)
+
+# For testing purpose
+ifeq ($(_NDK_TESTING_ALL_),all32)
+NDK_APP_ABI_ALL_EXPANDED := $(NDK_APP_ABI_ALL32_EXPANDED)
+else
+ifeq ($(_NDK_TESTING_ALL_),all64)
+NDK_APP_ABI_ALL_EXPANDED := $(NDK_APP_ABI_ALL64_EXPANDED)
+endif
+endif
+
+# 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))
+
+NDK_DEFAULT_ABIS := all
+
+# 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 -> mipsel-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/main.mk b/build/core/main.mk
new file mode 100644
index 0000000..76bdb2a
--- /dev/null
+++ b/build/core/main.mk
@@ -0,0 +1,138 @@
+# 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.
+#
+
+# ====================================================================
+#
+# Define the main configuration variables, and read the host-specific
+# configuration file that is normally generated by build/host-setup.sh
+#
+# ====================================================================
+
+# Detect the NDK installation path by processing this Makefile's location.
+# This assumes we are located under $NDK_ROOT/build/core/main.mk
+#
+NDK_ROOT := $(lastword $(MAKEFILE_LIST))
+NDK_ROOT := $(strip $(NDK_ROOT:%build/core/main.mk=%))
+ifeq ($(NDK_ROOT),)
+    # for the case when we're invoked from the NDK install path
+    NDK_ROOT := .
+else
+    # get rid of trailing slash
+    NDK_ROOT := $(NDK_ROOT:%/=%)
+endif
+ifeq ($(NDK_LOG),1)
+    $(info Android NDK: NDK installation path auto-detected: '$(NDK_ROOT)')
+endif
+
+include $(NDK_ROOT)/build/core/init.mk
+
+# ====================================================================
+#
+# Read all application configuration files
+#
+# Each 'application' must have a corresponding Application.mk file
+# located in apps/<name> where <name> is a liberal name that doesn't
+# contain any space in it, used to uniquely identify the
+#
+# See docs/ANDROID-MK.TXT for their specification.
+#
+# ====================================================================
+
+NDK_ALL_APPS :=
+NDK_APPS_ROOT := $(NDK_ROOT)/apps
+
+# Get the list of apps listed under apps/*
+NDK_APPLICATIONS := $(wildcard $(NDK_APPS_ROOT)/*)
+NDK_ALL_APPS     := $(NDK_APPLICATIONS:$(NDK_APPS_ROOT)/%=%)
+
+# Check that APP is not empty
+APP := $(strip $(APP))
+ifndef APP
+  $(call __ndk_info,\
+    The APP variable is undefined or empty.)
+  $(call __ndk_info,\
+    Please define it to one of: $(NDK_ALL_APPS))
+  $(call __ndk_info,\
+    You can also add new applications by writing an Application.mk file.)
+  $(call __ndk_info,\
+    See docs/APPLICATION-MK.TXT for details.)
+  $(call __ndk_error, Aborting)
+endif
+
+# Check that all apps listed in APP do exist
+_bad_apps := $(strip $(filter-out $(NDK_ALL_APPS),$(APP)))
+ifdef _bad_apps
+  $(call __ndk_info,\
+    APP variable defined to unknown applications: $(_bad_apps))
+  $(call __ndk_info,\
+    You might want to use one of the following: $(NDK_ALL_APPS))
+  $(call __ndk_error, Aborting)
+endif
+
+# Check that all apps listed in APP have an Application.mk
+
+$(foreach _app,$(APP),\
+  $(eval _application_mk := $(strip $(wildcard $(NDK_ROOT)/apps/$(_app)/Application.mk))) \
+  $(call ndk_log,Parsing $(_application_mk))\
+  $(if $(_application_mk),\
+    $(eval include $(BUILD_SYSTEM)/add-application.mk)\
+  ,\
+    $(call __ndk_info,\
+      Missing file: apps/$(_app)/Application.mk !)\
+    $(call __ndk_error, Aborting)\
+  )\
+)
+
+# clean up environment, just to be safe
+$(call clear-vars, $(NDK_APP_VARS))
+
+ifeq ($(strip $(NDK_ALL_APPS)),)
+  $(call __ndk_info,\
+    The NDK could not find a proper application description under apps/*/Application.mk)
+  $(call __ndk_info,\
+    Please follow the instructions in docs/NDK-APPS.TXT to write one.)
+  $(call __ndk_error, Aborting)
+endif
+
+# now check that APP doesn't contain an unknown app name
+# if it does, we ignore them if there is at least one known
+# app name in the list. Otherwise, abort with an error message
+#
+_unknown_apps := $(filter-out $(NDK_ALL_APPS),$(APP))
+_known_apps   := $(filter     $(NDK_ALL_APPS),$(APP))
+
+NDK_APPS := $(APP)
+
+$(if $(_unknown_apps),\
+  $(if $(_known_apps),\
+    $(call __ndk_info,WARNING:\
+        Removing unknown names from APP variable: $(_unknown_apps))\
+    $(eval NDK_APPS := $(_known_apps))\
+   ,\
+    $(call __ndk_info,\
+        The APP variable contains unknown app names: $(_unknown_apps))\
+    $(call __ndk_info,\
+        Please use one of: $(NDK_ALL_APPS))\
+    $(call __ndk_error, Aborting)\
+  )\
+)
+
+$(call __ndk_info,Building for application '$(NDK_APPS)')
+
+# Where all app-specific generated files will be stored
+NDK_APP_OUT := $(NDK_ROOT)/out/apps
+
+include $(BUILD_SYSTEM)/setup-imports.mk
+include $(BUILD_SYSTEM)/build-all.mk
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/setup-abi.mk b/build/core/setup-abi.mk
new file mode 100644
index 0000000..782f6d5
--- /dev/null
+++ b/build/core/setup-abi.mk
@@ -0,0 +1,81 @@
+# 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)
+ifneq ($(filter %x86 %mips,$(TARGET_ARCH_ABI)),)
+$(foreach _plat,3 4 5 8,\
+    $(eval TARGET_PLATFORM := $$(subst android-$(_plat),android-9,$$(TARGET_PLATFORM)))\
+)
+endif
+
+# 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
+
+# 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),mips)
+  RS_TRIPLE := mipsel-unknown-linux
+endif
+ifeq ($(TARGET_ARCH_ABI),x86)
+  RS_TRIPLE := i686-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.mk b/build/core/setup-app.mk
new file mode 100644
index 0000000..28f199a
--- /dev/null
+++ b/build/core/setup-app.mk
@@ -0,0 +1,149 @@
+# 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)
+ifeq ($(TARGET_PLATFORM),android-L)
+$(call __ndk_warning,WARNING: android-L is renamed as android-21)
+TARGET_PLATFORM := android-21
+endif
+
+# 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)
+    _abis_without_toolchain := $(filter-out $(NDK_ALL_ABIS),$(NDK_APP_ABI))
+    ifneq (,$(_abis_without_toolchain))
+        $(call ndk_log,Remove the following abis expanded from 'all' due to no toolchain: $(_abis_without_toolchain))
+        NDK_APP_ABI := $(filter-out $(_abis_without_toolchain),$(NDK_APP_ABI))
+    endif
+else
+ifeq ($(NDK_APP_ABI),all32)
+    NDK_APP_ABI := $(NDK_APP_ABI_ALL32_EXPANDED)
+    _abis_without_toolchain := $(filter-out $(NDK_ALL_ABIS),$(NDK_APP_ABI))
+    ifneq (,$(_abis_without_toolchain))
+        $(call ndk_log,Remove the following abis expanded from 'all32' due to no toolchain: $(_abis_without_toolchain))
+        NDK_APP_ABI := $(filter-out $(_abis_without_toolchain),$(NDK_APP_ABI))
+    endif
+else
+ifeq ($(NDK_APP_ABI),all64)
+    NDK_APP_ABI := $(NDK_APP_ABI_ALL64_EXPANDED)
+    _abis_without_toolchain := $(filter-out $(NDK_ALL_ABIS),$(NDK_APP_ABI))
+    ifneq (,$(_abis_without_toolchain))
+        $(call ndk_log,Remove the following abis expanded from 'all64' due to no toolchain: $(_abis_without_toolchain))
+        NDK_APP_ABI := $(filter-out $(_abis_without_toolchain),$(NDK_APP_ABI))
+    endif
+else
+    # Plug in the unknown
+    _unknown_abis := $(strip $(filter-out $(NDK_ALL_ABIS),$(NDK_APP_ABI)))
+    ifneq ($(_unknown_abis),)
+        ifeq (1,$(words $(filter-out $(NDK_KNOWN_ARCHS),$(NDK_FOUND_ARCHS))))
+            ifneq ($(filter %bcall,$(_unknown_abis)),)
+                 _unknown_abis_prefix := $(_unknown_abis:%bcall=%)
+                 NDK_APP_ABI := $(NDK_KNOWN_ABI32S:%=$(_unknown_abis_prefix)bc%)
+            else
+                ifneq ($(filter %all,$(_unknown_abis)),)
+                    _unknown_abis_prefix := $(_unknown_abis:%all=%)
+                    NDK_APP_ABI := $(NDK_KNOWN_ABIS:%=$(_unknown_abis_prefix)%)
+                else
+                    $(foreach _abi,$(NDK_KNOWN_ABIS),\
+                        $(eval _unknown_abis := $(subst $(_abi),,$(subst bc$(_abi),,$(_unknown_abis)))) \
+                    )
+                    _unknown_abis_prefix := $(sort $(_unknown_abis))
+                endif
+            endif
+            ifeq (1,$(words $(_unknown_abis_prefix)))
+                NDK_APP_ABI := $(subst $(_unknown_abis_prefix),$(filter-out $(NDK_KNOWN_ARCHS),$(NDK_FOUND_ARCHS)),$(NDK_APP_ABI))
+            endif
+        endif
+	TARGET_PLATFORM := android-21
+    endif
+    # 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)
+        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
+endif
+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)/lib/clang/3.5/include
+
+# 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..658ac68
--- /dev/null
+++ b/build/core/setup-toolchain.mk
@@ -0,0 +1,209 @@
+# 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)))
+
+    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 GCC, which is the first item in the list.
+    TARGET_TOOLCHAIN := $(firstword $(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))
+    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)
+
+# setup sysroot variable.
+# SYSROOT_INC points to a directory that contains all public header
+# files for a given platform, and
+# SYSROOT_LIB points to libraries and object files used for linking
+# the generated target files properly.
+#
+SYSROOT_INC := $(NDK_PLATFORMS_ROOT)/$(TARGET_PLATFORM)/arch-$(TARGET_ARCH)
+SYSROOT_LINK := $(SYSROOT_INC)
+
+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)
+
+clean-installed-binaries::
+
+# 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)/usr/include
+
+$(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
+
+# 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)
+
+$(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..2fcb007
--- /dev/null
+++ b/build/core/toolchains/aarch64-linux-android-clang/setup.mk
@@ -0,0 +1,78 @@
+# 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
+#
+
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,llvm)
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+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)-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+LLVM_TRIPLE := aarch64-none-linux-android
+
+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..e9b547d
--- /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 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..668b148
--- /dev/null
+++ b/build/core/toolchains/arm-linux-androideabi-4.9/setup.mk
@@ -0,0 +1,104 @@
+# 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
+
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+    TARGET_CFLAGS += \
+        -march=armv7-a \
+        -mfpu=vfpv3-d16 \
+        -mfloat-abi=softfp \
+
+    TARGET_LDFLAGS += \
+        -march=armv7-a \
+        -Wl,--fix-cortex-a8 \
+
+else ifeq ($(TARGET_ARCH_ABI),armeabi)
+    TARGET_CFLAGS += \
+        -march=armv5te \
+        -mtune=xscale \
+        -msoft-float \
+
+else
+    $(call __ndk_error,Unsupported ABI: $(TARGET_ARCH_ABI))
+endif
+
+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..0e748a0
--- /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 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..94bae34
--- /dev/null
+++ b/build/core/toolchains/arm-linux-androideabi-clang/setup.mk
@@ -0,0 +1,142 @@
+# 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
+#
+
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,llvm)
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+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)-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+#
+# CFLAGS and LDFLAGS
+#
+
+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
+
+# Disable integrated-as for better compatibility
+TARGET_CFLAGS += -fno-integrated-as
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS += \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -no-canonical-prefixes
+
+ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
+    LLVM_TRIPLE := armv7-none-linux-androideabi
+
+    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
+else ifeq ($(TARGET_ARCH_ABI),armeabi)
+    LLVM_TRIPLE := armv5te-none-linux-androideabi
+
+    TARGET_CFLAGS += -target $(LLVM_TRIPLE) \
+                     -march=armv5te \
+                     -mtune=xscale \
+                     -msoft-float
+
+    TARGET_LDFLAGS += -target $(LLVM_TRIPLE)
+
+    GCCLIB_SUBDIR :=
+else
+    $(call __ndk_error,Unsupported ABI: $(TARGET_ARCH_ABI))
+endif
+
+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/mips64el-linux-android-4.9/config.mk b/build/core/toolchains/mips64el-linux-android-4.9/config.mk
new file mode 100644
index 0000000..91fe648
--- /dev/null
+++ b/build/core/toolchains/mips64el-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 mips64el gcc-4.9 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := mips64
+TOOLCHAIN_ABIS := mips64
diff --git a/build/core/toolchains/mips64el-linux-android-4.9/setup.mk b/build/core/toolchains/mips64el-linux-android-4.9/setup.mk
new file mode 100644
index 0000000..3867173
--- /dev/null
+++ b/build/core/toolchains/mips64el-linux-android-4.9/setup.mk
@@ -0,0 +1,57 @@
+# 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 mips64el 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 \
+    -fmessage-length=0 \
+    -no-canonical-prefixes \
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS := -no-canonical-prefixes
+
+TARGET_mips64_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_mips64_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_mips64_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(__release_sources),\
+    $(TARGET_mips64_release_CFLAGS)) \
diff --git a/build/core/toolchains/mips64el-linux-android-clang/config.mk b/build/core/toolchains/mips64el-linux-android-clang/config.mk
new file mode 100644
index 0000000..ea570a1
--- /dev/null
+++ b/build/core/toolchains/mips64el-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 mips64el llvm toolchain for the Android NDK the real meat
+# is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := mips64
+TOOLCHAIN_ABIS := mips64
diff --git a/build/core/toolchains/mips64el-linux-android-clang/setup.mk b/build/core/toolchains/mips64el-linux-android-clang/setup.mk
new file mode 100644
index 0000000..c92ce90
--- /dev/null
+++ b/build/core/toolchains/mips64el-linux-android-clang/setup.mk
@@ -0,0 +1,86 @@
+# 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 mips64el 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
+#
+
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,llvm)
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+TOOLCHAIN_NAME := mips64el-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)-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+#
+# CFLAGS, C_INCLUDES, and LDFLAGS
+#
+
+LLVM_TRIPLE := mips64el-none-linux-android
+
+TARGET_CFLAGS := \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -target $(LLVM_TRIPLE) \
+    -fpic \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -fmessage-length=0 \
+    -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_mips64_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_mips64_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_mips64_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(__release_sources),\
+    $(TARGET_mips64_release_CFLAGS)) \
diff --git a/build/core/toolchains/mipsel-linux-android-4.9/config.mk b/build/core/toolchains/mipsel-linux-android-4.9/config.mk
new file mode 100644
index 0000000..7902cc7
--- /dev/null
+++ b/build/core/toolchains/mipsel-linux-android-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 mipsel gcc-4.9 toolchain for the Android NDK
+# the real meat is in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := mips
+TOOLCHAIN_ABIS := mips
diff --git a/build/core/toolchains/mipsel-linux-android-4.9/setup.mk b/build/core/toolchains/mipsel-linux-android-4.9/setup.mk
new file mode 100644
index 0000000..1970a2e
--- /dev/null
+++ b/build/core/toolchains/mipsel-linux-android-4.9/setup.mk
@@ -0,0 +1,57 @@
+# 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 mipsel 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 \
+    -fmessage-length=0 \
+    -no-canonical-prefixes \
+
+# Always enable debug info. We strip binaries when needed.
+TARGET_CFLAGS += -g
+
+TARGET_LDFLAGS := -no-canonical-prefixes
+
+TARGET_mips_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_mips_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_mips_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(__release_sources),\
+    $(TARGET_mips_release_CFLAGS)) \
diff --git a/build/core/toolchains/mipsel-linux-android-clang/config.mk b/build/core/toolchains/mipsel-linux-android-clang/config.mk
new file mode 100644
index 0000000..4357e2c
--- /dev/null
+++ b/build/core/toolchains/mipsel-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 mipsel llvm toolchain for the Android NDK the real meat is
+# in the setup.mk file adjacent to this one
+#
+TOOLCHAIN_ARCH := mips
+TOOLCHAIN_ABIS := mips
diff --git a/build/core/toolchains/mipsel-linux-android-clang/setup.mk b/build/core/toolchains/mipsel-linux-android-clang/setup.mk
new file mode 100644
index 0000000..53322b1
--- /dev/null
+++ b/build/core/toolchains/mipsel-linux-android-clang/setup.mk
@@ -0,0 +1,93 @@
+# 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 mipsel 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
+#
+
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,llvm)
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+TOOLCHAIN_NAME := mipsel-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)-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+#
+# CFLAGS, C_INCLUDES, and LDFLAGS
+#
+
+LLVM_TRIPLE := mipsel-none-linux-android
+
+TARGET_CFLAGS := \
+    -gcc-toolchain $(call host-path,$(TOOLCHAIN_ROOT)) \
+    -target $(LLVM_TRIPLE) \
+    -fpic \
+    -ffunction-sections \
+    -funwind-tables \
+    -fstack-protector-strong \
+    -fmessage-length=0 \
+    -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 \
+
+# Clang outputs mips32r2 by default, switch to mips32r1
+# TODO: Remove this once mipsel-linux-android target is changed in clang
+ifeq ($(TARGET_ARCH_ABI),mips)
+    TARGET_CFLAGS += -mips32
+    TARGET_LDFLAGS += -mips32
+endif
+
+TARGET_mips_release_CFLAGS := \
+    -O2 \
+    -DNDEBUG \
+
+TARGET_mips_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_mips_debug_CFLAGS)) \
+$(call set-src-files-target-cflags,\
+    $(__release_sources),\
+    $(TARGET_mips_release_CFLAGS)) \
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..238cd9f
--- /dev/null
+++ b/build/core/toolchains/x86-clang/setup.mk
@@ -0,0 +1,84 @@
+# 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
+#
+
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,llvm)
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+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)-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+LLVM_TRIPLE := i686-none-linux-android
+
+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..c3f7bae
--- /dev/null
+++ b/build/core/toolchains/x86_64-clang/setup.mk
@@ -0,0 +1,82 @@
+# 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
+#
+
+LLVM_TOOLCHAIN_PREBUILT_ROOT := $(call get-toolchain-root,llvm)
+LLVM_TOOLCHAIN_PREFIX := $(LLVM_TOOLCHAIN_PREBUILT_ROOT)/bin/
+
+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)-
+
+TARGET_CC := $(LLVM_TOOLCHAIN_PREFIX)clang$(HOST_EXEEXT)
+TARGET_CXX := $(LLVM_TOOLCHAIN_PREFIX)clang++$(HOST_EXEEXT)
+
+LLVM_TRIPLE := x86_64-none-linux-android
+
+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/gmsl/README b/build/gmsl/README
new file mode 100644
index 0000000..152ada6
--- /dev/null
+++ b/build/gmsl/README
@@ -0,0 +1,27 @@
+GNU Make Standard Library
+-------------------------
+
+1. Visit http://gmsl.sf.net for more details
+
+2. To use the GMSL in your Makefile make sure that you have the files
+
+   gmsl
+   __gmsl
+
+   Add 
+
+   include gmsl
+
+   to your Makefile(s).
+
+3. To run the GMSL test suite have 
+
+   gmsl
+   __gmsl
+   gmsl-tests
+
+   And then run
+
+   make -f gmsl-tests
+
+ 
\ No newline at end of file
diff --git a/build/gmsl/__gmsl b/build/gmsl/__gmsl
new file mode 100644
index 0000000..596ff19
--- /dev/null
+++ b/build/gmsl/__gmsl
@@ -0,0 +1,854 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL)
+#
+# A library of functions to be used with GNU Make's $(call) that
+# provides functionality not available in standard GNU Make.
+#
+# Copyright (c) 2005-2007 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 
+# Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# Neither the name of the John Graham-Cumming nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# ----------------------------------------------------------------------------
+
+# This is the GNU Make Standard Library version number as a list with
+# three items: major, minor, revision
+
+gmsl_version := 1 0 11
+
+# Used to output warnings and error from the library, it's possible to
+# disable any warnings or errors by overriding these definitions
+# manually or by setting GMSL_NO_WARNINGS or GMSL_NO_ERRORS
+
+__gmsl_name := GNU Make Standard Library
+__gmsl_warning = $(warning $(__gmsl_name): $1)
+__gmsl_error = $(error $(__gmsl_name): $1)
+
+ifdef GMSL_NO_WARNINGS
+__gmsl_warning :=
+endif
+ifdef GMSL_NO_ERRORS
+__gmsl_error :=
+endif
+
+# If GMSL_TRACE is enabled then calls to the library functions are
+# traced to stdout using warning messages with their arguments
+
+ifdef GMSL_TRACE
+__gmsl_tr1 = $(warning $0('$1'))
+__gmsl_tr2 = $(warning $0('$1','$2'))
+__gmsl_tr3 = $(warning $0('$1','$2','$3'))
+else
+__gmsl_tr1 :=
+__gmsl_tr2 :=
+__gmsl_tr3 :=
+endif
+
+# Figure out whether we have $(eval) or not (GNU Make 3.80 and above)
+# if we do not then output a warning message, if we do then some
+# functions will be enabled.
+
+__gmsl_have_eval := $(false)
+__gmsl_ignore := $(eval __gmsl_have_eval := $(true))
+
+# If this is being run with Electric Cloud's emake then warn that
+# their $(eval) support is incomplete.
+
+ifdef ECLOUD_BUILD_ID
+$(warning You are using Electric Cloud's emake which has incomplete $$(eval) support)
+__gmsl_have_eval := $(false)
+endif
+
+# See if we have $(lastword) (GNU Make 3.81 and above)
+
+__gmsl_have_lastword := $(lastword $(false) $(true))
+
+# See if we have native or and and (GNU Make 3.81 and above)
+
+__gmsl_have_or := $(if $(filter-out undefined,  \
+    $(origin or)),$(call or,$(true),$(false)))
+__gmsl_have_and := $(if $(filter-out undefined, \
+    $(origin and)),$(call and,$(true),$(true)))
+
+ifneq ($(__gmsl_have_eval),$(true))
+$(call __gmsl_warning,GNU Make $(MAKE_VERSION) does not support $$$$(eval): some functions disabled)
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  gmsl_compatible
+# Arguments: List containing the desired library version number (maj min rev)
+# Returns:   $(true) if this version of the library is compatible
+#            with the requested version number, otherwise $(false)
+# ----------------------------------------------------------------------------
+gmsl_compatible = $(strip                                                 \
+    $(if $(call gt,$(word 1,$1),$(word 1,$(gmsl_version))),               \
+        $(false),                                                         \
+        $(if $(call lt,$(word 1,$1),$(word 1,$(gmsl_version))),           \
+            $(true),                                                      \
+            $(if $(call gt,$(word 2,$1),$(word 2,$(gmsl_version))),       \
+                $(false),                                                 \
+                $(if $(call lt,$(word 2,$1),$(word 2,$(gmsl_version))),   \
+                    $(true),                                              \
+                    $(call lte,$(word 3,$1),$(word 3,$(gmsl_version))))))))
+
+# ###########################################################################
+# LOGICAL OPERATORS
+# ###########################################################################
+
+# not is defined in gmsl
+
+# ----------------------------------------------------------------------------
+# Function:  and
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if both of the booleans are true
+# ----------------------------------------------------------------------------
+ifneq ($(__gmsl_have_and),$(true))
+and = $(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(false))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  or
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if either of the booleans is true
+# ----------------------------------------------------------------------------
+ifneq ($(__gmsl_have_or),$(true))
+or = $(__gmsl_tr2)$(if $1$2,$(true),$(false))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  xor
+# Arguments: Two boolean values
+# Returns:   Returns $(true) if exactly one of the booleans is true
+# ----------------------------------------------------------------------------
+xor = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(if $2,$(true),$(false)))
+
+# ----------------------------------------------------------------------------
+# Function:  nand
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not and'
+# ----------------------------------------------------------------------------
+nand = $(__gmsl_tr2)$(if $1,$(if $2,$(false),$(true)),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  nor
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not or'
+# ----------------------------------------------------------------------------
+nor = $(__gmsl_tr2)$(if $1$2,$(false),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  xnor
+# Arguments: Two boolean values
+# Returns:   Returns value of 'not xor'
+# ----------------------------------------------------------------------------
+xnor =$(__gmsl_tr2)$(if $1,$(if $2,$(true),$(false)),$(if $2,$(false),$(true)))
+
+# ###########################################################################
+# LIST MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  first (same as LISP's car, or head)
+# Arguments: 1: A list
+# Returns:   Returns the first element of a list
+# ----------------------------------------------------------------------------
+first = $(__gmsl_tr1)$(firstword $1)
+
+# ----------------------------------------------------------------------------
+# Function:  last
+# Arguments: 1: A list
+# Returns:   Returns the last element of a list
+# ----------------------------------------------------------------------------
+ifeq ($(__gmsl_have_lastword),$(true))
+last = $(__gmsl_tr1)$(lastword $1)
+else
+last = $(__gmsl_tr1)$(if $1,$(word $(words $1),$1))
+endif
+
+# ----------------------------------------------------------------------------
+# Function:  rest (same as LISP's cdr, or tail)
+# Arguments: 1: A list
+# Returns:   Returns the list with the first element removed
+# ----------------------------------------------------------------------------
+rest = $(__gmsl_tr1)$(wordlist 2,$(words $1),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  chop
+# Arguments: 1: A list
+# Returns:   Returns the list with the last element removed
+# ----------------------------------------------------------------------------
+chop = $(__gmsl_tr1)$(wordlist 2,$(words $1),x $1)
+
+# ----------------------------------------------------------------------------
+# Function:  map
+# Arguments: 1: Name of function to $(call) for each element of list
+#            2: List to iterate over calling the function in 1
+# Returns:   The list after calling the function on each element
+# ----------------------------------------------------------------------------
+map = $(__gmsl_tr2)$(strip $(foreach a,$2,$(call $1,$a)))
+
+# ----------------------------------------------------------------------------
+# Function:  pairmap
+# Arguments: 1: Name of function to $(call) for each pair of elements
+#            2: List to iterate over calling the function in 1
+#            3: Second list to iterate over calling the function in 1
+# Returns:   The list after calling the function on each pair of elements
+# ----------------------------------------------------------------------------
+pairmap = $(strip $(__gmsl_tr3)\
+          $(if $2$3,$(call $1,$(call first,$2),$(call first,$3))     \
+                        $(call pairmap,$1,$(call rest,$2),$(call rest,$3))))
+
+# ----------------------------------------------------------------------------
+# Function:  leq
+# Arguments: 1: A list to compare against...
+#            2: ...this list
+# Returns:   Returns $(true) if the two lists are identical
+# ----------------------------------------------------------------------------
+leq = $(__gmsl_tr2)$(strip $(if $(call seq,$(words $1),$(words $2)),     \
+          $(call __gmsl_list_equal,$1,$2),$(false)))
+
+__gmsl_list_equal = $(if $(strip $1),                                       \
+                        $(if $(call seq,$(call first,$1),$(call first,$2)), \
+                            $(call __gmsl_list_equal,                       \
+                                $(call rest,$1),                            \
+                                $(call rest,$2)),                           \
+                            $(false)),                                      \
+                     $(true))
+
+# ----------------------------------------------------------------------------
+# Function:  lne
+# Arguments: 1: A list to compare against...
+#            2: ...this list
+# Returns:   Returns $(true) if the two lists are different
+# ----------------------------------------------------------------------------
+lne = $(__gmsl_tr2)$(call not,$(call leq,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  reverse
+# Arguments: 1: A list to reverse
+# Returns:   The list with its elements in reverse order
+# ----------------------------------------------------------------------------
+reverse =$(__gmsl_tr1)$(strip $(if $1,$(call reverse,$(call rest,$1)) \
+                        $(call first,$1)))
+
+# ----------------------------------------------------------------------------
+# Function:  uniq
+# Arguments: 1: A list from which to remove repeated elements
+# Returns:   The list with duplicate elements removed without reordering
+# ----------------------------------------------------------------------------
+uniq = $(strip $(__gmsl_tr1)$(if $1,$(call uniq,$(call chop,$1)) \
+            $(if $(filter $(call last,$1),$(call chop,$1)),,$(call last,$1))))
+
+# ----------------------------------------------------------------------------
+# Function:  length
+# Arguments: 1: A list
+# Returns:   The number of elements in the list
+# ----------------------------------------------------------------------------
+length = $(__gmsl_tr1)$(words $1)
+
+# ###########################################################################
+# STRING MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# Helper function that translates any GNU Make 'true' value (i.e. a
+# non-empty string) to our $(true)
+
+__gmsl_make_bool = $(if $(strip $1),$(true),$(false))
+
+# ----------------------------------------------------------------------------
+# Function:  seq
+# Arguments: 1: A string to compare against...
+#            2: ...this string
+# Returns:   Returns $(true) if the two strings are identical
+# ----------------------------------------------------------------------------
+seq = $(__gmsl_tr2)$(if $(filter-out xx,x$(subst $1,,$2)$(subst $2,,$1)x),$(false),$(true))
+
+# ----------------------------------------------------------------------------
+# Function:  sne
+# Arguments: 1: A string to compare against...
+#            2: ...this string
+# Returns:   Returns $(true) if the two strings are not the same
+# ----------------------------------------------------------------------------
+sne = $(__gmsl_tr2)$(call not,$(call seq,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  split
+# Arguments: 1: The character to split on
+#            2: A string to split
+# Returns:   Splits a string into a list separated by spaces at the split
+#            character in the first argument
+# ----------------------------------------------------------------------------
+split = $(__gmsl_tr2)$(strip $(subst $1, ,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  merge
+# Arguments: 1: The character to put between fields
+#            2: A list to merge into a string
+# Returns:   Merges a list into a single string, list elements are separated
+#            by the character in the first argument
+# ----------------------------------------------------------------------------
+merge = $(__gmsl_tr2)$(strip $(if $2,                                     \
+            $(if $(call seq,1,$(words $2)),                               \
+                $2,$(call first,$2)$1$(call merge,$1,$(call rest,$2)))))
+
+ifdef __gmsl_have_eval
+# ----------------------------------------------------------------------------
+# Function:  tr
+# Arguments: 1: The list of characters to translate from 
+#            2: The list of characters to translate to
+#            3: The text to translate
+# Returns:   Returns the text after translating characters
+# ----------------------------------------------------------------------------
+tr = $(strip $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)              \
+     $(eval __gmsl_t := $3)                                               \
+     $(foreach c,                                                         \
+         $(join $(addsuffix :,$1),$2),                                    \
+         $(eval __gmsl_t :=                                               \
+             $(subst $(word 1,$(subst :, ,$c)),$(word 2,$(subst :, ,$c)), \
+                 $(__gmsl_t))))$(__gmsl_t))
+
+# Common character classes for use with the tr function.  Each of
+# these is actually a variable declaration and must be wrapped with
+# $() or ${} to be used.
+
+[A-Z] := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z #
+[a-z] := a b c d e f g h i j k l m n o p q r s t u v w x y z #
+[0-9] := 0 1 2 3 4 5 6 7 8 9 #
+[A-F] := A B C D E F #
+
+# ----------------------------------------------------------------------------
+# Function:  uc
+# Arguments: 1: Text to upper case
+# Returns:   Returns the text in upper case
+# ----------------------------------------------------------------------------
+uc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([a-z]),$([A-Z]),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  lc
+# Arguments: 1: Text to lower case
+# Returns:   Returns the text in lower case
+# ----------------------------------------------------------------------------
+lc = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call tr,$([A-Z]),$([a-z]),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  strlen
+# Arguments: 1: A string
+# Returns:   Returns the length of the string
+# ----------------------------------------------------------------------------
+__gmsl_characters := A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
+__gmsl_characters += a b c d e f g h i j k l m n o p q r s t u v w x y z
+__gmsl_characters += 0 1 2 3 4 5 6 7 8 9
+__gmsl_characters += ` ~ ! @ \# $$ % ^ & * ( ) - _ = +
+__gmsl_characters += { } [ ] \ : ; ' " < > , . / ? |
+
+# Aside: if you read the above you might think that the lower-case
+# letter x is missing, and that that's an error.  It is missing, but
+# it's not an error.  __gmsl_characters is used by the strlen
+# function.  strlen works by transforming every character and space
+# into the letter x and then counting the x's.  Since there's no need
+# to transform x into x I omitted it.
+
+# This results in __gmsl_space containing just a space
+
+__gmsl_space := 
+__gmsl_space +=
+
+strlen = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(eval __temp := $(subst $(__gmsl_space),x,$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,x,$(__temp))))$(eval __temp := $(subst x,x ,$(__temp)))$(words $(__temp)))
+
+# This results in __gmsl_newline containing just a newline
+
+define __gmsl_newline
+
+
+endef
+
+# This results in __gmsl_tab containing a tab
+
+__gmsl_tab :=	#
+
+# ----------------------------------------------------------------------------
+# Function:  substr
+# Arguments: 1: A string
+# 	     2: Start position (first character is 1)
+#	     3: End position (inclusive)
+# Returns:   A substring.  
+# Note:      The string in $1 must not contain a §
+# ----------------------------------------------------------------------------
+
+substr = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(strip $(eval __temp := $$(subst $$(__gmsl_space),§ ,$$1))$(foreach a,$(__gmsl_characters),$(eval __temp := $$(subst $$a,$$a$$(__gmsl_space),$(__temp))))$(eval __temp := $(wordlist $2,$3,$(__temp))))$(subst §,$(__gmsl_space),$(subst $(__gmsl_space),,$(__temp)))
+
+endif # __gmsl_have_eval
+
+# ###########################################################################
+# SET MANIPULATION FUNCTIONS
+# ###########################################################################
+
+# Sets are represented by sorted, deduplicated lists.  To create a set
+# from a list use set_create, or start with the empty_set and
+# set_insert individual elements
+
+# This is the empty set
+empty_set := 
+
+# ----------------------------------------------------------------------------
+# Function:  set_create
+# Arguments: 1: A list of set elements
+# Returns:   Returns the newly created set
+# ----------------------------------------------------------------------------
+set_create = $(__gmsl_tr1)$(sort $1)
+
+# ----------------------------------------------------------------------------
+# Function:  set_insert
+# Arguments: 1: A single element to add to a set
+#            2: A set
+# Returns:   Returns the set with the element added
+# ----------------------------------------------------------------------------
+set_insert = $(__gmsl_tr2)$(sort $1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_remove
+# Arguments: 1: A single element to remove from a set
+#            2: A set
+# Returns:   Returns the set with the element removed
+# ----------------------------------------------------------------------------
+set_remove = $(__gmsl_tr2)$(filter-out $1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_is_member
+# Arguments: 1: A single element 
+#            2: A set
+# Returns:   Returns $(true) if the element is in the set
+# ----------------------------------------------------------------------------
+set_is_member = $(__gmsl_tr2)$(if $(filter $1,$2),$(true),$(false))
+
+# ----------------------------------------------------------------------------
+# Function:  set_union
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns the union of the two sets
+# ----------------------------------------------------------------------------
+set_union = $(__gmsl_tr2)$(sort $1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_intersection
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns the intersection of the two sets
+# ----------------------------------------------------------------------------
+set_intersection = $(__gmsl_tr2)$(filter $1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  set_is_subset
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns $(true) if the first set is a subset of the second
+# ----------------------------------------------------------------------------
+set_is_subset = $(__gmsl_tr2)$(call set_equal,$(call set_intersection,$1,$2),$1)
+
+# ----------------------------------------------------------------------------
+# Function:  set_equal
+# Arguments: 1: A set
+#            2: Another set
+# Returns:   Returns $(true) if the two sets are identical
+# ----------------------------------------------------------------------------
+set_equal = $(__gmsl_tr2)$(call seq,$1,$2)
+
+# ###########################################################################
+# ARITHMETIC LIBRARY
+# ###########################################################################
+
+# Integers a represented by lists with the equivalent number of x's.
+# For example the number 4 is x x x x.  The maximum integer that the
+# library can handle as _input_ is __gmsl_input_int which is defined
+# here as 65536
+
+__gmsl_sixteen := x x x x x x x x x x x x x x x x
+__gmsl_input_int := $(foreach a,$(__gmsl_sixteen),         \
+                        $(foreach b,$(__gmsl_sixteen),     \
+                            $(foreach c,$(__gmsl_sixteen), \
+                                $(__gmsl_sixteen)))))
+
+# ----------------------------------------------------------------------------
+# Function:  int_decode
+# Arguments: 1: A number of x's representation
+# Returns:   Returns the integer for human consumption that is represented
+#            by the string of x's
+# ----------------------------------------------------------------------------
+int_decode = $(__gmsl_tr1)$(words $1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_encode
+# Arguments: 1: A number in human-readable integer form
+# Returns:   Returns the integer encoded as a string of x's
+# ----------------------------------------------------------------------------
+int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int))
+
+# The arithmetic library functions come in two forms: one form of each
+# function takes integers as arguments and the other form takes the
+# encoded form (x's created by a call to int_encode).  For example,
+# there are two plus functions:
+#
+# plus        Called with integer arguments and returns an integer
+# int_plus    Called with encoded arguments and returns an encoded result
+#
+# plus will be slower than int_plus because its arguments and result
+# have to be translated between the x's format and integers.  If doing
+# a complex calculation use the int_* forms with a single encoding of
+# inputs and single decoding of the output.  For simple calculations
+# the direct forms can be used.
+
+# Helper function used to wrap an int_* function into a function that
+# takes a pair of integers, perhaps a function and returns an integer
+# result
+__gmsl_int_wrap = $(call int_decode,$(call $1,$(call int_encode,$2),$(call int_encode,$3)))
+__gmsl_int_wrap1 = $(call int_decode,$(call $1,$(call int_encode,$2)))
+__gmsl_int_wrap2 = $(call $1,$(call int_encode,$2),$(call int_encode,$3))
+
+# ----------------------------------------------------------------------------
+# Function:  int_plus
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the sum of the two numbers in x's representation
+# ----------------------------------------------------------------------------
+int_plus = $(strip $(__gmsl_tr2)$1 $2)
+
+# ----------------------------------------------------------------------------
+# Function:  plus (wrapped version of int_plus)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the sum of the two integers
+# ----------------------------------------------------------------------------
+plus = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_plus,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_subtract
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the difference of the two numbers in x's representation,
+#            or outputs an error on a numeric underflow
+# ----------------------------------------------------------------------------
+int_subtract = $(strip $(__gmsl_tr2)$(if $(call int_gte,$1,$2), \
+                $(filter-out xx,$(join $1,$2)),                 \
+                $(call __gmsl_warning,Subtraction underflow)))
+
+# ----------------------------------------------------------------------------
+# Function:  subtract (wrapped version of int_subtract)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the difference of the two integers,
+#            or outputs an error on a numeric underflow
+# ----------------------------------------------------------------------------
+subtract = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_subtract,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_multiply
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the product of the two numbers in x's representation
+# ----------------------------------------------------------------------------
+int_multiply = $(strip $(__gmsl_tr2)$(foreach a,$1,$2))
+
+# ----------------------------------------------------------------------------
+# Function:  multiply (wrapped version of int_multiply)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the product of the two integers
+# ----------------------------------------------------------------------------
+multiply = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_multiply,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_divide
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the result of integer division of argument 1 divided
+#            by argument 2 in x's representation
+# ----------------------------------------------------------------------------
+int_divide = $(__gmsl_tr2)$(strip $(if $2,                                 \
+                 $(if $(call int_gte,$1,$2),                               \
+                     x $(call int_divide,$(call int_subtract,$1,$2),$2),), \
+                 $(call __gmsl_error,Division by zero)))
+
+# ----------------------------------------------------------------------------
+# Function:  divide (wrapped version of int_divide)
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the integer division of the first argument by the second
+# ----------------------------------------------------------------------------
+divide = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_divide,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function:  int_max, int_min
+# Arguments: 1: A number in x's representation
+#            2: Another number in x's represntation
+# Returns:   Returns the maximum or minimum of its arguments in x's
+#            representation
+# ----------------------------------------------------------------------------
+int_max = $(__gmsl_tr2)$(subst xx,x,$(join $1,$2))
+int_min = $(__gmsl_tr2)$(subst xx,x,$(filter xx,$(join $1,$2)))
+
+# ----------------------------------------------------------------------------
+# Function:  max, min
+# Arguments: 1: An integer
+#            2: Another integer
+# Returns:   Returns the maximum or minimum of its integer arguments
+# ----------------------------------------------------------------------------
+max = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_max,$1,$2)
+min = $(__gmsl_tr2)$(call __gmsl_int_wrap,int_min,$1,$2)
+
+# ----------------------------------------------------------------------------
+# Function: int_gt, int_gte, int_lt, int_lte, int_eq, int_ne
+# Arguments: Two x's representation numbers to be compared
+# Returns:   $(true) or $(false)
+#
+# int_gt    First argument greater than second argument
+# int_gte   First argument greater than or equal to second argument
+# int_lt    First argument less than second argument 
+# int_lte   First argument less than or equal to second argument
+# int_eq    First argument is numerically equal to the second argument
+# int_ne    First argument is not numerically equal to the second argument
+# ----------------------------------------------------------------------------
+int_gt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $2), \
+                              $(words $(call int_max,$1,$2))))
+int_gte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
+                           $(call int_gt,$1,$2)$(call int_eq,$1,$2))
+int_lt = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $1), \
+                              $(words $(call int_max,$1,$2))))
+int_lte = $(__gmsl_tr2)$(call __gmsl_make_bool,     \
+                           $(call int_lt,$1,$2)$(call int_eq,$1,$2))
+int_eq = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter $(words $1),$(words $2)))
+int_ne = $(__gmsl_tr2)$(call __gmsl_make_bool,      \
+                          $(filter-out $(words $1),$(words $2)))
+
+# ----------------------------------------------------------------------------
+# Function: gt, gte, lt, lte, eq, ne
+# Arguments: Two integers to be compared
+# Returns:   $(true) or $(false)
+#
+# gt    First argument greater than second argument
+# gte   First argument greater than or equal to second argument
+# lt    First argument less than second argument 
+# lte   First argument less than or equal to second argument
+# eq    First argument is numerically equal to the second argument
+# ne    First argument is not numerically equal to the second argument
+# ----------------------------------------------------------------------------
+gt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gt,$1,$2)
+gte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_gte,$1,$2)
+lt = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lt,$1,$2)
+lte = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_lte,$1,$2)
+eq = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_eq,$1,$2)
+ne = $(__gmsl_tr2)$(call __gmsl_int_wrap2,int_ne,$1,$2)
+
+# increment adds 1 to its argument, decrement subtracts 1.  Note that
+# decrement does not range check and hence will not underflow, but
+# will incorrectly say that 0 - 1 = 0
+
+# ----------------------------------------------------------------------------
+# Function:  int_inc
+# Arguments: 1: A number in x's representation
+# Returns:   The number incremented by 1 in x's representation
+# ----------------------------------------------------------------------------
+int_inc = $(strip $(__gmsl_tr1)$1 x)
+
+# ----------------------------------------------------------------------------
+# Function:  inc
+# Arguments: 1: An integer
+# Returns:   The argument incremented by 1
+# ----------------------------------------------------------------------------
+inc = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_inc,$1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_dec
+# Arguments: 1: A number in x's representation
+# Returns:   The number decremented by 1 in x's representation
+# ----------------------------------------------------------------------------
+int_dec = $(__gmsl_tr1)$(strip $(if $(call sne,0,$(words $1)), \
+              $(wordlist 2,$(words $1),$1),                    \
+              $(call __gmsl_warning,Decrement underflow)))
+
+# ----------------------------------------------------------------------------
+# Function:  dec
+# Arguments: 1: An integer
+# Returns:   The argument decremented by 1
+# ----------------------------------------------------------------------------
+dec = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_dec,$1)
+
+# double doubles its argument, and halve halves it
+
+# ----------------------------------------------------------------------------
+# Function:  int_double
+# Arguments: 1: A number in x's representation
+# Returns:   The number doubled (i.e. * 2) and returned in x's representation
+# ----------------------------------------------------------------------------
+int_double = $(strip $(__gmsl_tr1)$1 $1)
+
+# ----------------------------------------------------------------------------
+# Function:  double
+# Arguments: 1: An integer
+# Returns:   The integer times 2
+# ----------------------------------------------------------------------------
+double = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_double,$1)
+
+# ----------------------------------------------------------------------------
+# Function:  int_halve
+# Arguments: 1: A number in x's representation
+# Returns:   The number halved (i.e. / 2) and returned in x's representation
+# ----------------------------------------------------------------------------
+int_halve = $(__gmsl_tr1)$(strip $(subst xx,x,$(filter-out xy x y, \
+                             $(join $1,$(foreach a,$1,y x)))))
+
+# ----------------------------------------------------------------------------
+# Function:  halve
+# Arguments: 1: An integer
+# Returns:   The integer divided by 2
+# ----------------------------------------------------------------------------
+halve = $(__gmsl_tr1)$(call __gmsl_int_wrap1,int_halve,$1)
+
+ifdef __gmsl_have_eval
+# ###########################################################################
+# ASSOCIATIVE ARRAYS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  set
+# Arguments: 1: Name of associative array
+#            2: The key value to associate
+#            3: The value associated with the key
+# Returns:   None
+# ----------------------------------------------------------------------------
+set = $(__gmsl_tr3)$(call assert_no_dollar,$0,$1$2$3)$(eval __gmsl_aa_$1_$2 = $3)
+
+# ----------------------------------------------------------------------------
+# Function:  get
+# Arguments: 1: Name of associative array
+#            2: The key to retrieve
+# Returns:   The value stored in the array for that key
+# ----------------------------------------------------------------------------
+get = $(strip $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(if $(filter-out undefined,$(origin __gmsl_aa_$1_$2)), \
+    $(__gmsl_aa_$1_$2)))
+
+# ----------------------------------------------------------------------------
+# Function:  keys
+# Arguments: 1: Name of associative array
+# Returns:   Returns a list of all defined keys in the array
+# ----------------------------------------------------------------------------
+keys = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(sort $(patsubst __gmsl_aa_$1_%,%, \
+                  $(filter __gmsl_aa_$1_%,$(.VARIABLES))))
+
+# ----------------------------------------------------------------------------
+# Function:  defined
+# Arguments: 1: Name of associative array
+#            2: The key to test
+# Returns:   Returns true if the key is defined (i.e. not empty)
+# ----------------------------------------------------------------------------
+defined = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(call sne,$(call get,$1,$2),)
+
+endif # __gmsl_have_eval
+
+ifdef __gmsl_have_eval
+# ###########################################################################
+# NAMED STACKS
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Function:  push
+# Arguments: 1: Name of stack
+#            2: Value to push onto the top of the stack (must not contain
+#               a space)
+# Returns:   None
+# ----------------------------------------------------------------------------
+push = $(__gmsl_tr2)$(call assert_no_dollar,$0,$1$2)$(eval __gmsl_stack_$1 := $2 $(if $(filter-out undefined,\
+    $(origin __gmsl_stack_$1)),$(__gmsl_stack_$1)))
+
+# ----------------------------------------------------------------------------
+# Function:  pop
+# Arguments: 1: Name of stack
+# Returns:   Top element from the stack after removing it
+# ----------------------------------------------------------------------------
+pop = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(strip $(if $(filter-out undefined,$(origin __gmsl_stack_$1)), \
+    $(call first,$(__gmsl_stack_$1))                                       \
+    $(eval __gmsl_stack_$1 := $(call rest,$(__gmsl_stack_$1)))))
+
+# ----------------------------------------------------------------------------
+# Function:  peek
+# Arguments: 1: Name of stack
+# Returns:   Top element from the stack without removing it
+# ----------------------------------------------------------------------------
+peek = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(call first,$(__gmsl_stack_$1))
+
+# ----------------------------------------------------------------------------
+# Function:  depth
+# Arguments: 1: Name of stack
+# Returns:   Number of items on the stack
+# ----------------------------------------------------------------------------
+depth = $(__gmsl_tr1)$(call assert_no_dollar,$0,$1)$(words $(__gmsl_stack_$1))
+
+endif # __gmsl_have_eval
+
+# ###########################################################################
+# DEBUGGING FACILITIES
+# ###########################################################################
+
+# ----------------------------------------------------------------------------
+# Target:    gmsl-print-%
+# Arguments: The % should be replaced by the name of a variable that you
+#            wish to print out.
+# Action:    Echos the name of the variable that matches the % and its value.
+#            For example, 'make gmsl-print-SHELL' will output the value of
+#            the SHELL variable
+# ----------------------------------------------------------------------------
+gmsl-print-%: ; @echo $* = $($*)
+
+# ----------------------------------------------------------------------------
+# Function:  assert
+# Arguments: 1: A boolean that must be true or the assertion will fail
+#            2: The message to print with the assertion
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert = $(if $1,,$(call __gmsl_error,Assertion failure: $2))
+
+# ----------------------------------------------------------------------------
+# Function:  assert_exists
+# Arguments: 1: Name of file that must exist, if it is missing an assertion
+#               will be generated
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert_exists = $(call assert,$(wildcard $1),file '$1' missing)
+
+# ----------------------------------------------------------------------------
+# Function:  assert_no_dollar
+# Arguments: 1: Name of a function being executd
+#            2: Arguments to check
+# Returns:   None
+# ----------------------------------------------------------------------------
+assert_no_dollar = $(call assert,$(call not,$(findstring $$,$2)),$1 called with a dollar sign in argument)
diff --git a/build/gmsl/gmsl b/build/gmsl/gmsl
new file mode 100644
index 0000000..2ff2897
--- /dev/null
+++ b/build/gmsl/gmsl
@@ -0,0 +1,89 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL)
+#
+# A library of functions to be used with GNU Make's $(call) that
+# provides functionality not available in standard GNU Make.
+#
+# Copyright (c) 2005-2008 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 
+# Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# Neither the name of the John Graham-Cumming nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# ----------------------------------------------------------------------------
+
+# Determine if the library has already been included and if so don't
+# bother including it again
+
+ifndef __gmsl_included
+
+# Standard definitions for true and false.  true is any non-empty
+# string, false is an empty string. These are intended for use with
+# $(if).
+
+true  := T
+false :=
+
+# ----------------------------------------------------------------------------
+# Function:  not
+# Arguments: 1: A boolean value
+# Returns:   Returns the opposite of the arg. (true -> false, false -> true)
+# ----------------------------------------------------------------------------
+not = $(if $1,$(false),$(true))
+
+# Prevent reinclusion of the library
+
+__gmsl_included := $(true)
+
+# Try to determine where this file is located.  If the caller did
+# include /foo/gmsl then extract the /foo/ so that __gmsl gets
+# included transparently
+
+ifneq ($(MAKEFILE_LIST),)
+__gmsl_root := $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST))
+
+# If there are any spaces in the path in __gmsl_root then give up
+
+ifeq (1,$(words $(__gmsl_root)))
+__gmsl_root := $(patsubst %gmsl,%,$(__gmsl_root))
+else
+__gmsl_root :=
+endif
+
+include $(__gmsl_root)__gmsl
+
+else
+
+include __gmsl
+
+endif
+
+endif # __gmsl_included
+
diff --git a/build/gmsl/gmsl-tests b/build/gmsl/gmsl-tests
new file mode 100644
index 0000000..b205be6
--- /dev/null
+++ b/build/gmsl/gmsl-tests
@@ -0,0 +1,647 @@
+# ----------------------------------------------------------------------------
+#
+# GNU Make Standard Library (GMSL) Test Suite
+#
+# Test suite for the GMSL
+#
+# Copyright (c) 2005-2007 John Graham-Cumming
+#
+# This file is part of GMSL
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 
+# Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# Neither the name of the John Graham-Cumming nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# ----------------------------------------------------------------------------
+
+.PHONY: all
+all:
+	@echo
+	@echo Test Summary
+	@echo ------------
+	@echo "$(call int_decode,$(passed)) tests passed; $(call int_decode,$(failed)) tests failed"
+
+include gmsl
+
+passed :=
+failed :=
+
+ECHO := /bin/echo
+
+start_test = $(shell $(ECHO) -n "Testing '$1': " >&2)$(eval current_test := OK)
+stop_test  = $(shell $(ECHO) " $(current_test)" >&2)
+test_pass = .$(eval passed := $(call int_inc,$(passed)))
+test_fail = X$(eval failed := $(call int_inc,$(failed)))$(eval current_test := ERROR '$1' != '$2')
+test_assert = $(if $(filter undefined,$(origin 2)),$(eval 2 :=))$(shell $(ECHO) -n $(if $(call seq,$1,$2),$(call test_pass,$1,$2),$(call test_fail,$1,$2)) >&2)
+
+$(call start_test,not)
+$(call test_assert,$(call not,$(true)),$(false))
+$(call test_assert,$(call not,$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,or)
+$(call test_assert,$(call or,$(true),$(true)),$(true))
+$(call test_assert,$(call or,$(true),$(false)),$(true))
+$(call test_assert,$(call or,$(false),$(true)),$(true))
+$(call test_assert,$(call or,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,and)
+$(call test_assert,$(call and,$(true),$(true)),$(true))
+$(call test_assert,$(call and,$(true),$(false)),$(false))
+$(call test_assert,$(call and,$(false),$(true)),$(false))
+$(call test_assert,$(call and,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,xor)
+$(call test_assert,$(call xor,$(true),$(true)),$(false))
+$(call test_assert,$(call xor,$(true),$(false)),$(true))
+$(call test_assert,$(call xor,$(false),$(true)),$(true))
+$(call test_assert,$(call xor,$(false),$(false)),$(false))
+$(call stop_test)
+
+$(call start_test,nand)
+$(call test_assert,$(call nand,$(true),$(true)),$(false))
+$(call test_assert,$(call nand,$(true),$(false)),$(true))
+$(call test_assert,$(call nand,$(false),$(true)),$(true))
+$(call test_assert,$(call nand,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,nor)
+$(call test_assert,$(call nor,$(true),$(true)),$(false))
+$(call test_assert,$(call nor,$(true),$(false)),$(false))
+$(call test_assert,$(call nor,$(false),$(true)),$(false))
+$(call test_assert,$(call nor,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,xnor)
+$(call test_assert,$(call xnor,$(true),$(true)),$(true))
+$(call test_assert,$(call xnor,$(true),$(false)),$(false))
+$(call test_assert,$(call xnor,$(false),$(true)),$(false))
+$(call test_assert,$(call xnor,$(false),$(false)),$(true))
+$(call stop_test)
+
+$(call start_test,first)
+$(call test_assert,$(call first,1 2 3),1)
+$(call test_assert,$(call first,1),1)
+$(call test_assert,$(call first,),)
+$(call stop_test)
+
+$(call start_test,last)
+$(call test_assert,$(call last,1 2 3),3)
+$(call test_assert,$(call last,1),1)
+$(call test_assert,$(call last,),)
+$(call stop_test)
+
+$(call start_test,rest)
+$(call test_assert,$(call rest,1 2 3),2 3)
+$(call test_assert,$(call rest,1),)
+$(call test_assert,$(call rest,),)
+$(call stop_test)
+
+$(call start_test,chop)
+$(call test_assert,$(call chop,1 2 3),1 2)
+$(call test_assert,$(call chop,1 2 3 4),1 2 3)
+$(call test_assert,$(call chop,1),)
+$(call test_assert,$(call chop,),)
+$(call stop_test)
+
+$(call start_test,length)
+$(call test_assert,$(call length,1 2 3),3)
+$(call test_assert,$(call length,1 2 3 4),4)
+$(call test_assert,$(call length,1),1)
+$(call test_assert,$(call length,),0)
+$(call stop_test)
+
+$(call start_test,map)
+$(call test_assert,$(call map,origin,__undefined map MAKE),undefined file default)
+$(call test_assert,$(call map,origin,),)
+$(call stop_test)
+
+joinem = $1$2
+$(call start_test,pairmap)
+$(call test_assert,$(call pairmap,addsuffix,2 1 3,a b c),a2 b1 c3)
+$(call test_assert,$(call pairmap,addprefix,2 1 3,a b c d),2a 1b 3c d)
+$(call test_assert,$(call pairmap,addprefix,2 1 3 4,a b c),2a 1b 3c)
+$(call test_assert,$(call pairmap,joinem,2 1 3 4,a b c),2a 1b 3c 4)
+$(call stop_test)
+
+$(call start_test,seq)
+$(call test_assert,$(call seq,abc,abc),T)
+$(call test_assert,$(call seq,x,),)
+$(call test_assert,$(call seq,,x),)
+$(call test_assert,$(call seq,x,x),T)
+$(call test_assert,$(call seq,a%c,abc),)
+$(call test_assert,$(call seq,abc,a%c),)
+$(call test_assert,$(call seq,abc,ABC),)
+$(call test_assert,$(call seq,abc,),)
+$(call test_assert,$(call seq,,),T)
+$(call test_assert,$(call seq,a b c,a b c),T)
+$(call test_assert,$(call seq,aa% bb% cc,aa% bb% cc),T)
+$(call test_assert,$(call seq,aa% bb% cc,aa% bb cc),)
+$(call test_assert,$(call seq,aa% bb% cc,xx yy zz),)
+$(call stop_test)
+
+$(call start_test,sne)
+$(call test_assert,$(call sne,abc,abc),)
+$(call test_assert,$(call sne,x,),T)
+$(call test_assert,$(call sne,,x),T)
+$(call test_assert,$(call sne,x,x),)
+$(call test_assert,$(call sne,abc,ABC),T)
+$(call test_assert,$(call sne,abc,),T)
+$(call test_assert,$(call sne,,),)
+$(call test_assert,$(call sne,a b c,a b c),)
+$(call test_assert,$(call sne,aa% bb% cc,aa% bb% cc),)
+$(call test_assert,$(call sne,aa% bb% cc,aa% bb cc),T)
+$(call stop_test)
+
+$(call start_test,strlen)
+$(call test_assert,$(call strlen,),0)
+$(call test_assert,$(call strlen,a),1)
+$(call test_assert,$(call strlen,a b),3)
+$(call test_assert,$(call strlen,a ),2)
+$(call test_assert,$(call strlen, a),2)
+$(call test_assert,$(call strlen,  ),2)
+$(call test_assert,$(call strlen,   ),3)
+$(call test_assert,$(call strlen,    ),4)
+$(call stop_test)
+
+$(call start_test,substr)
+$(call test_assert,$(call substr,xyz,1,1),x)
+$(call test_assert,$(call substr,xyz,1,2),xy)
+$(call test_assert,$(call substr,xyz,2,3),yz)
+$(call test_assert,$(call substr,some string,1,1),s)
+$(call test_assert,$(call substr,some string,1,2),so)
+$(call test_assert,$(call substr,some string,1,3),som)
+$(call test_assert,$(call substr,some string,1,4),some)
+$(call test_assert,$(call substr,some string,1,5),some )
+$(call test_assert,$(call substr,some string,1,6),some s)
+$(call test_assert,$(call substr,some string,5,5), )
+$(call test_assert,$(call substr,some string,5,6), s)
+$(call test_assert,$(call substr,some string,5,7), st)
+$(call test_assert,$(call substr,some string,5,8), str)
+$(call test_assert,$(call substr,some string,1,100),some string)
+$(call stop_test)
+
+$(call start_test,lc)
+$(call test_assert,$(call lc,The Quick Brown Fox),the quick brown fox)
+$(call test_assert,$(call lc,the1 quick2 brown3 fox4),the1 quick2 brown3 fox4)
+$(call test_assert,$(call lc,The_),the_)
+$(call test_assert,$(call lc,),)
+$(call stop_test)
+
+$(call start_test,uc)
+$(call test_assert,$(call uc,The Quick Brown Fox),THE QUICK BROWN FOX)
+$(call test_assert,$(call uc,the1 quick2 brown3 fox4),THE1 QUICK2 BROWN3 FOX4)
+$(call test_assert,$(call uc,The_),THE_)
+$(call test_assert,$(call uc,),)
+$(call stop_test)
+
+$(call start_test,tr)
+$(call test_assert,$(call tr,A B C,1 2 3,CAPITAL),31PIT1L)
+$(call test_assert,$(call tr,a b c,1 2 3,CAPITAL),CAPITAL)
+$(call test_assert,$(call tr,E L I,3 1 1,I AM ELITE),1 AM 311T3)
+$(call stop_test)
+
+$(call start_test,leq)
+$(call test_assert,$(call leq,1 2 3,1 2 3),T)
+$(call test_assert,$(call leq,1 2 3,1 2 3 4),)
+$(call test_assert,$(call leq,1 2 3 4,1 2 3),)
+$(call test_assert,$(call leq,1,1),T)
+$(call test_assert,$(call leq,,),T)
+$(call stop_test)
+
+$(call start_test,lne)
+$(call test_assert,$(call lne,1 2 3,1 2 3),)
+$(call test_assert,$(call lne,1 2 3,1 2 3 4),T)
+$(call test_assert,$(call lne,1 2 3 4,1 2 3),T)
+$(call test_assert,$(call lne,1,1),)
+$(call test_assert,$(call lne,,),)
+$(call stop_test)
+
+$(call start_test,empty_set)
+$(call test_assert,$(empty_set),)
+$(call test_assert,$(empty_set),$(call set_create,))
+$(call stop_test)
+
+$(call start_test,set_create)
+$(call test_assert,$(call set_create,),)
+$(call test_assert,$(call set_create,1 2 2 3),1 2 3)
+$(call test_assert,$(call set_create,2 1 1 2 2 3),1 2 3)
+$(call test_assert,$(call set_create,1),1)
+$(call stop_test)
+
+$(call start_test,set_insert)
+$(call test_assert,$(call set_insert,1,$(empty_set)),1)
+$(call test_assert,$(call set_insert,1,$(call set_create,1)),1)
+$(call test_assert,$(call set_insert,1,$(call set_create,1 2)),1 2)
+$(call test_assert,$(call set_insert,0,$(call set_create,1 2)),0 1 2)
+$(call stop_test)
+
+$(call start_test,set_remove)
+$(call test_assert,$(call set_remove,1,$(empty_set)),$(empty_set))
+$(call test_assert,$(call set_remove,1,$(call set_create,1 2)),2)
+$(call test_assert,$(call set_remove,1,$(call set_create,1 11 2)),11 2)
+$(call test_assert,$(call set_remove,0,$(call set_create,1 2)),1 2)
+$(call stop_test)
+
+$(call start_test,set_is_member)
+$(call test_assert,$(call set_is_member,1,$(empty_set)),)
+$(call test_assert,$(call set_is_member,1,$(call set_create,2 3)),)
+$(call test_assert,$(call set_is_member,1,$(call set_create,1 2 3)),T)
+$(call test_assert,$(call set_is_member,1,$(call set_create,1)),T)
+$(call stop_test)
+
+$(call start_test,set_union)
+$(call test_assert,$(call set_union,,),)
+$(call test_assert,$(call set_union,1 2,),1 2)
+$(call test_assert,$(call set_union,,3 4),3 4)
+$(call test_assert,$(call set_union,1 2,3 4),1 2 3 4)
+$(call test_assert,$(call set_union,1 2 3,3 4 5),1 2 3 4 5)
+$(call stop_test)
+
+$(call start_test,set_intersection)
+$(call test_assert,$(call set_intersection,,),)
+$(call test_assert,$(call set_intersection,1 2,),)
+$(call test_assert,$(call set_intersection,,3 4),)
+$(call test_assert,$(call set_intersection,1 2,3 4),)
+$(call test_assert,$(call set_intersection,1 2 3 4,3 4 5),3 4)
+$(call stop_test)
+
+$(call start_test,set_is_subset)
+$(call test_assert,$(call set_is_subset,,),T)
+$(call test_assert,$(call set_is_subset,1 2,),)
+$(call test_assert,$(call set_is_subset,,3 4),T)
+$(call test_assert,$(call set_is_subset,1 2,3 4),)
+$(call test_assert,$(call set_is_subset,1 2,1 2 3 4 5),T)
+$(call test_assert,$(call set_is_subset,1 2,1 2),T)
+$(call test_assert,$(call set_is_subset,1 2,1 3 4 5),)
+$(call stop_test)
+
+$(call start_test,set_equal)
+$(call test_assert,$(call set_equal,,),T)
+$(call test_assert,$(call set_equal,1,),)
+$(call test_assert,$(call set_equal,,1),)
+$(call test_assert,$(call set_equal,1,1),T)
+$(call test_assert,$(call set_equal,1 2,),)
+$(call test_assert,$(call set_equal,,1 2),)
+$(call test_assert,$(call set_equal,1 2,1 2 3),)
+$(call stop_test)
+
+$(call start_test,int_encode)
+$(call test_assert,$(call int_encode,0),)
+$(call test_assert,$(call int_encode,1),x)
+$(call test_assert,$(call int_encode,2),x x)
+$(call test_assert,$(call int_encode,10),x x x x x x x x x x)
+$(call stop_test)
+
+$(call start_test,int_decode)
+$(call test_assert,$(call int_decode,),0)
+$(call test_assert,$(call int_decode,x),1)
+$(call test_assert,$(call int_decode,x x),2)
+$(call test_assert,$(call int_decode,x x x x x x x x x x),10)
+$(call stop_test)
+
+$(call start_test,int_plus)
+$(call test_assert,$(call int_plus,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,7))
+$(call test_assert,$(call int_plus,$(call int_encode,0),$(call int_encode,4)),$(call int_encode,4))
+$(call test_assert,$(call int_plus,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,3))
+$(call test_assert,$(call int_plus,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_plus,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,1))
+$(call stop_test)
+
+$(call start_test,plus)
+$(call test_assert,$(call plus,3,4),7)
+$(call test_assert,$(call plus,4,3),7)
+$(call test_assert,$(call plus,0,4),4)
+$(call test_assert,$(call plus,3,0),3)
+$(call test_assert,$(call plus,0,0),0)
+$(call stop_test)
+
+__gmsl_warning = $1
+$(call start_test,int_subtract)
+$(call test_assert,$(call int_subtract,$(call int_encode,3),$(call int_encode,4)),Subtraction underflow)
+$(call test_assert,$(call int_subtract,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1))
+$(call test_assert,$(call int_subtract,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,3))
+$(call test_assert,$(call int_subtract,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_subtract,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,1))
+$(call stop_test)
+
+__gmsl_warning = x x x x x x x x x x
+$(call start_test,subtract)
+$(call test_assert,$(call subtract,3,4),10)
+$(call test_assert,$(call subtract,4,3),1)
+$(call test_assert,$(call subtract,3,0),3)
+$(call test_assert,$(call subtract,0,0),0)
+$(call stop_test)
+
+$(call start_test,int_multiply)
+$(call test_assert,$(call int_multiply,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,12))
+$(call test_assert,$(call int_multiply,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,12))
+$(call test_assert,$(call int_multiply,$(call int_encode,3),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_multiply,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_multiply,$(call int_encode,1),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,multiply)
+$(call test_assert,$(call multiply,3,4),12)
+$(call test_assert,$(call multiply,4,3),12)
+$(call test_assert,$(call multiply,3,0),0)
+$(call test_assert,$(call multiply,0,3),0)
+$(call test_assert,$(call multiply,0,0),0)
+$(call stop_test)
+
+__gmsl_error = $1
+$(call start_test,int_divide)
+$(call test_assert,$(call int_divide,$(call int_encode,3),$(call int_encode,4)),$(call int_encode,0))
+$(call test_assert,$(call int_divide,$(call int_encode,4),$(call int_encode,3)),$(call int_encode,1))
+$(call test_assert,$(call int_divide,$(call int_encode,31),$(call int_encode,3)),$(call int_encode,10))
+$(call test_assert,$(call int_divide,$(call int_encode,30),$(call int_encode,3)),$(call int_encode,10))
+$(call test_assert,$(call int_divide,$(call int_encode,29),$(call int_encode,3)),$(call int_encode,9))
+$(call test_assert,$(call int_divide,$(call int_encode,0),$(call int_encode,1)),$(call int_encode,0))
+$(call test_assert,$(call int_divide,$(call int_encode,1),$(call int_encode,0)),Division by zero)
+$(call stop_test)
+
+__gmsl_error = x x x x x x x x x x
+$(call start_test,divide)
+$(call test_assert,$(call divide,3,4),0)
+$(call test_assert,$(call divide,4,3),1)
+$(call test_assert,$(call divide,21,2),10)
+$(call test_assert,$(call divide,20,2),10)
+$(call test_assert,$(call divide,19,2),9)
+$(call test_assert,$(call divide,1,0),10)
+$(call stop_test)
+
+$(call start_test,associative array)
+$(call test_assert,$(call get,myarray,key1),)
+$(call set,myarray,key1,value1)
+$(call test_assert,$(call get,myarray,key1),value1)
+$(call test_assert,$(call get,myarray,key2),)
+$(call test_assert,$(call get,myarray1,key1),)
+$(call test_assert,$(call defined,myarray,key1),T)
+$(call test_assert,$(call defined,myarray,key2),)
+$(call test_assert,$(call defined,myarray1,key1),)
+$(call set,myarray,key2,value2)
+$(call test_assert,$(call keys,myarray),key1 key2)
+$(call test_assert,$(call keys,myarray1),)
+$(call stop_test)
+
+$(call start_test,named stack)
+$(call test_assert,$(call pop,mystack),)
+$(call test_assert,$(call push,mystack,e2))
+$(call push,mystack,e1)
+$(call test_assert,$(call pop,mystack),e1)
+$(call test_assert,$(call pop,mystack),e2)
+$(call push,mystack,f3)
+$(call push,mystack,f1)
+$(call test_assert,$(call pop,mystack),f1)
+$(call push,mystack,f2)
+$(call test_assert,$(call peek,mystack),f2)
+$(call test_assert,$(call depth,mystack),2)
+$(call test_assert,$(call pop,mystack),f2)
+$(call test_assert,$(call depth,mystack),1)
+$(call test_assert,$(call pop,myotherstack),)
+$(call stop_test)
+
+$(call start_test,reverse)
+$(call test_assert,$(call reverse,),)
+$(call test_assert,$(call reverse,1),1)
+$(call test_assert,$(call reverse,1 2),2 1)
+$(call test_assert,$(call reverse,1 2 3),3 2 1)
+$(call stop_test)
+
+$(call start_test,uniq)
+$(call test_assert,$(call uniq,),)
+$(call test_assert,$(call uniq,a),a)
+$(call test_assert,$(call uniq,a a),a)
+$(call test_assert,$(call uniq,a aa),a aa)
+$(call test_assert,$(call uniq,a aa a),a aa)
+$(call test_assert,$(call uniq,a b ba ab b a a ba a),a b ba ab)
+$(call stop_test)
+
+c:=,
+$(call start_test,split)
+$(call test_assert,$(call split,$c,comma$cseparated$cstring),comma separated string)
+$(call test_assert,$(call split,*,star*field*record),star field record)
+$(call test_assert,$(call split,*,star*),star)
+$(call test_assert,$(call split,*,star*field),star field)
+$(call test_assert,$(call split,*,star****field),star field)
+$(call test_assert,$(call split,*,),)
+$(call stop_test)
+
+$(call start_test,merge)
+$(call test_assert,$(call merge,$c,list of things),list$cof$cthings)
+$(call test_assert,$(call merge,*,list of things),list*of*things)
+$(call test_assert,$(call merge,*,list),list)
+$(call test_assert,$(call merge,*,),)
+$(call stop_test)
+
+$(call start_test,int_max)
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,1),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,0)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,0),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,2),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_max,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,max)
+$(call test_assert,$(call max,2,1),2)
+$(call test_assert,$(call max,1,2),2)
+$(call test_assert,$(call max,2,0),2)
+$(call test_assert,$(call max,0,2),2)
+$(call test_assert,$(call max,2,2),2)
+$(call test_assert,$(call max,0,0),0)
+$(call stop_test)
+
+$(call start_test,int_min)
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,1)),$(call int_encode,1))
+$(call test_assert,$(call int_min,$(call int_encode,1),$(call int_encode,2)),$(call int_encode,1))
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_min,$(call int_encode,0),$(call int_encode,2)),$(call int_encode,0))
+$(call test_assert,$(call int_min,$(call int_encode,2),$(call int_encode,2)),$(call int_encode,2))
+$(call test_assert,$(call int_min,$(call int_encode,0),$(call int_encode,0)),$(call int_encode,0))
+$(call stop_test)
+
+$(call start_test,min)
+$(call test_assert,$(call min,2,1),1)
+$(call test_assert,$(call min,1,2),1)
+$(call test_assert,$(call min,2,0),0)
+$(call test_assert,$(call min,0,2),0)
+$(call test_assert,$(call min,2,2),2)
+$(call test_assert,$(call min,0,0),0)
+$(call stop_test)
+
+__gmsl_error = $1
+$(call start_test,assert functions)
+$(call test_assert,$(call assert,$(true),ignore),)
+$(call test_assert,$(call assert,$(false),failed),Assertion failure: failed)
+$(call test_assert,$(call assert_exists,gmsl-tests),)
+$(call test_assert,$(call assert_exists,MISSING-gmsl-tests),Assertion failure: file 'MISSING-gmsl-tests' missing)
+$(call stop_test)
+
+$(call start_test,int_inc)
+$(call test_assert,$(call int_inc,$(call int_encode,0)),$(call int_encode,1))
+$(call test_assert,$(call int_inc,$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_inc,$(call int_encode,4)),$(call int_encode,5))
+$(call test_assert,$(call int_inc,$(call int_encode,10)),$(call int_encode,11))
+$(call stop_test)
+
+$(call start_test,inc)
+$(call test_assert,$(call inc,0),1)
+$(call test_assert,$(call inc,1),2)
+$(call test_assert,$(call inc,4),5)
+$(call test_assert,$(call inc,10),11)
+$(call stop_test)
+
+__gmsl_warning = $1
+$(call start_test,int_dec)
+$(call test_assert,$(call int_dec,$(call int_encode,0)),Decrement underflow)
+$(call test_assert,$(call int_dec,$(call int_encode,1)),$(call int_encode,0))
+$(call test_assert,$(call int_dec,$(call int_encode,4)),$(call int_encode,3))
+$(call test_assert,$(call int_dec,$(call int_encode,10)),$(call int_encode,9))
+$(call stop_test)
+
+__gmsl_warning = x x x x x x x x x x
+$(call start_test,dec)
+$(call test_assert,$(call dec,0),10)
+$(call test_assert,$(call dec,1),0)
+$(call test_assert,$(call dec,4),3)
+$(call test_assert,$(call dec,10),9)
+$(call stop_test)
+
+$(call start_test,int_double)
+$(call test_assert,$(call int_double,$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_double,$(call int_encode,1)),$(call int_encode,2))
+$(call test_assert,$(call int_double,$(call int_encode,4)),$(call int_encode,8))
+$(call stop_test)
+
+$(call start_test,double)
+$(call test_assert,$(call double,0),0)
+$(call test_assert,$(call double,1),2)
+$(call test_assert,$(call double,4),8)
+$(call stop_test)
+
+$(call start_test,int_halve)
+$(call test_assert,$(call int_halve,$(call int_encode,0)),$(call int_encode,0))
+$(call test_assert,$(call int_halve,$(call int_encode,2)),$(call int_encode,1))
+$(call test_assert,$(call int_halve,$(call int_encode,8)),$(call int_encode,4))
+$(call test_assert,$(call int_halve,$(call int_encode,7)),$(call int_encode,3))
+$(call stop_test)
+
+$(call start_test,halve)
+$(call test_assert,$(call halve,0),0)
+$(call test_assert,$(call halve,2),1)
+$(call test_assert,$(call halve,8),4)
+$(call test_assert,$(call halve,7),3)
+$(call stop_test) 
+
+$(call start_test,gt)
+$(call test_assert,$(call gt,2,3),)
+$(call test_assert,$(call gt,3,2),$(true))
+$(call test_assert,$(call gt,2,2),)
+$(call stop_test)
+
+$(call start_test,gte)
+$(call test_assert,$(call gte,2,3),)
+$(call test_assert,$(call gte,3,2),$(true))
+$(call test_assert,$(call gte,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,lt)
+$(call test_assert,$(call lt,2,3),$(true))
+$(call test_assert,$(call lt,3,2),)
+$(call test_assert,$(call lt,2,2),)
+$(call stop_test)
+
+$(call start_test,lte)
+$(call test_assert,$(call lte,2,3),$(true))
+$(call test_assert,$(call lte,3,2),)
+$(call test_assert,$(call lte,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,eq)
+$(call test_assert,$(call eq,2,3),)
+$(call test_assert,$(call eq,3,2),)
+$(call test_assert,$(call eq,2,2),$(true))
+$(call stop_test)
+
+$(call start_test,ne)
+$(call test_assert,$(call ne,2,3),$(true))
+$(call test_assert,$(call ne,3,2),$(true))
+$(call test_assert,$(call ne,2,2),)
+$(call stop_test)
+
+$(call start_test,int_gt)
+$(call test_assert,$(call int_gt,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_gt,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_gt,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,int_gte)
+$(call test_assert,$(call int_gte,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_gte,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_gte,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_lt)
+$(call test_assert,$(call int_lt,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_lt,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_lt,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,int_lte)
+$(call test_assert,$(call int_lte,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_lte,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_lte,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_eq)
+$(call test_assert,$(call int_eq,$(call int_encode,2),$(call int_encode,3)),)
+$(call test_assert,$(call int_eq,$(call int_encode,3),$(call int_encode,2)),)
+$(call test_assert,$(call int_eq,$(call int_encode,2),$(call int_encode,2)),$(true))
+$(call stop_test)
+
+$(call start_test,int_ne)
+$(call test_assert,$(call int_ne,$(call int_encode,2),$(call int_encode,3)),$(true))
+$(call test_assert,$(call int_ne,$(call int_encode,3),$(call int_encode,2)),$(true))
+$(call test_assert,$(call int_ne,$(call int_encode,2),$(call int_encode,2)),)
+$(call stop_test)
+
+$(call start_test,gmsl_compatible)
+$(call test_assert,$(call gmsl_compatible,$(gmsl_version)),$(true))
+$(call test_assert,$(call gmsl_compatible,0 9 0),$(true))
+$(call test_assert,$(call gmsl_compatible,0 0 1),$(true))
+$(call test_assert,$(call gmsl_compatible,0 0 0),$(true))
+$(call test_assert,$(call gmsl_compatible,2 0 0),)
+$(call test_assert,$(call gmsl_compatible,1 1 0),)
+$(call test_assert,$(call gmsl_compatible,1 0 8),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 8),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 10),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 11),$(true))
+$(call test_assert,$(call gmsl_compatible,1 0 12),)
+$(call stop_test)
diff --git a/build/gmsl/index.html b/build/gmsl/index.html
new file mode 100644
index 0000000..8cc93ae
--- /dev/null
+++ b/build/gmsl/index.html
@@ -0,0 +1,687 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
+  <title>GNU Make Standard Library</title></head>
+
+<body>
+<h1>GNU Make Standard Library</h1>
+The GNU Make Standard Library (GMSL) is a collection of functions
+implemented using native GNU Make functionality that provide list and
+string manipulation, integer arithmetic, associative arrays, stacks,
+and debugging facilities.&nbsp; The GMSL is released under the BSD License.<br>
+<br>
+<a href="http://sourceforge.net/projects/gmsl/">[Project Page]</a> <a href="http://sourceforge.net/project/showfiles.php?group_id=129887">[Download]</a>
+<a href="http://sourceforge.net/forum/forum.php?forum_id=443916">[Discussion
+Forum]</a><br>
+<h2>Using GMSL</h2>
+The two files needed are <span style="font-family: monospace;">gmsl</span>
+and <span style="font-family: monospace;">__gmsl</span>.&nbsp; To
+include the GMSL in your Makefile do<br>
+<pre style="margin-left: 40px;">include gmsl</pre>
+<span style="font-family: monospace;">gmsl</span> automatically includes<span style="font-family: monospace;"> __gmsl</span>.&nbsp; To check that
+you have the right version of <span style="font-family: monospace;">gmsl</span>
+use the <span style="font-family: monospace;">gmsl_compatible</span>
+function (see
+below). The current version is <span style="font-family: monospace;">1
+0 11</span>.<br>
+<br>
+The GMSL package also includes a test suite for GMSL.&nbsp; Just run <span style="font-family: monospace;">make -f gmsl-tests</span>.<br>
+<h2>Logical Operators</h2>GMSL has boolean $(true) (a non-empty string)
+and $(false) (an empty string).&nbsp; The following operators can be
+used with those variables.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><span style="font-weight: bold;">not</span><br>
+
+<br>
+
+<span style="font-family: monospace;">Arguments: A boolean value</span><br style="font-family: monospace;">
+
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if the boolean is $(false) and vice versa</span><br style="font-family: monospace;">
+
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;"></span><span style="font-weight: bold;">and</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if both of the booleans are true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">or</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if either of the booleans is true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xor</span><br style="font-weight: bold;">
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns $(true) if exactly one of the booleans is true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nand</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not and'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nor</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not or'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xnor</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns:&nbsp;&nbsp; Returns value of 'not xor'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;">
+<h2>List Manipulation Functions</h2>
+&nbsp;A list is a string of characters; the list separator is a space.<br>
+
+<br>
+<hr style="width: 100%; height: 2px;"><b>first</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the first element of a list<br>
+</span>
+<hr><b>last</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the last element of a list<br>
+</span>
+<hr><b>rest</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the list with the first element
+removed<br>
+</span>
+<hr><b>chop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the list with the last element removed<br>
+</span>
+<hr><b>map</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of function to
+$(call) for each element of list<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: List to
+iterate over calling the function in 1<br>
+Returns:&nbsp;&nbsp;&nbsp;The list after calling the function on each
+element<br>
+</span>
+<hr><b>pairmap</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of function to
+$(call) for each pair of elements<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: List to
+iterate over calling the function in 1<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: Second
+list to iterate over calling the function in 1<br>
+Returns:&nbsp;&nbsp;&nbsp;The list after calling the function on each
+pair of elements<br>
+</span>
+<hr><b>leq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two lists are identical<br>
+</span>
+<hr><b>lne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+list<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two lists are different<br>
+</span>
+<hr><b>reverse</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to reverse<br>
+Returns:&nbsp;&nbsp;&nbsp;The list with its elements in reverse order<br>
+</span>
+<hr><b>uniq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to deduplicate<br>
+Returns:&nbsp;&nbsp;&nbsp;The list with elements in order without duplicates<br>
+</span>
+<hr><b>length</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns:&nbsp;&nbsp;&nbsp;The number of elements in the list<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>String Manipulation Functions</h2>
+A string is any sequence of characters.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>seq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two strings are
+identical<br>
+</span>
+<hr><b>sne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string to compare
+against...<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: ...this
+string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two strings are not
+the same<br>
+</span>
+<hr><b>strlen</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the length of the string<br>
+</span>
+<hr><b>substr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Start offset (first character is 1)<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: Ending offset (inclusive)<br>Returns:&nbsp;&nbsp;&nbsp;Returns a substring<br>
+</span>
+<hr><b>split</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+split on<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: A
+string to split<br>
+Returns:&nbsp;&nbsp;&nbsp;Splits a string into a list separated by
+spaces at the split<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; character
+in the first argument<br>
+</span>
+<hr><b>merge</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+put between fields<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: A list
+to merge into a string<br>
+Returns:&nbsp;&nbsp;&nbsp;Merges a list into a single string, list
+elements are separated<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by the
+character in the first argument<br>
+</span>
+<hr><b>tr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The list of
+characters to translate from <br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The
+list of characters to translate to<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: The
+text to translate<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text after translating characters<br>
+</span>
+<hr><b>uc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Text to upper case<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text in upper case<br>
+</span>
+<hr><b>lc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Text to lower case<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the text in lower case<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Set Manipulation Functions</h2>
+Sets are represented by sorted, deduplicated lists.  To create a set
+from a list use <span style="font-family:
+monospace;">set_create</span>, or start with the <span
+style="font-family: monospace;">empty_set</span> and <span
+style="font-family: monospace;">set_insert</span> individual elements.
+The empty set is defined as <span style="font-family:
+monospace;">empty_set</span>.<p>
+
+<hr><b>set_create</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list of set elements<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the newly created set<br>
+</span>
+
+<hr><b>set_insert</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element to add to a set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the set with the element added<br>
+</span>
+
+<hr><b>set_remove</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element to remove from a set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the set with the element removed<br>
+</span>
+
+<hr><b>set_is_member</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: A set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the element is in the set<br>
+</span>
+
+<hr><b>set_union</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the union of the two sets<br>
+</span>
+
+<hr><b>set_intersection</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the intersection of the two sets<br>
+</span>
+
+<hr><b>set_is_subset</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the first set is a subset of the second<br>
+</span>
+
+<hr><b>set_equal</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2: Another set<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns $(true) if the two sets are identical<br>
+</span>
+
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Integer Arithmetic Functions</h2>
+Integers are represented by lists with the equivalent number of
+x's.&nbsp; For example the number 4 is x x x x.&nbsp; The maximum
+integer that the library can handle as <span style="font-style: italic;">input</span> (i.e. as the argument to a
+call to <span style="font-family: monospace;">int_encode</span>) is
+65536. There is no limit on integer size for internal computations or
+output.<br>
+<br>
+The arithmetic library functions come in two forms: one form of each
+function takes integers as arguments and the other form takes the
+encoded form (x's created by a call to <span style="font-family: monospace;">int_encode</span>).&nbsp; For example,
+there are two plus functions: <span style="font-family: monospace;">plus</span>
+(called with integer arguments and returns an integer) and <span style="font-family: monospace;">int_plus</span> (called with encoded
+arguments and returns an encoded result).<br>
+<br>
+<span style="font-family: monospace;">plus</span> will be slower than <span style="font-family: monospace;">int_plus</span> because its arguments
+and result have to be translated between the x's format and
+integers.&nbsp; If doing a complex calculation use the <span style="font-family: monospace;">int_*</span> forms with a single
+encoding of inputs and single decoding of the output.&nbsp; For simple
+calculations the direct forms can be used.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>int_decode</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number of x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer for human consumption
+that is represented<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by the
+string of x's<br>
+</span>
+<hr><b>int_encode</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in
+human-readable integer form<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer encoded as a string of x's<br>
+</span>
+<hr><b>int_plus</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the sum of the two numbers in x's
+representation<br>
+</span>
+<hr><b>plus (wrapped version of int_plus)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the sum of the two integers<br>
+</span>
+<hr><b>int_subtract</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the difference of the two numbers in
+x's representation,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or outputs
+an error on a numeric underflow<br>
+</span>
+<hr><b>subtract (wrapped version of int_subtract)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the difference of the two integers,<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; or outputs
+an error on a numeric underflow<br>
+</span>
+<hr><b>int_multiply</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the product of the two numbers in x's
+representation<br>
+</span>
+<hr><b>multiply (wrapped version of int_multiply)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the product of the two integers<br>
+</span>
+<hr><b>int_divide</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the result of integer division of
+argument 1 divided<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; by
+argument 2 in x's representation<br>
+</span>
+<hr><b>divide (wrapped version of int_divide)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the integer division of the first
+argument by the second<br>
+</span>
+<hr><b>int_max, int_min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+number in x's represntation<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the maximum or minimum of its
+arguments in x's<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+representation<br>
+</span>
+<hr><b>max, min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Another
+integer<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns the maximum or minimum of its integer
+arguments<br>
+</span>
+<hr><b>int_gt, int_gte, int_lt, int_lte, int_eq, int_ne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two x's representation
+numbers to be compared<br>
+Returns:&nbsp;&nbsp;&nbsp;$(true) or $(false)<br>
+<br>
+int_gt First argument greater than second argument<br>
+int_gte First argument greater than or equal to second argument<br>
+int_lt First argument less than second argument <br>
+int_lte First argument less than or equal to second argument<br>
+int_eq First argument is numerically equal to the second argument<br>
+int_ne First argument is not numerically equal to the second argument<br>
+</span>
+<hr><b>gt, gte, lt, lte, eq, ne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two integers to be
+compared<br>
+Returns:&nbsp;&nbsp;&nbsp;$(true) or $(false)<br>
+<br>
+gt First argument greater than second argument<br>
+gte First argument greater than or equal to second argument<br>
+lt First argument less than second argument <br>
+lte First argument less than or equal to second argument<br>
+eq First argument is numerically equal to the second argument<br>
+ne First argument is not numerically equal to the second argument<br>
+</span>
+increment adds 1 to its argument, decrement subtracts 1. Note that<br>
+decrement does not range check and hence will not underflow, but<br>
+will incorrectly say that 0 - 1 = 0<br>
+<hr><b>int_inc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number incremented by 1 in x's
+representation<br>
+</span>
+<hr><b>inc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The argument incremented by 1<br>
+</span>
+<hr><b>int_dec</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number decremented by 1 in x's
+representation<br>
+</span>
+<hr><b>dec</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The argument decremented by 1<br>
+</span>
+<hr><b>int_double</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number doubled (i.e. * 2) and returned in
+x's representation<br>
+</span>
+<hr><b>double</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The integer times 2<br>
+</span>
+<hr><b>int_halve</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns:&nbsp;&nbsp;&nbsp;The number halved (i.e. / 2) and returned in
+x's representation<br>
+</span>
+<hr><b>halve</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns:&nbsp;&nbsp;&nbsp;The integer divided by 2<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Associative Arrays</h2>
+An associate array maps a key value (a string with no spaces in it) to
+a single value (any string).&nbsp;&nbsp;&nbsp; <br>
+<b><br>
+</b>
+<hr style="width: 100%; height: 2px;"><b>set</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+value to associate<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3: The
+value associated with the key<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>get</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+to retrieve<br>
+Returns:&nbsp;&nbsp;&nbsp;The value stored in the array for that key<br>
+</span>
+<hr><b>keys</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns a list of all defined keys in the
+array<br>
+</span>
+<hr><b>defined</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The key
+to test<br>
+Returns:&nbsp;&nbsp;&nbsp;Returns true if the key is defined (i.e. not
+empty)<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Named Stacks</h2>
+A stack is an ordered list of strings (with no spaces in them).<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>push</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: Value
+to push onto the top of the stack (must not contain<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a space)<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>pop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Top element from the stack after removing it<br>
+</span>
+<hr><b>peek</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Top element from the stack without removing it<br>
+</span>
+<hr><b>depth</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns:&nbsp;&nbsp;&nbsp;Number of items on the stack<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Miscellaneous and Debugging Facilities</h2>
+GMSL defines the following constants; all are accessed as normal GNU
+Make variables by wrapping them in <span style="font-family: monospace;">$()</span> or <span style="font-family: monospace;">${}</span>.<br>
+<br>
+<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td><span style="font-style: italic;">Constant</span><br>
+      </td>
+      <td><span style="font-style: italic;">Value</span><br>
+      </td>
+      <td><span style="font-style: italic;">Purpose</span><br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">true</span><br>
+      </td>
+      <td><span style="font-family: monospace;">T</span><br>
+      </td>
+      <td>Boolean for <span style="font-family: monospace;">$(if)</span>
+and return from&nbsp; GMSL functions<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">false</span><br>
+      </td>
+      <td><br>
+      </td>
+      <td>Boolean for <span style="font-family: monospace;">$(if)</span>
+and return from GMSL functions<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">gmsl_version</span><br>
+      </td>
+      <td><span style="font-family: monospace;">1 0 0</span><br>
+      </td>
+      <td>GMSL version number as list: major minor revision<br>
+      </td>
+    </tr>
+  </tbody>
+</table>
+<span style="font-weight: bold;"><br>
+gmsl_compatible</span><span style="font-family: monospace;"><br>
+<br>
+Arguments: List containing the desired library version number (maj min
+rev)<br>
+</span><span style="font-family: monospace;">Returns:&nbsp;&nbsp;
+$(true) if this version of the library is compatible<br>
+</span><span style="font-family: monospace;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+with the requested version number, otherwise $(false)</span>
+<hr><b>gmsl-print-% (target not a function)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: The % should be
+replaced by the name of a variable that you<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wish to
+print out.<br>
+Action:&nbsp;&nbsp;&nbsp; Echos the name of the variable that matches
+the % and its value.<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; For
+example, 'make gmsl-print-SHELL' will output the value of<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; the SHELL
+variable<br>
+</span>
+<hr><b>assert</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A boolean that must
+be true or the assertion will fail<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2: The
+message to print with the assertion<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr><b>assert_exists</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of file that
+must exist, if it is missing an assertion<br>
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; will be
+generated<br>
+Returns:&nbsp;&nbsp;&nbsp;None<br>
+</span>
+<hr style="width: 100%; height: 2px;"><br>
+GMSL has a number of environment variables (or command-line overrides)
+that control various bits of functionality:<br>
+<br>
+<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td><span style="font-style: italic;">Variable</span><br>
+      </td>
+      <td><span style="font-style: italic;">Purpose</span><br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_NO_WARNINGS</span><br>
+      </td>
+      <td>If set prevents GMSL from outputting warning messages:
+artithmetic functions generate underflow warnings.<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_NO_ERRORS</span><br>
+      </td>
+      <td>If set prevents GMSL from generating fatal errors: division
+by zero or failed assertions are fatal.<br>
+      </td>
+    </tr>
+    <tr>
+      <td><span style="font-family: monospace;">GMSL_TRACE</span><br>
+      </td>
+      <td>Enables function tracing.&nbsp; Calls to GMSL functions will
+result in name and arguments being traced.<br>
+      </td>
+    </tr>
+  </tbody>
+</table>
+<span style="font-family: monospace;"></span><br>
+<hr>
+Copyright (c) 2005-2006 <a href="http://www.jgc.org/">John Graham-Cumming</a>.<br>
+<hr style="width: 100%; height: 2px;">
+<table style="width: 100%; text-align: left;" border="0" cellpadding="2" cellspacing="2">
+  <tbody>
+    <tr>
+      <td style="width: 50%;">John Graham-Cumming's work on this
+project was sponsored by <a href="http://www.electric-cloud.com/">Electric
+Cloud, Inc</a>.<br>
+      <a href="http://www.electric-cloud.com/"><img alt="" src="http://gmsl.sf.net/ec_logo.gif" style="border: 0px solid ; width: 223px; height: 47px;"></a><br>
+      </td>
+      <td align="right">
+      <p><a href="http://sourceforge.net/"><img src="http://sourceforge.net/sflogo.php?group_id=129887&amp;type=1" alt="SourceForge.net Logo" border="0" height="31" width="88"></a></p>
+      </td>
+    </tr>
+  </tbody>
+</table>
+</body></html>
diff --git a/build/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..153d6f2
--- /dev/null
+++ b/build/lib/build_support.py
@@ -0,0 +1,322 @@
+#
+# 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 datetime
+import multiprocessing
+import os
+import shutil
+import subprocess
+import sys
+import tempfile
+import timeit
+import zipfile
+
+
+THIS_DIR = os.path.realpath(os.path.dirname(__file__))
+
+
+# TODO: Make the x86 toolchain names just be the triple.
+ALL_TOOLCHAINS = (
+    'arm-linux-androideabi',
+    'aarch64-linux-android',
+    'mipsel-linux-android',
+    'mips64el-linux-android',
+    'x86',
+    'x86_64',
+)
+
+
+ALL_TRIPLES = (
+    'arm-linux-androideabi',
+    'aarch64-linux-android',
+    'mipsel-linux-android',
+    'mips64el-linux-android',
+    'i686-linux-android',
+    'x86_64-linux-android',
+)
+
+
+ALL_ARCHITECTURES = (
+    'arm',
+    'arm64',
+    'mips',
+    'mips64',
+    'x86',
+    'x86_64',
+)
+
+
+ALL_ABIS = (
+    'armeabi',
+    'armeabi-v7a',
+    'arm64-v8a',
+    'mips',
+    'mips64',
+    'x86',
+    'x86_64',
+)
+
+
+LP32_ABIS = ('armeabi', 'armeabi-v7a', 'mips', 'x86')
+LP64_ABIS = ('arm64-v8a', 'mips64', 'x86_64')
+
+
+def minimum_platform_level(abi):
+    if abi in LP64_ABIS:
+        return 21
+    else:
+        return 9
+
+
+class Timer(object):
+    def __init__(self):
+        self.start_time = None
+        self.end_time = None
+        self.duration = None
+
+    def start(self):
+        self.start_time = timeit.default_timer()
+
+    def finish(self):
+        self.end_time = timeit.default_timer()
+
+        # Not interested in partial seconds at this scale.
+        seconds = int(self.end_time - self.start_time)
+        self.duration = datetime.timedelta(seconds=seconds)
+
+    def __enter__(self):
+        self.start()
+
+    def __exit__(self, _exc_type, _exc_value, _traceback):
+        self.finish()
+
+
+def arch_to_toolchain(arch):
+    return dict(zip(ALL_ARCHITECTURES, ALL_TOOLCHAINS))[arch]
+
+
+def arch_to_triple(arch):
+    return dict(zip(ALL_ARCHITECTURES, ALL_TRIPLES))[arch]
+
+
+def toolchain_to_arch(toolchain):
+    return dict(zip(ALL_TOOLCHAINS, ALL_ARCHITECTURES))[toolchain]
+
+
+def arch_to_abis(arch):
+    return {
+        'arm': ['armeabi', 'armeabi-v7a'],
+        'arm64': ['arm64-v8a'],
+        'mips': ['mips'],
+        'mips64': ['mips64'],
+        'x86': ['x86'],
+        'x86_64': ['x86_64'],
+    }[arch]
+
+
+def abi_to_arch(arch):
+    return {
+        'armeabi': 'arm',
+        'armeabi-v7a': 'arm',
+        'arm64-v8a': 'arm64',
+        'mips': 'mips',
+        'mips64': 'mips64',
+        'x86': 'x86',
+        'x86_64': 'x86_64',
+    }[arch]
+
+
+def android_path(*args):
+    top = os.path.realpath(os.path.join(THIS_DIR, '../../..'))
+    return os.path.normpath(os.path.join(top, *args))
+
+
+def sysroot_path(toolchain):
+    arch = toolchain_to_arch(toolchain)
+    # Only ARM has more than one ABI, and they both have the same minimum
+    # platform level.
+    abi = arch_to_abis(arch)[0]
+    version = minimum_platform_level(abi)
+
+    prebuilt_ndk = 'prebuilts/ndk/current'
+    sysroot_subpath = 'platforms/android-{}/arch-{}'.format(version, arch)
+    return android_path(prebuilt_ndk, sysroot_subpath)
+
+
+def ndk_path(*args):
+    return android_path('ndk', *args)
+
+
+def toolchain_path(*args):
+    return android_path('toolchain', *args)
+
+
+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 _get_dir_from_env(default, env_var):
+    path = os.path.realpath(os.getenv(env_var, default))
+    if not os.path.isdir(path):
+        os.makedirs(path)
+    return path
+
+
+def get_out_dir():
+    return _get_dir_from_env(android_path('out'), 'OUT_DIR')
+
+
+def get_dist_dir(out_dir):
+    return _get_dir_from_env(os.path.join(out_dir, 'dist'), 'DIST_DIR')
+
+
+def get_default_host():
+    if sys.platform in ('linux', 'linux2'):
+        return 'linux'
+    elif sys.platform == 'darwin':
+        return 'darwin'
+    elif sys.platform == 'win32':
+        return 'windows'
+    else:
+        raise RuntimeError('Unsupported host: {}'.format(sys.platform))
+
+
+def host_to_tag(host):
+    if host in ['darwin', 'linux']:
+        return host + '-x86_64'
+    elif host == 'windows':
+        return 'windows'
+    elif host == 'windows64':
+        return 'windows-x86_64'
+    else:
+        raise RuntimeError('Unsupported host: {}'.format(host))
+
+
+def make_repo_prop(out_dir):
+    file_name = 'repo.prop'
+
+    dist_dir = os.environ.get('DIST_DIR')
+    if dist_dir is not None:
+        dist_repo_prop = os.path.join(dist_dir, file_name)
+        shutil.copy(dist_repo_prop, out_dir)
+    else:
+        out_file = os.path.join(out_dir, file_name)
+        with open(out_file, 'w') as prop_file:
+            cmd = [
+                'repo', 'forall', '-c',
+                'echo $REPO_PROJECT $(git rev-parse HEAD)',
+            ]
+            subprocess.check_call(cmd, stdout=prop_file)
+
+
+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:
+        subprocess.check_call(
+            ['zip', '-x', '*.pyc', '-x', '*.pyo', '-x', '*.swp',
+             '-x', '*.git*', '-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..d3700b4
--- /dev/null
+++ b/build/ndk-build
@@ -0,0 +1,275 @@
+#!/bin/sh
+#
+# 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`
+
+# 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=
+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_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 $PROGDIR/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=$PROGDIR/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/build/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`
+    for ABI in $APP_ABIS; do
+        TOOLCHAIN_PREFIX=`get_build_var_for_abi TOOLCHAIN_PREFIX $ABI`
+        LLVM_PATH=$PROGDIR/toolchains/llvm-${DEFAULT_LLVM_VERSION}/prebuilt
+        perl $LLVM_PATH/tools/scan-build/scan-build \
+            --use-analyzer $LLVM_PATH/bin/${ABI}/analyzer \
+            --use-cc ${TOOLCHAIN_PREFIX}gcc \
+            --use-c++ ${TOOLCHAIN_PREFIX}g++ \
+            --status-bugs \
+            $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..76190f4
--- /dev/null
+++ b/build/repo.prop
@@ -0,0 +1,55 @@
+platform/bionic ed9e6a41c92c9552be84ecc126e29b4604eee246
+platform/development 33b95fc1d131d4b07a67d14dce776217f4c36d9a
+platform/external/googletest 013ee6fccb6bb9ebd6215b504f0eef45dccfde4e
+platform/external/libcxx 45e09a55b249d0d97942702c26850e4b3c424b92
+platform/external/libcxxabi 9711d72e91f48830db3f4e8133d1e2e328e8504c
+platform/external/libunwind_llvm fecc6f26cfdbfc9cf0ea2021629ac6e85b7c0113
+platform/external/llvm c62dc90488ad1807fab24cb56f98fb88585c08a2
+platform/external/shaderc/glslang 59ebccccee399c0577230aeb608259fa71d7b1b7
+platform/external/shaderc/shaderc fcd85bc9ec80390d39d204360d2c36a6423146f0
+platform/external/shaderc/spirv-headers 9bec171dc9ffda91c2291102c04d75b10bf01e8a
+platform/external/shaderc/spirv-tools 410cd1fca9703990880d4ddc53bb0b367889b173
+platform/external/vulkan-validation-layers cbc75f522adb1f0cc3d86caae467faccce840b04
+platform/manifest c421db3ebcf25f0642b4032118d4a2754f6f457c
+platform/ndk d982fe4778a3d7d00c4df53502d630c808f025a3
+platform/prebuilts/clang/host/darwin-x86 e60e8d81fb820b988728ea5b2ab6c8f34bc2d978
+platform/prebuilts/clang/host/linux-x86 860bed8090d2d47e5646b34ef2ed7e756d222bc4
+platform/prebuilts/clang/host/windows-x86 90efd850fcd95bfdd9945e4c0e90e4cb396d2a6c
+platform/prebuilts/cmake/darwin-x86 289589930105f9db21313bfd5aaa4a5fe02509e5
+platform/prebuilts/cmake/linux-x86 ee96b2ec399702e23faee15863fed3ae33144fdd
+platform/prebuilts/gcc/darwin-x86/aarch64/aarch64-linux-android-4.9 51fa77f10f8c5ee658bfaf3e5a2a29ebd8de50d2
+platform/prebuilts/gcc/darwin-x86/arm/arm-eabi-4.8 6d08ca9f45ff685648fd13c75bf5cac4b11c19bb
+platform/prebuilts/gcc/darwin-x86/arm/arm-linux-androideabi-4.9 39fd9577fe3895a68a921216836ebdd46b4255a8
+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 4ba48d4ace63404304f201dc7d5e87ac55fc7d59
+platform/prebuilts/gcc/darwin-x86/x86/x86_64-linux-android-4.9 2500bd9aaa640c179730df7f7315d5ee90e4c3c1
+platform/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 423c0265176bcabd1c885f8cf6f0cedf67d3f59b
+platform/prebuilts/gcc/linux-x86/arm/arm-eabi-4.8 26e93f6af47f7bd3a9beb5c102a5f45e19bfa38a
+platform/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9 887574f98e97475d6fb2f91a8f7b24602466017a
+platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8 1273431a189717842f033573eb8c777e13dd88b7
+platform/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8 73ca99196723f810dad42390d154654354f57c16
+platform/prebuilts/gcc/linux-x86/host/x86_64-w64-mingw32-4.8 c795eed743bc6cee4ead5407cc237c43abf6fa26
+platform/prebuilts/gcc/linux-x86/mips/mips64el-linux-android-4.9 88bfecab5b700a1f6a601434d5816fab6c9261fc
+platform/prebuilts/gcc/linux-x86/x86/x86_64-linux-android-4.9 e3b93a8f44d43101b396d41ef30562885714e130
+platform/prebuilts/ndk adc9927c0f3f5107a777a67b94a4b1f447255681
+platform/prebuilts/ninja/darwin-x86 cc147ae2956e96279085abfadda2767b50edc2cc
+platform/prebuilts/ninja/linux-x86 543112c6744acb7a018ac36118eb2a862834809b
+platform/prebuilts/python/darwin-x86/2.7.5 0c5958b1636c47ed7c284f859c8e805fd06a0e63
+platform/prebuilts/python/linux-x86/2.7.5 ce294655f981e19b420f2201b7c499a435ef1ce2
+platform/prebuilts/simpleperf 7323ef4840428a32b6e9d8b58fcce87e05295b05
+toolchain/binutils 6422a80df992e4542dbd4fb70a04f316065674af
+toolchain/build f280657461aee54b6d2807881d8a77832f4e794c
+toolchain/cloog 604793eab97d360aef729f064674569ee6dbf3e1
+toolchain/expat 40172a0ae9d40a068f1e1a48ffcf6a1ccf765ed5
+toolchain/gcc 535de7eb0179bdcd01fcd99f1dad6208250d3706
+toolchain/gdb b66267cc5491513a9ad0369761a1c1b52bf15fed
+toolchain/gmp b2acd5dbf47868ac5b5bc844e16d2cadcbd4c810
+toolchain/isl 0ccf95726af8ce58ad61ff474addbce3a31ba99c
+toolchain/mpc 835d16e92eed875638a8b5d552034c3b1aae045b
+toolchain/mpfr de979fc377db766591e7feaf052f0de59be46e76
+toolchain/ppl 979062d362bc5a1c00804237b408b19b4618fb24
+toolchain/python 6a7fc9bfd21da85dda97a8bcd2952e0bfbded424
+toolchain/sed 45df23d6dc8b51ea5cd903d023c10fd7d72415b9
+toolchain/xz 595407f5a237e9bfd6821d70096d38825ec9c4e0
+toolchain/yasm a159fe073809b4138cf90b7298ea31ea17af85c0
diff --git a/build/tools/README.md b/build/tools/README.md
new file mode 100644
index 0000000..dd27d97
--- /dev/null
+++ b/build/tools/README.md
@@ -0,0 +1,533 @@
+This directory contains a number of shell scripts, which we will
+call the "dev-scripts", that are only used to develop the NDK
+itself, i.e. they are not needed when using ndk-build to build
+applicative native code.
+
+Their purpose is to handle various sophisticated issues:
+
+ * Rebuilding host cross-toolchains for our supported CPU ABIs.
+
+ * Rebuilding other required host tools (e.g. ndk-stack) from sources.
+
+ * Rebuilding all target-specific prebuilt binaries from sources (this requires
+   working host cross-toolchains).
+
+ * Packaging final NDK release tarballs, including adding documentation which
+   normally lives in $NDK/../development/ndk.
+
+This document is here to explain how to use these dev-scripts and how everything
+is architected / designed, in case you want to maintain it.
+
+Generally, everything dev-script supports the --help option to display a
+description of the program and the list of all supported options. Also, debug
+traces can be activated by using the --verbose option. Use it several times to
+increase the level of verbosity.
+
+Note that all Windows host programs can be built on Linux if you have the
+`mingw-w64` cross-toolchain installed (`apt-get install mingw-w64` on Debian or
+Ubuntu). You will need to add the `--mingw` option when invoking the script.
+
+All dev-scripts rebuilding host programs on Linux and Darwin will only generate
+32-bit programs by default. You can experiment with 64-bit binary generation by
+adding the `--try-64` option. Note that as of now, 64-bit binaries are never
+distributed as part of official NDK releases.
+
+When building 32-bit Linux host programs, the dev-scripts will look for
+`$ANDROID_BUILD_TOP/prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.11-4.8`,
+which is part of the Android platform source tree. It is a special toolchain
+that ensures that the generated programs can run on old systems like Ubuntu 8.04
+that only have GLibc 2.7. Otherwise, the corresponding binaries may not run due
+to ABI changes in more recent versions of GLibc.
+
+I. Organization:
+================
+
+First, a small description of the NDK's overall directory structure:
+
+build/core
+----------
+
+Contains the main NDK build system used when `ndk-build`. Relies heavily on GNU
+Make 3.81+ but isn't used by any of the scripts described here.
+
+build/tools
+-----------
+
+Contains all the dev-scripts that are described in this document. More on this
+later.
+
+sources/host-tools
+------------------
+
+Contains sources of various libraries or programs that will be compiled to
+generate useful host programs for the final NDK installation. For example,
+$NDK/sources/host-tools/ndk-stack/ contains the sources of the `ndk-stack`
+program.
+
+sources/cxx-stl
+---------------
+
+Contains the sources of various C++ runtime and libraries that can be used with
+`ndk-build`. See docs/CPLUSPLUS-SUPPORT.html for more details.
+
+sources/cxx-stl/gabi++
+----------------------
+
+Contains the sources of the GAbi++ C++ runtime library. Only used via stlport or
+libc++.
+
+sources/cxx-stl/stlport
+-----------------------
+
+Contains the sources of a port of STLport that can be used with `ndk-build`. The
+dev-script `build-cxx-stl.sh` can be used to generate prebuilt libraries from
+these sources, that will be copied under this directory.
+
+sources/cxx-stl/llvm-libc++
+---------------------------
+
+Contains the sources of a port of LLVM's libc++ that can be used with ndk-build.
+The dev-script `build-cxx-stl.sh` can be used to generate prebuilt libraries
+from these sources, that will be copied under this directory.
+
+sources/cxx-stl/gnu-libstdc++
+-----------------------------
+
+This directory doesn't contain sources at all, only an Android.mk. The
+dev-script `build-gnu-libstdc++.sh` is used to generate prebuilt libraries from
+the sources that are located in the toolchain source tree instead.
+
+sources/cxx-stl/system
+----------------------
+
+This directory contains a few headers used to use the native system Android C++
+runtime (with _very_ limited capabilities), a.k.a. /system/lib/libstdc++.so. The
+prebuilt version of this library is generated by the `gen-platform.sh`
+dev-script described later, but it never placed in this directory.
+
+sources/android/libthread\_db
+-----------------------------
+
+This directory contains the sources of the libthread\_db implementation that is
+linked into the prebuilt target gdbserver binary.
+
+sources
+-------
+
+The rest of `sources` is used to store the sources of helper libraries used with
+`ndk-build`. For example, the `cpu-features` helper library is under
+`sources/android/cpu-features`.
+
+$DEVNDK a.k.a $NDK/../development/ndk
+-------------------------------------
+
+This directory contains platform-specific files. The reason why it it is
+separate from $NDK is because it is not primarily developed in the open.
+
+More specifically:
+
+ * All $NDK development happens in the public AOSP repository ndk.git.
+
+ * Any $DEVNDK development that happens in the public AOSP development.git
+   repository is auto-merged to the internal tree maintained by Google.
+
+ * $DEVNDK developments that are specific to an yet-unreleased version of the
+   system happen only in the internal tree. They get back-ported to the public
+   tree only when the corresponding system release is open-sourced.
+
+$DEVNDK/platforms/android-$PLATFORM
+-----------------------------------
+
+Contains all files that are specific to a given API level `$PLATFORM`, that were
+not already defined for the previous API level.
+
+For example, android-3 corresponds to Android 1.5, and android-4 corresponds to
+Android 1.6. The platforms/android-4 directory only contains files that are
+either new or modified, compared to android-3.
+
+$DEVNDK/platforms/android-$PLATFORM/include
+-------------------------------------------
+
+Contains all system headers exposed by the NDK for a given platform. All these
+headers are independent from the CPU architecture of target devices.
+
+$DEVNDK/platforms/android-$PLATFORM/arch-$ARCH
+----------------------------------------------
+
+Contains all files that are specific to a given $PLATFORM level and a specific
+CPU architecture. $ARCH is typically 'arm' or 'x86'
+
+$DEVNDK/platforms/android-$PLATFORM/arch-$ARCH/include
+------------------------------------------------------
+
+Contains all the architecture-specific headers for a given API level.
+
+$DEVNDK/platforms/android-$PLATFORM/arch-$ARCH/lib
+--------------------------------------------------
+
+Contains several CPU-specific object files and static libraries that are
+required to build the host cross-toolchains properly.
+
+Before NDK r7, this also contains prebuilt system shared libraries that had been
+hand-picked from various platform builds. These have been replaced by symbol
+list files instead (see below).
+
+$DEVNDK/platforms/android-$PLATFORM/arch-$ARCH/symbols
+------------------------------------------------------
+
+Contains, for each system shared library exposed by the NDK, two files
+describing the dynamic symbols it exports, for example, for the C library:
+
+    libc.so.functions.txt -> list of exported function names
+    libc.so.variables.txt -> list of exported variable names
+
+These files were introduced in NDK r7 and are used to generate stub shared
+libraries that can be used by ndk-build at link time. These shared libraries
+contain the same symbols that make the NDK ABI for the given version, but do not
+function.
+
+These files can be generated from a given platform build using the
+`dev-platform-import.sh` dev-script, described later in this document.
+
+This is handy to compare which symbols were added between platform releases (and
+check that nothing disappeared).
+
+$NDK/platforms
+--------------
+
+Not to be confused with $DEVNDK/platforms/, this directory is not part of the
+NDK git directory (and is specifically listed in $NDK/.gitignore) but of its final
+installation.
+
+Its purpose is to hold the fully expanded platform-specific files. This means
+that, unlike $DEVNDK/platforms/android-$PLATFORM, the
+$NDK/platforms/android-$PLATFORM will contain _all_ the files that are specific
+to API level $PLATFORM.
+
+Moreover, the directory is organized slightly differently, i.e. as toolchain
+sysroot, i.e. for each supported $PLATFORM and $ARCH values, it provides two
+directories:
+
+    $NDK/platforms/android-$PLATFORM/arch-$ARCH/usr/include
+    $NDK/platforms/android-$PLATFORM/arch-$ARCH/usr/lib
+
+Notice the `usr` subdirectory here. It is required by GCC to be able to use the
+directories with --with-sysroot. For example, to generate binaries that target
+API level 5 for the arm architecture, one would use:
+
+    $TOOLCHAIN_PREFIX-gcc --with-sysroot=$NDK/platforms/android-5/arch-arm
+
+Where `$TOOLCHAIN_PREFIX` depends on the exact toolchain being used.
+
+The dev-script `gen-platforms.sh` is used to populate $NDK/platforms. Note that
+by default, the script does more, see its detailed description below.
+
+II. Host toolchains:
+====================
+
+The host toolchains are the compiler, linker, debugger and other crucial
+programs used to generate machine code for the target Android system supported
+by the NDK.
+
+II.1 Getting the toolchain sources:
+-----------------------------------
+
+The AOSP toolchain/ repository contains the source for the toolchains used to
+build the Android platform and in the NDK.
+
+The master-ndk branch of AOSP contains an already checked out and patched
+version of the toolchain repository at toolchain/. The old process of using
+download-toolchain-sources.sh is now obsolete.
+
+The toolchains binaries are typically placed under the directory
+$NDK/toolchains/$NAME/prebuilt, where $NAME is the toolchain name's full name
+(e.g. arm-linux-androideabi-4.8).
+
+I.2. Building the toolchains:
+-----------------------------
+
+First you will need to build a proper "sysroot" directory before being able to
+configure/build them.
+
+A sysroot is a directory containing system headers and libraries that the
+compiler will use to build a few required target-specific binaries (e.g.
+libgcc.a)
+
+To do that, use:
+
+    $NDK/build/tools/gen-platforms.sh --minimal
+
+This will populate $NDK/platforms/ with just the files necessary to rebuild the
+toolchains. Note that without the --minimal option, the script will fail without
+prebuilt toolchain binaries.
+
+Once the sysroots are in place, use `build-gcc.sh` by providing the path to the
+toolchain sources root directory, a destination NDK installation directory to
+build, and the full toolchain name.
+
+For example, to rebuild the arm and x86 prebuilt toolchain binaries in the
+current NDK directory (which can be handy if you want to later use them to
+rebuild other target prebuilts or run tests), do:
+
+    $NDK/build/tools/build-gcc.sh /tmp/ndk-$USER/src $NDK \
+        arm-linux-androideabi-4.8
+    $NDK/build/tools/build-gcc.sh /tmp/ndk-$USER/src $NDK x86-4.8
+
+Here, we assume you're using the master-ndk branch as described in the previous
+section.
+
+This operation can take some time. The script automatically performs a parallel
+build to speed up the build on multi-core machine (use the -j<number> option to
+control this), but the GCC sources are very large, so expect to wait a few
+minutes.
+
+For the record, on a 2.4 GHz Xeon with 16 Hyper-threaded cores and 12GB of
+memory, rebuilding each toolchain takes between 2 and 4 minutes.
+
+You need to be on Linux to build the Windows binaries, using the "mingw-w64"
+cross-toolchain (install it with "apt-get install mingw-w64" on Ubuntu). To do
+so use the "--mingw" option, as in:
+
+    $NDK/build/tools/build-gcc.sh --mingw \
+        /tmp/ndk-$USER/src $NDK arm-linux-androideabi-4.8
+
+    $NDK/build/tools/build-gcc.sh --mingw \
+        /tmp/ndk-$USER/src $NDK x86-4.8
+
+The corresponding binaries are installed under $NDK/toolchains/$NAME/prebuilt.
+Note that these are native Windows programs, not Cygwin ones.
+
+Building the Windows toolchains under MSys and Cygwin is completely unsupported
+and highly un-recommended: even if it works, it will probably take several
+hours, even on a powerful machine :-(
+
+The Darwin binaries must be generated on a Darwin machine. Note that the script
+will try to use the 10.5 XCode SDK if it is installed on your system. This
+ensures that the generated binaries run on Leopard, even if you're building on a
+more recent version of the system.
+
+Once you've completed your builds, you should be able to generate the other
+target-specific prebuilts.
+
+III. Target-specific prebuilt binaries:
+=======================================
+
+A final NDK installation comes with a lot of various target-specific prebuilt
+binaries that must be generated from sources once you have working host
+toolchains.
+
+III.1.: Preparation of platform sysroots:
+-----------------------------------------
+
+Each target prebuilt is handled by a specific dev-script. HOWEVER, all these
+script require that you generate a fully populated $NDK/platforms/ directory
+first. To do that, simply run:
+
+    $NDK/gen-platforms.sh
+
+Note that we used this script with the --minimal option to generate the host
+toolchains. That's because without this flag, the script will also auto-generate
+tiny versions of the system shared libraries that will be used at link-time when
+building our target prebuilts.
+
+III.2.: Generation of gdbserver:
+---------------------------------
+
+A target-specific `gdbserver` binary is required. This is a small program that
+is run on the device through `ndk-gdb` during debugging. For a variety of
+technical reasons, it must be copied into a debuggable project's output
+directory when `ndk-build` is called.
+
+The prebuilt binary is placed under $NDK/gdbserver/$ARCH in the final NDK
+installation. You can generate them with `build-gdbserver.py`.
+
+
+III.3. Generating C++ runtime prebuilt binaries:
+-----------------------------------------------
+
+Sources and support files for several C++ runtimes / standard libraries are
+provided under $NDK/sources/cxx-stl/. Several dev-scripts are provided to
+rebuild their binaries. The scripts place them to their respective location
+(e.g. the libc++ binaries will go to $NDK/sources/cxx-stl/llvm-libc++/libs/)
+unless you use the --out-dir=<path> option.
+
+Note that:
+
+ * Each script will generate the binaries for all the CPU ABIs supported by the
+   NDK, e.g. armeabi, armeabi-v7a, x86 and mips. You can restrict them using the
+   --abis=<list> option though.
+
+ - The GNU libstdc++ dev-script requires the path to the toolchain sources,
+   since this is where the library's sources are located.
+
+An example usage would be:
+
+    $NDK/build/tools/build-cxx-stl.sh --stl=stlport
+    $NDK/build/tools/build-cxx-stl.sh --stl=libc++
+    $NDK/build/tools/build-gnu-libstdc++.sh /tmp/ndk-$USER/src
+
+Note that generating the STLport and GNU libstdc++ binaries can take a few
+minutes. You can follow the build by using the --verbose option to display
+what's going on.
+
+IV. Other host prebuilt binaries:
+=================================
+
+There are a few other host prebuilt binaries that are needed for a full NDK
+installation. Their sources are typically installed under
+$NDK/sources/host-tools/
+
+Note that the corresponding dev-script recognize the --mingw and --try-64
+options described at the end of section I above.
+
+IV.1.: Building `ndk-stack`:
+---------------------------
+
+The `build-ndk-stack.sh` script can be used to rebuild the `ndk-stack` helper
+host program. See docs/NDK-STACK.html for a usage description.  To build it,
+just do:
+
+    $NDK/build/tools/build-ndk-stack.sh
+
+IV.2.: Building `ndk-depends`:
+-----------------------------
+
+Similar to `ndk-stack`, see the `build-ndk-depends.sh` script.
+
+V. Packaging all prebuilts:
+===========================
+
+Generating all the prebuilt binaries takes a lot of time and is no fun.  To
+avoid doing it again and again, it is useful to place all the generated files
+aside in special tarballs.
+
+Most dev-scripts generating them typically support a --package-dir=<path> option
+to do this, where <path> points to a directory that will store compressed
+tarballs of the generated binaries.
+
+For example, to build and package the libc++ binaries, use:
+
+    $NDK/build/tools/build-cxx-stl.sh --stl=libc++ \
+        --package-dir=/tmp/ndk-$USER/prebuilt/
+
+This will actually create one tarball per supported ABI in
+`$ANDROID_BUILD_TOP/out/ndk`, i.e.:
+
+ * libcxx-libs-armeabi.tar.bz2
+ * libcxx-libs-armeabi-v7a.tar.bz2
+ * libcxx-libs-x86.tar.bz2
+ * ...
+
+Note that these tarballs are built to be uncompressed from the top-level of an
+existing NDK install tree.
+
+Similarly, to rebuild the STLport binaries and package them:
+
+    $NDK/build/tools/build-cxx-stl.sh --stl=stlport \
+        --package-dir=/tmp/ndk-$USER/prebuilt
+
+The `rebuilt-all-prebuilt.sh` script has been entirely replaced by checkbuild.py
+in the root of the NDK.  Note that by default, it will automatically place the
+prebuilt tarballs under `$ANDROID_BUILD_TOP/out/ndk`.
+
+By default, this only rebuilds the host prebuilts for the current host system.
+You can use `--system windows` or `--system windows64` to build Windows binaries
+on Linux.
+
+Once you have used the script three times (once per supported host systems), you
+should have plenty of files under /tmp/ndk-$USER/prebuilt-$DATE.  For the
+record, with NDK r7, the list was:
+
+VI. Packaging NDK releases:
+===========================
+
+Use the `package-release.sh` dev-script to generate full NDK release packages.
+These contain everything needed by a typical NDK user, including:
+
+ * All prebuilt binaries (host toolchains, host tools, target libs, etc...).
+ * All documentation.
+
+You need to have a directory containing prebuilt tarballs, as described in the
+previous section. You can use it as:
+
+    $NDK/build/tools/package-release.sh \
+        --release=<name> \
+        --systems=<list> \
+        --arch=<list> \
+        --prebuilt-dir=<path>
+
+The --release option is optional and allows you to provide a name for your
+generated NDK archive. More specifically, the archive file name will be
+something like android-ndk-$RELEASE-$SYSTEM.tar.bz2, where $RELEASE is the
+release name, and $SYSTEM the supported host system (e.g. linux-x86).
+
+By default, i.e. without the option, $RELEASE will be set to the current $DATE.
+
+The --systems=<list> is optional, but can be used to limit the number of host
+systems you want to generate for. <list> must be a comma-separated list of
+system names (from `linux-x86`, `windows` and `darwin-x86`). This is useful if
+you're working on a experimental feature and don't have the time to regenerate
+the host toolchains for all systems. It allows you to generate an experimental
+package that you can distribute to third-party for experimentation.
+
+By default, i.e. without the option, the scripts tries to build NDK archives for
+all supported host systems.
+
+The --arch=<list> is also optional, but can be used to limit the number of
+target architectures you want to generate for. <list> must be a comma-separated
+list of CPU architectures (e.g. from `arm` and `x86`). Without the option, this
+will try to build packages that support all architectures.
+
+Finally, --prebuilt-dir=<path> must point to the directory that contains the
+prebuilt tarballs described in section V. Following our previous example, one
+could use --prebuilt-dir=/tmp/ndk-$USER/prebuilt here.
+
+VI. Testing:
+============
+
+The $NDK/tests directory contains a number of NDK unit-tests that can be used to
+verify that the generated NDK packages or the working NDK tree still behave
+correctly.
+
+If you have an NDK package archive, you can run the following to run the test
+suite against it:
+
+    $NDK/tests/run-tests.sh --package=<ndk-archive>
+
+This will uncompress the NDK archive in a temporary directory, then run all the
+tests with it. When all tests have run, the temporary directory is removed
+automatically.
+
+You can also point to an existing NDK installation with --ndk=<path>, as in:
+
+    $NDK/tests/run-tests.sh --ndk=<path>
+
+Where <path> points to another NDK installation. The script will run the test
+suite present under $NDK/tests/, not the one in the remote NDK directory.
+
+If you don't use any option, the test suite will be run with the current NDK
+directory. This can only work if you have generated or unpacked all prebuilt
+archives into it before that.
+
+You can get more traces from the tests by using --verbose. Use it twice to see
+even more traces.
+
+There are several kinds of tests:
+
+ * 'build tests' are used to test the building capabilities of the NDK.
+   I.e. the tests will only use them to check that the NDK build system
+   didn't regress. The corresponding generated binaries are never used
+   otherwise.
+
+ * 'device tests' are used to test both the build and the behaviour of
+   the generated code. If the `adb` program is in your path, and have
+   one device or emulator connected to your host machine, `run-tests.sh`
+   will automatically upload, run and cleanup these tests for you.
+
+   If adb is not in your path, or no device is connected, run-tests.sh
+   will simply print a warning and carry on.
+
+
+Whenever you add a feature to the NDK, or fix a bug, it is recommended to add a
+unit test to check the feature or the fix. Use $NDK/tests/build for build tests,
+and $NDK/tests/device for device tests.
diff --git a/build/tools/build-cxx-stl.sh b/build/tools/build-cxx-stl.sh
new file mode 100755
index 0000000..4f1a935
--- /dev/null
+++ b/build/tools/build-cxx-stl.sh
@@ -0,0 +1,668 @@
+#!/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=
+OPTION_BUILD_DIR=
+register_var_option "--build-dir=<path>" OPTION_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
+
+if [ -z "$OPTION_BUILD_DIR" ]; then
+    BUILD_DIR=$NDK_TMPDIR/build-$CXX_STL
+else
+    BUILD_DIR=$OPTION_BUILD_DIR
+fi
+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 \