Merge "Also install STLs to thumb paths."
diff --git a/build/tools/make_standalone_toolchain.py b/build/tools/make_standalone_toolchain.py
index ae20dbc..3e398a8 100755
--- a/build/tools/make_standalone_toolchain.py
+++ b/build/tools/make_standalone_toolchain.py
@@ -327,10 +327,12 @@
     return dst_libdir
 
 
-def copy_gnustl_libs(src_dir, dst_dir, triple, abi):
+def copy_gnustl_libs(src_dir, dst_dir, triple, abi, thumb=False):
     """Copy the gnustl libraries to the toolchain."""
     src_libdir = get_src_libdir(src_dir, abi)
     dst_libdir = get_dest_libdir(dst_dir, triple, abi)
+    if thumb:
+        dst_libdir = os.path.join(dst_libdir, 'thumb')
 
     logger().debug('Copying %s libs to %s', abi, dst_libdir)
 
@@ -347,10 +349,12 @@
                  os.path.join(dst_libdir, 'libstdc++.a'))
 
 
-def copy_stlport_libs(src_dir, dst_dir, triple, abi):
+def copy_stlport_libs(src_dir, dst_dir, triple, abi, thumb=False):
     """Copy the stlport libraries to the toolchain."""
     src_libdir = get_src_libdir(src_dir, abi)
     dst_libdir = get_dest_libdir(dst_dir, triple, abi)
+    if thumb:
+        dst_libdir = os.path.join(dst_libdir, 'thumb')
 
     if not os.path.exists(dst_libdir):
         os.makedirs(dst_libdir)
@@ -360,6 +364,36 @@
                  os.path.join(dst_libdir, 'libstdc++.a'))
 
 
+def copy_libcxx_libs(src_dir, dst_dir, include_libunwind):
+    shutil.copy2(os.path.join(src_dir, 'libc++_shared.so'), dst_dir)
+    shutil.copy2(os.path.join(src_dir, 'libc++_static.a'), dst_dir)
+    shutil.copy2(os.path.join(src_dir, 'libandroid_support.a'), dst_dir)
+    shutil.copy2(os.path.join(src_dir, 'libc++abi.a'), dst_dir)
+
+    if include_libunwind:
+        shutil.copy2(os.path.join(src_dir, 'libunwind.a'), dst_dir)
+
+    # libc++ is different from the other STLs. It has a libc++.(a|so) that is a
+    # linker script which automatically pulls in the necessary libraries. This
+    # way users don't have to do `-lc++abi -lunwind -landroid_support` on their
+    # own.
+    #
+    # As with the other STLs, we still copy this as libstdc++.a so the compiler
+    # will pick it up by default.
+    #
+    # Unlike the other STLs, also copy libc++.so (another linker script) over
+    # as libstdc++.so.  Since it's a linker script, the linker will still get
+    # the right DT_NEEDED from the SONAME of the actual linked object.
+    #
+    # TODO(danalbert): We should add linker scripts for the other STLs too
+    # since it lets the user avoid the current mess of having to always
+    # manually add `-lstlport_shared` (or whichever STL).
+    shutil.copy2(os.path.join(src_dir, 'libc++.a'),
+                 os.path.join(dst_dir, 'libstdc++.a'))
+    shutil.copy2(os.path.join(src_dir, 'libc++.so'),
+                 os.path.join(dst_dir, 'libstdc++.so'))
+
+
 def create_toolchain(install_path, arch, api, gcc_path, clang_path,
                      sysroot_path, stl, host_tag):
     """Create a standalone toolchain."""
@@ -418,6 +452,8 @@
             if arch == 'arm':
                 copy_gnustl_abi_headers(gnustl_dir, install_path, gcc_ver,
                                         triple, abi, thumb=True)
+                copy_gnustl_libs(gnustl_dir, install_path, triple, abi,
+                                 thumb=True)
     elif stl == 'libc++':
         libcxx_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/llvm-libc++')
         libcxxabi_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/llvm-libc++abi')
@@ -444,38 +480,11 @@
         for abi in get_abis(arch):
             src_libdir = get_src_libdir(libcxx_dir, abi)
             dest_libdir = get_dest_libdir(install_path, triple, abi)
