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