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. The GMSL is released under the BSD License.<br>
+<br>
+<a href="http://sourceforge.net/projects/gmsl/">[Project Page]</a> <a href="http://sourceforge.net/project/showfiles.php?group_id=129887">[Download]</a>
+<a href="http://sourceforge.net/forum/forum.php?forum_id=443916">[Discussion
+Forum]</a><br>
+<h2>Using GMSL</h2>
+The two files needed are <span style="font-family: monospace;">gmsl</span>
+and <span style="font-family: monospace;">__gmsl</span>. To
+include the GMSL in your Makefile do<br>
+<pre style="margin-left: 40px;">include gmsl</pre>
+<span style="font-family: monospace;">gmsl</span> automatically includes<span style="font-family: monospace;"> __gmsl</span>. To check that
+you have the right version of <span style="font-family: monospace;">gmsl</span>
+use the <span style="font-family: monospace;">gmsl_compatible</span>
+function (see
+below). The current version is <span style="font-family: monospace;">1
+0 11</span>.<br>
+<br>
+The GMSL package also includes a test suite for GMSL. Just run <span style="font-family: monospace;">make -f gmsl-tests</span>.<br>
+<h2>Logical Operators</h2>GMSL has boolean $(true) (a non-empty string)
+and $(false) (an empty string). The following operators can be
+used with those variables.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><span style="font-weight: bold;">not</span><br>
+
+<br>
+
+<span style="font-family: monospace;">Arguments: A boolean value</span><br style="font-family: monospace;">
+
+<span style="font-family: monospace;">Returns: Returns $(true) if the boolean is $(false) and vice versa</span><br style="font-family: monospace;">
+
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;"></span><span style="font-weight: bold;">and</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns: Returns $(true) if both of the booleans are true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">or</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns: Returns $(true) if either of the booleans is true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xor</span><br style="font-weight: bold;">
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns: Returns $(true) if exactly one of the booleans is true</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nand</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns: Returns value of 'not and'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">nor</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns: Returns value of 'not or'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;"><span style="font-weight: bold;">xnor</span><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two boolean values</span><br style="font-family: monospace;">
+<span style="font-family: monospace;">Returns: Returns value of 'not xor'</span><br style="font-family: monospace;">
+<hr style="width: 100%; height: 2px; font-family: monospace;">
+<h2>List Manipulation Functions</h2>
+ A list is a string of characters; the list separator is a space.<br>
+
+<br>
+<hr style="width: 100%; height: 2px;"><b>first</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns: Returns the first element of a list<br>
+</span>
+<hr><b>last</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns: Returns the last element of a list<br>
+</span>
+<hr><b>rest</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns: Returns the list with the first element
+removed<br>
+</span>
+<hr><b>chop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns: Returns the list with the last element removed<br>
+</span>
+<hr><b>map</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of function to
+$(call) for each element of list<br>
+ 2: List to
+iterate over calling the function in 1<br>
+Returns: The list after calling the function on each
+element<br>
+</span>
+<hr><b>pairmap</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of function to
+$(call) for each pair of elements<br>
+ 2: List to
+iterate over calling the function in 1<br>
+ 3: Second
+list to iterate over calling the function in 1<br>
+Returns: The list after calling the function on each
+pair of elements<br>
+</span>
+<hr><b>leq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to compare
+against...<br>
+ 2: ...this
+list<br>
+Returns: Returns $(true) if the two lists are identical<br>
+</span>
+<hr><b>lne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to compare
+against...<br>
+ 2: ...this
+list<br>
+Returns: Returns $(true) if the two lists are different<br>
+</span>
+<hr><b>reverse</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to reverse<br>
+Returns: The list with its elements in reverse order<br>
+</span>
+<hr><b>uniq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list to deduplicate<br>
+Returns: The list with elements in order without duplicates<br>
+</span>
+<hr><b>length</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list<br>
+Returns: The number of elements in the list<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>String Manipulation Functions</h2>
+A string is any sequence of characters.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>seq</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string to compare
+against...<br>
+ 2: ...this
+string<br>
+Returns: Returns $(true) if the two strings are
+identical<br>
+</span>
+<hr><b>sne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string to compare
+against...<br>
+ 2: ...this
+string<br>
+Returns: Returns $(true) if the two strings are not
+the same<br>
+</span>
+<hr><b>strlen</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+Returns: Returns the length of the string<br>
+</span>
+<hr><b>substr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A string<br>
+ 2: Start offset (first character is 1)<br>
+ 3: Ending offset (inclusive)<br>Returns: Returns a substring<br>
+</span>
+<hr><b>split</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+split on<br>
+ 2: A
+string to split<br>
+Returns: Splits a string into a list separated by
+spaces at the split<br>
+ character
+in the first argument<br>
+</span>
+<hr><b>merge</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The character to
+put between fields<br>
+ 2: A list
+to merge into a string<br>
+Returns: Merges a list into a single string, list
+elements are separated<br>
+ by the
+character in the first argument<br>
+</span>
+<hr><b>tr</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: The list of
+characters to translate from <br>
+ 2: The
+list of characters to translate to<br>
+ 3: The
+text to translate<br>
+Returns: Returns the text after translating characters<br>
+</span>
+<hr><b>uc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Text to upper case<br>
+Returns: Returns the text in upper case<br>
+</span>
+<hr><b>lc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Text to lower case<br>
+Returns: Returns the text in lower case<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Set Manipulation Functions</h2>
+Sets are represented by sorted, deduplicated lists. To create a set
+from a list use <span style="font-family:
+monospace;">set_create</span>, or start with the <span
+style="font-family: monospace;">empty_set</span> and <span
+style="font-family: monospace;">set_insert</span> individual elements.
+The empty set is defined as <span style="font-family:
+monospace;">empty_set</span>.<p>
+
+<hr><b>set_create</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A list of set elements<br>
+Returns: Returns the newly created set<br>
+</span>
+
+<hr><b>set_insert</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element to add to a set<br>
+ 2: A set<br>
+Returns: Returns the set with the element added<br>
+</span>
+
+<hr><b>set_remove</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element to remove from a set<br>
+ 2: A set<br>
+Returns: Returns the set with the element removed<br>
+</span>
+
+<hr><b>set_is_member</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A single element<br>
+ 2: A set<br>
+Returns: Returns $(true) if the element is in the set<br>
+</span>
+
+<hr><b>set_union</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+ 2: Another set<br>
+Returns: Returns the union of the two sets<br>
+</span>
+
+<hr><b>set_intersection</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+ 2: Another set<br>
+Returns: Returns the intersection of the two sets<br>
+</span>
+
+<hr><b>set_is_subset</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+ 2: Another set<br>
+Returns: Returns $(true) if the first set is a subset of the second<br>
+</span>
+
+<hr><b>set_equal</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A set<br>
+ 2: Another set<br>
+Returns: Returns $(true) if the two sets are identical<br>
+</span>
+
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Integer Arithmetic Functions</h2>
+Integers are represented by lists with the equivalent number of
+x's. For example the number 4 is x x x x. The maximum
+integer that the library can handle as <span style="font-style: italic;">input</span> (i.e. as the argument to a
+call to <span style="font-family: monospace;">int_encode</span>) is
+65536. There is no limit on integer size for internal computations or
+output.<br>
+<br>
+The arithmetic library functions come in two forms: one form of each
+function takes integers as arguments and the other form takes the
+encoded form (x's created by a call to <span style="font-family: monospace;">int_encode</span>). For example,
+there are two plus functions: <span style="font-family: monospace;">plus</span>
+(called with integer arguments and returns an integer) and <span style="font-family: monospace;">int_plus</span> (called with encoded
+arguments and returns an encoded result).<br>
+<br>
+<span style="font-family: monospace;">plus</span> will be slower than <span style="font-family: monospace;">int_plus</span> because its arguments
+and result have to be translated between the x's format and
+integers. If doing a complex calculation use the <span style="font-family: monospace;">int_*</span> forms with a single
+encoding of inputs and single decoding of the output. For simple
+calculations the direct forms can be used.<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>int_decode</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number of x's
+representation<br>
+Returns: Returns the integer for human consumption
+that is represented<br>
+ by the
+string of x's<br>
+</span>
+<hr><b>int_encode</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in
+human-readable integer form<br>
+Returns: Returns the integer encoded as a string of x's<br>
+</span>
+<hr><b>int_plus</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+ 2: Another
+number in x's represntation<br>
+Returns: Returns the sum of the two numbers in x's
+representation<br>
+</span>
+<hr><b>plus (wrapped version of int_plus)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+ 2: Another
+integer<br>
+Returns: Returns the sum of the two integers<br>
+</span>
+<hr><b>int_subtract</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+ 2: Another
+number in x's represntation<br>
+Returns: Returns the difference of the two numbers in
+x's representation,<br>
+ or outputs
+an error on a numeric underflow<br>
+</span>
+<hr><b>subtract (wrapped version of int_subtract)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+ 2: Another
+integer<br>
+Returns: Returns the difference of the two integers,<br>
+ or outputs
+an error on a numeric underflow<br>
+</span>
+<hr><b>int_multiply</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+ 2: Another
+number in x's represntation<br>
+Returns: Returns the product of the two numbers in x's
+representation<br>
+</span>
+<hr><b>multiply (wrapped version of int_multiply)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+ 2: Another
+integer<br>
+Returns: Returns the product of the two integers<br>
+</span>
+<hr><b>int_divide</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+ 2: Another
+number in x's represntation<br>
+Returns: Returns the result of integer division of
+argument 1 divided<br>
+ by
+argument 2 in x's representation<br>
+</span>
+<hr><b>divide (wrapped version of int_divide)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+ 2: Another
+integer<br>
+Returns: Returns the integer division of the first
+argument by the second<br>
+</span>
+<hr><b>int_max, int_min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+ 2: Another
+number in x's represntation<br>
+Returns: Returns the maximum or minimum of its
+arguments in x's<br>
+
+representation<br>
+</span>
+<hr><b>max, min</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+ 2: Another
+integer<br>
+Returns: Returns the maximum or minimum of its integer
+arguments<br>
+</span>
+<hr><b>int_gt, int_gte, int_lt, int_lte, int_eq, int_ne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two x's representation
+numbers to be compared<br>
+Returns: $(true) or $(false)<br>
+<br>
+int_gt First argument greater than second argument<br>
+int_gte First argument greater than or equal to second argument<br>
+int_lt First argument less than second argument <br>
+int_lte First argument less than or equal to second argument<br>
+int_eq First argument is numerically equal to the second argument<br>
+int_ne First argument is not numerically equal to the second argument<br>
+</span>
+<hr><b>gt, gte, lt, lte, eq, ne</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: Two integers to be
+compared<br>
+Returns: $(true) or $(false)<br>
+<br>
+gt First argument greater than second argument<br>
+gte First argument greater than or equal to second argument<br>
+lt First argument less than second argument <br>
+lte First argument less than or equal to second argument<br>
+eq First argument is numerically equal to the second argument<br>
+ne First argument is not numerically equal to the second argument<br>
+</span>
+increment adds 1 to its argument, decrement subtracts 1. Note that<br>
+decrement does not range check and hence will not underflow, but<br>
+will incorrectly say that 0 - 1 = 0<br>
+<hr><b>int_inc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns: The number incremented by 1 in x's
+representation<br>
+</span>
+<hr><b>inc</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns: The argument incremented by 1<br>
+</span>
+<hr><b>int_dec</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns: The number decremented by 1 in x's
+representation<br>
+</span>
+<hr><b>dec</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns: The argument decremented by 1<br>
+</span>
+<hr><b>int_double</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns: The number doubled (i.e. * 2) and returned in
+x's representation<br>
+</span>
+<hr><b>double</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns: The integer times 2<br>
+</span>
+<hr><b>int_halve</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A number in x's
+representation<br>
+Returns: The number halved (i.e. / 2) and returned in
+x's representation<br>
+</span>
+<hr><b>halve</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: An integer<br>
+Returns: The integer divided by 2<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Associative Arrays</h2>
+An associate array maps a key value (a string with no spaces in it) to
+a single value (any string). <br>
+<b><br>
+</b>
+<hr style="width: 100%; height: 2px;"><b>set</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+ 2: The key
+value to associate<br>
+ 3: The
+value associated with the key<br>
+Returns: None<br>
+</span>
+<hr><b>get</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+ 2: The key
+to retrieve<br>
+Returns: The value stored in the array for that key<br>
+</span>
+<hr><b>keys</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+Returns: Returns a list of all defined keys in the
+array<br>
+</span>
+<hr><b>defined</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of associative
+array<br>
+ 2: The key
+to test<br>
+Returns: Returns true if the key is defined (i.e. not
+empty)<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Named Stacks</h2>
+A stack is an ordered list of strings (with no spaces in them).<br>
+<br>
+<hr style="width: 100%; height: 2px;"><b>push</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+ 2: Value
+to push onto the top of the stack (must not contain<br>
+ a space)<br>
+Returns: None<br>
+</span>
+<hr><b>pop</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns: Top element from the stack after removing it<br>
+</span>
+<hr><b>peek</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns: Top element from the stack without removing it<br>
+</span>
+<hr><b>depth</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of stack<br>
+Returns: Number of items on the stack<br>
+</span>
+<hr style="width: 100%; height: 2px;"><span style="font-family: monospace;"></span>
+<h2>Miscellaneous and Debugging Facilities</h2>
+GMSL defines the following constants; all are accessed as normal GNU
+Make variables by wrapping them in <span style="font-family: monospace;">$()</span> or <span style="font-family: monospace;">${}</span>.<br>
+<br>
+<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
+ <tbody>
+ <tr>
+ <td><span style="font-style: italic;">Constant</span><br>
+ </td>
+ <td><span style="font-style: italic;">Value</span><br>
+ </td>
+ <td><span style="font-style: italic;">Purpose</span><br>
+ </td>
+ </tr>
+ <tr>
+ <td><span style="font-family: monospace;">true</span><br>
+ </td>
+ <td><span style="font-family: monospace;">T</span><br>
+ </td>
+ <td>Boolean for <span style="font-family: monospace;">$(if)</span>
+and return from GMSL functions<br>
+ </td>
+ </tr>
+ <tr>
+ <td><span style="font-family: monospace;">false</span><br>
+ </td>
+ <td><br>
+ </td>
+ <td>Boolean for <span style="font-family: monospace;">$(if)</span>
+and return from GMSL functions<br>
+ </td>
+ </tr>
+ <tr>
+ <td><span style="font-family: monospace;">gmsl_version</span><br>
+ </td>
+ <td><span style="font-family: monospace;">1 0 0</span><br>
+ </td>
+ <td>GMSL version number as list: major minor revision<br>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<span style="font-weight: bold;"><br>
+gmsl_compatible</span><span style="font-family: monospace;"><br>
+<br>
+Arguments: List containing the desired library version number (maj min
+rev)<br>
+</span><span style="font-family: monospace;">Returns:
+$(true) if this version of the library is compatible<br>
+</span><span style="font-family: monospace;">
+with the requested version number, otherwise $(false)</span>
+<hr><b>gmsl-print-% (target not a function)</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: The % should be
+replaced by the name of a variable that you<br>
+ wish to
+print out.<br>
+Action: Echos the name of the variable that matches
+the % and its value.<br>
+ For
+example, 'make gmsl-print-SHELL' will output the value of<br>
+ the SHELL
+variable<br>
+</span>
+<hr><b>assert</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: A boolean that must
+be true or the assertion will fail<br>
+ 2: The
+message to print with the assertion<br>
+Returns: None<br>
+</span>
+<hr><b>assert_exists</b><br>
+<br>
+<span style="font-family: monospace;">Arguments: 1: Name of file that
+must exist, if it is missing an assertion<br>
+ will be
+generated<br>
+Returns: None<br>
+</span>
+<hr style="width: 100%; height: 2px;"><br>
+GMSL has a number of environment variables (or command-line overrides)
+that control various bits of functionality:<br>
+<br>
+<table style="text-align: left;" border="1" cellpadding="2" cellspacing="2">
+ <tbody>
+ <tr>
+ <td><span style="font-style: italic;">Variable</span><br>
+ </td>
+ <td><span style="font-style: italic;">Purpose</span><br>
+ </td>
+ </tr>
+ <tr>
+ <td><span style="font-family: monospace;">GMSL_NO_WARNINGS</span><br>
+ </td>
+ <td>If set prevents GMSL from outputting warning messages:
+artithmetic functions generate underflow warnings.<br>
+ </td>
+ </tr>
+ <tr>
+ <td><span style="font-family: monospace;">GMSL_NO_ERRORS</span><br>
+ </td>
+ <td>If set prevents GMSL from generating fatal errors: division
+by zero or failed assertions are fatal.<br>
+ </td>
+ </tr>
+ <tr>
+ <td><span style="font-family: monospace;">GMSL_TRACE</span><br>
+ </td>
+ <td>Enables function tracing. Calls to GMSL functions will
+result in name and arguments being traced.<br>
+ </td>
+ </tr>
+ </tbody>
+</table>
+<span style="font-family: monospace;"></span><br>
+<hr>
+Copyright (c) 2005-2006 <a href="http://www.jgc.org/">John Graham-Cumming</a>.<br>
+<hr style="width: 100%; height: 2px;">
+<table style="width: 100%; text-align: left;" border="0" cellpadding="2" cellspacing="2">
+ <tbody>
+ <tr>
+ <td style="width: 50%;">John Graham-Cumming's work on this
+project was sponsored by <a href="http://www.electric-cloud.com/">Electric
+Cloud, Inc</a>.<br>
+ <a href="http://www.electric-cloud.com/"><img alt="" src="http://gmsl.sf.net/ec_logo.gif" style="border: 0px solid ; width: 223px; height: 47px;"></a><br>
+ </td>
+ <td align="right">
+ <p><a href="http://sourceforge.net/"><img src="http://sourceforge.net/sflogo.php?group_id=129887&type=1" alt="SourceForge.net Logo" border="0" height="31" width="88"></a></p>
+ </td>
+ </tr>
+ </tbody>
+</table>
+</body></html>
diff --git a/build/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 \
+libcxx/src/rand