-            shutil.copy2(os.path.join(src_libdir, 'libc++_shared.so'),
-                         dest_libdir)
-            shutil.copy2(os.path.join(src_libdir, 'libc++_static.a'),
-                         dest_libdir)
-            shutil.copy2(os.path.join(src_libdir, 'libandroid_support.a'),
-                         dest_libdir)
-            shutil.copy2(os.path.join(src_libdir, 'libc++abi.a'), dest_libdir)
-
+            include_libunwind = arch == 'arm'
+            copy_libcxx_libs(src_libdir, dest_libdir, include_libunwind)
             if arch == 'arm':
-                shutil.copy2(os.path.join(src_libdir, 'libunwind.a'),
-                             dest_libdir)
-
-            # libc++ is different from the other STLs. It has a libc++.(a|so)
-            # that is a linker script which automatically pulls in the
-            # necessary libraries. This way users don't have to do
-            # `-lc++abi -lunwind -landroid_support` on their own.
-            #
-            # As with the other STLs, we still copy this as libstdc++.a so the
-            # compiler will pick it up by default.
-            #
-            # Unlike the other STLs, also copy libc++.so (another linker
-            # script) over as libstdc++.so.  Since it's a linker script, the
-            # linker will still get the right DT_NEEDED from the SONAME of the
-            # actual linked object.
-            #
-            # TODO(danalbert): We should add linker scripts for the other STLs
-            # too since it lets the user avoid the current mess of having to
-            # always manually add `-lstlport_shared` (or whichever STL).
-            shutil.copy2(os.path.join(src_libdir, 'libc++.a'),
-                         os.path.join(dest_libdir, 'libstdc++.a'))
-            shutil.copy2(os.path.join(src_libdir, 'libc++.so'),
-                         os.path.join(dest_libdir, 'libstdc++.so'))
+                thumb_libdir = os.path.join(dest_libdir, 'thumb')
+                copy_libcxx_libs(src_libdir, thumb_libdir, include_libunwind)
     elif stl == 'stlport':
         stlport_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/stlport')
         gabixx_dir = os.path.join(NDK_DIR, 'sources/cxx-stl/gabi++')
@@ -504,7 +513,8 @@
         for abi in get_abis(arch):
             copy_stlport_libs(stlport_dir, install_path, triple, abi)
             if arch == 'arm':
-                copy_stlport_libs(stlport_dir, install_path, triple, abi)
+                copy_stlport_libs(stlport_dir, install_path, triple, abi,
+                                  thumb=True)
     else:
         raise ValueError(stl)
 
diff --git a/ndk/testing/standalone_toolchain.py b/ndk/testing/standalone_toolchain.py
index 9aa1c1f..25a02df 100644
--- a/ndk/testing/standalone_toolchain.py
+++ b/ndk/testing/standalone_toolchain.py
@@ -61,7 +61,8 @@
     return rc == 0, out
 
 
-def test_standalone_toolchain(arch, toolchain, install_dir, test_source):
+def test_standalone_toolchain(arch, toolchain, install_dir, test_source,
+                              flags):
     if toolchain == '4.9':
         triple = build.lib.build_support.arch_to_triple(arch)
         # x86 toolchain names are dumb: http://b/25800583
@@ -73,6 +74,7 @@
 
     compiler = os.path.join(install_dir, 'bin', compiler_name)
     cmd = [compiler, test_source, '-Wl,--no-undefined', '-Wl,--fatal-warnings']
+    cmd += flags
     if os.name == 'nt':
         # The Windows equivalent of exec doesn't know file associations so it
         # tries to load the batch file as an executable. Invoke it with cmd.
@@ -81,7 +83,7 @@
     return rc == 0, out
 
 
-def run_test(abi, api, toolchain, test_source, extra_args):
+def run_test(abi, api, toolchain, test_source, extra_args, flags):
     arch = build.lib.build_support.abi_to_arch(abi)
 
     install_dir = tempfile.mkdtemp()
@@ -91,6 +93,6 @@
         if not success:
             return success, out
         return test_standalone_toolchain(
-            arch, toolchain, install_dir, test_source)
+            arch, toolchain, install_dir, test_source, flags)
     finally:
         shutil.rmtree(install_dir)
diff --git a/tests/build/standalone_toolchain/foo.cpp b/tests/build/standalone_toolchain/foo.cpp
index 256218b..fb7b6c7 100644
--- a/tests/build/standalone_toolchain/foo.cpp
+++ b/tests/build/standalone_toolchain/foo.cpp
@@ -1,16 +1,20 @@
-#include <stdio.h>
-
 // Make sure we're not clobbering libc++ headers with libandroid_support.
 #include <cmath>
 
+// Use iostream instead of stdio.h to make sure we can actually get symbols from
+// libc++.so. Most of libc++ is defined in the headers, but std::cout is in the
+// library.
+#include <iostream>
+
 // If std::strings don't work then there's really no point :)
 #include <string>
 
 void foo(const std::string& s) {
-  // Using new makes sure we get libc++abi/libsupc++, using std::string makes
-  // sure the STL works at all.
+  // Using new makes sure we get libc++abi/libsupc++. Using std::string makes
+  // sure the STL works at all. Using std::cout makes sure we can access the
+  // library itself and not just the headers.
   std::string* copy = new std::string(s);
-  printf("%s\n", copy->c_str());
+  std::cout << copy << std::endl;
   delete copy;
 }
 
diff --git a/tests/build/standalone_toolchain/test.py b/tests/build/standalone_toolchain/test.py
index f7a43b2..3eaf34b 100644
--- a/tests/build/standalone_toolchain/test.py
+++ b/tests/build/standalone_toolchain/test.py
@@ -18,4 +18,4 @@
 
 def run_test(abi, api, toolchain, _build_flags):
     return ndk.testing.standalone_toolchain.run_test(
-        abi, api, toolchain, 'foo.cpp', ['--stl=libc++'])
+        abi, api, toolchain, 'foo.cpp', ['--stl=libc++'], [])
diff --git a/tests/build/standalone_toolchain_gnustl/test.py b/tests/build/standalone_toolchain_gnustl/test.py
index 6084dd0..6a5c0fd 100644
--- a/tests/build/standalone_toolchain_gnustl/test.py
+++ b/tests/build/standalone_toolchain_gnustl/test.py
@@ -18,4 +18,4 @@
 
 def run_test(abi, api, toolchain, _build_flags):
     return ndk.testing.standalone_toolchain.run_test(
-        abi, api, toolchain, 'foo.cpp', ['--stl=gnustl'])
+        abi, api, toolchain, 'foo.cpp', ['--stl=gnustl'], [])
diff --git a/tests/build/standalone_toolchain_gnustl_thumb/__init__.py b/tests/build/standalone_toolchain_gnustl_thumb/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/build/standalone_toolchain_gnustl_thumb/__init__.py
diff --git a/tests/build/standalone_toolchain_gnustl_thumb/foo.cpp b/tests/build/standalone_toolchain_gnustl_thumb/foo.cpp
new file mode 100644
index 0000000..fb7b6c7
--- /dev/null
+++ b/tests/build/standalone_toolchain_gnustl_thumb/foo.cpp
@@ -0,0 +1,23 @@
+// Make sure we're not clobbering libc++ headers with libandroid_support.
+#include <cmath>
+
+// Use iostream instead of stdio.h to make sure we can actually get symbols from
+// libc++.so. Most of libc++ is defined in the headers, but std::cout is in the
+// library.
+#include <iostream>
+
+// If std::strings don't work then there's really no point :)
+#include <string>
+
+void foo(const std::string& s) {
+  // Using new makes sure we get libc++abi/libsupc++. Using std::string makes
+  // sure the STL works at all. Using std::cout makes sure we can access the
+  // library itself and not just the headers.
+  std::string* copy = new std::string(s);
+  std::cout << copy << std::endl;
+  delete copy;
+}
+
+int main(int, char**) {
+  foo("Hello, world!");
+}
diff --git a/tests/build/standalone_toolchain_gnustl_thumb/test.py b/tests/build/standalone_toolchain_gnustl_thumb/test.py
new file mode 100644
index 0000000..73f231e
--- /dev/null
+++ b/tests/build/standalone_toolchain_gnustl_thumb/test.py
@@ -0,0 +1,22 @@
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import ndk.testing.standalone_toolchain
+
+
+def run_test(abi, api, toolchain, _build_flags):
+    return ndk.testing.standalone_toolchain.run_test(
+        abi, api, toolchain, 'foo.cpp', ['--stl=gnustl'],
+        ['-mthumb', '-lgnustl_shared'])
diff --git a/tests/build/standalone_toolchain_gnustl_thumb/test_config.py b/tests/build/standalone_toolchain_gnustl_thumb/test_config.py
new file mode 100644
index 0000000..7322002
--- /dev/null
+++ b/tests/build/standalone_toolchain_gnustl_thumb/test_config.py
@@ -0,0 +1,9 @@
+# Shut up a warning about us not being a real package.
+from __future__ import absolute_import
+
+
+def build_unsupported(abi, _api_level, _toolchain):
+    # -mthumb is only relevant for 32-bit ARM.
+    if abi not in ('armeabi', 'armeabi-v7a'):
+        return abi
+    return None
diff --git a/tests/build/standalone_toolchain_thumb/__init__.py b/tests/build/standalone_toolchain_thumb/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/build/standalone_toolchain_thumb/__init__.py
diff --git a/tests/build/standalone_toolchain_thumb/foo.cpp b/tests/build/standalone_toolchain_thumb/foo.cpp
new file mode 100644
index 0000000..fb7b6c7
--- /dev/null
+++ b/tests/build/standalone_toolchain_thumb/foo.cpp
@@ -0,0 +1,23 @@
+// Make sure we're not clobbering libc++ headers with libandroid_support.
+#include <cmath>
+
+// Use iostream instead of stdio.h to make sure we can actually get symbols from
+// libc++.so. Most of libc++ is defined in the headers, but std::cout is in the
+// library.
+#include <iostream>
+
+// If std::strings don't work then there's really no point :)
+#include <string>
+
+void foo(const std::string& s) {
+  // Using new makes sure we get libc++abi/libsupc++. Using std::string makes
+  // sure the STL works at all. Using std::cout makes sure we can access the
+  // library itself and not just the headers.
+  std::string* copy = new std::string(s);
+  std::cout << copy << std::endl;
+  delete copy;
+}
+
+int main(int, char**) {
+  foo("Hello, world!");
+}
diff --git a/tests/build/standalone_toolchain_thumb/test.py b/tests/build/standalone_toolchain_thumb/test.py
new file mode 100644
index 0000000..8d6bd7a
--- /dev/null
+++ b/tests/build/standalone_toolchain_thumb/test.py
@@ -0,0 +1,21 @@
+#
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+import ndk.testing.standalone_toolchain
+
+
+def run_test(abi, api, toolchain, _build_flags):
+    return ndk.testing.standalone_toolchain.run_test(
+        abi, api, toolchain, 'foo.cpp', ['--stl=libc++'], ['-mthumb'])
diff --git a/tests/build/standalone_toolchain_thumb/test_config.py b/tests/build/standalone_toolchain_thumb/test_config.py
new file mode 100644
index 0000000..a3267fb
--- /dev/null
+++ b/tests/build/standalone_toolchain_thumb/test_config.py
@@ -0,0 +1,18 @@
+# Shut up a warning about us not being a real package.
+from __future__ import absolute_import
+
+
+def build_unsupported(abi, _api_level, _toolchain):
+    # -mthumb is only relevant for 32-bit ARM.
+    if abi not in ('armeabi', 'armeabi-v7a'):
+        return abi
+    return None
+
+
+def build_broken(_abi, _api_level, toolchain):
+    if toolchain == '4.9':
+        # GCC's default include ordering is wrong, preventing the C++ stdlib
+        # from overriding compiler headers. In this case we can't include
+        # <cstddef> because the include_next can't find the compiler's header.
+        return toolchain, 'http://b/30096326'
+    return None, None