diff options
author | android-build-team Robot <android-build-team-robot@google.com> | 2019-01-13 04:12:30 +0000 |
---|---|---|
committer | android-build-team Robot <android-build-team-robot@google.com> | 2019-01-13 04:12:30 +0000 |
commit | 5b5c31fba0d92fd692a947b07d9e078c13a3cf49 (patch) | |
tree | 8f217bfb7546b9bc7c361cb599cdc741b283a0fb | |
parent | e33cc465361b8ce6acb42b48b484e2422b7b5cc7 (diff) | |
parent | 35b46139a726a21c34c13e51a89fd11845ac7365 (diff) | |
download | libcxx-5b5c31fba0d92fd692a947b07d9e078c13a3cf49.tar.gz |
Snap for 5228332 from 35b46139a726a21c34c13e51a89fd11845ac7365 to qt-release
Change-Id: Id4f7fe87e925b4299c639e58b8f95ee3b7099903
-rw-r--r-- | Android.bp | 119 | ||||
-rwxr-xr-x | run_tests.py | 17 | ||||
-rw-r--r-- | test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp | 2 | ||||
-rw-r--r-- | test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp | 4 | ||||
-rw-r--r-- | test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp | 8 | ||||
-rw-r--r-- | utils/libcxx/android/compiler.py | 6 | ||||
-rw-r--r-- | utils/libcxx/android/executors.py | 4 | ||||
-rw-r--r-- | utils/libcxx/android/test/config.py | 64 | ||||
-rw-r--r-- | utils/libcxx/android/test/format.py | 32 |
9 files changed, 192 insertions, 64 deletions
diff --git a/Android.bp b/Android.bp index cb7b697ca..ccd04a42e 100644 --- a/Android.bp +++ b/Android.bp @@ -14,10 +14,47 @@ // limitations under the License. // +cc_defaults { + name: "libc++ defaults", + host_supported: true, + local_include_dirs: ["include"], + export_include_dirs: ["include"], + cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"], + cppflags: [ + "-std=c++14", + "-nostdinc++", + "-fexceptions", + "-DLIBCXX_BUILDING_LIBCXXABI", + "-D_LIBCPP_BUILDING_LIBRARY", + ], + rtti: true, + stl: "none", + target: { + linux_bionic: { + enabled: true, + }, + windows: { + enabled: true, + cflags: [ + "-D_LIBCPP_HAS_THREAD_API_WIN32", + "-D_LIBCXXABI_BUILDING_LIBRARY", + "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS", + "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS", + "-UWIN32_LEAN_AND_MEAN", + ], + }, + windows_x86: { + cflags: [ + "-fsjlj-exceptions", + ], + }, + }, +} + // host + device static lib cc_library_static { name: "libc++_static", - host_supported: true, + defaults: ["libc++ defaults"], vendor_available: true, recovery_available: true, srcs: [ @@ -52,43 +89,15 @@ cc_library_static { "src/variant.cpp", "src/vector.cpp", ], - local_include_dirs: ["include"], - export_include_dirs: ["include"], - cflags: ["-Wall", "-Werror", "-Wno-unused-parameter"], - cppflags: [ - "-std=c++14", - "-nostdinc++", - "-fexceptions", - "-DLIBCXX_BUILDING_LIBCXXABI", - "-D_LIBCPP_BUILDING_LIBRARY", - ], - rtti: true, whole_static_libs: [ "libc++abi", ], - stl: "none", target: { - linux_bionic: { - enabled: true, - }, windows: { - enabled: true, - cflags: [ - "-D_LIBCPP_HAS_THREAD_API_WIN32", - "-D_LIBCXXABI_BUILDING_LIBRARY", - "-D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS", - "-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS", - "-UWIN32_LEAN_AND_MEAN", - ], srcs: [ "src/support/win32/*.cpp", ] }, - windows_x86: { - cflags: [ - "-fsjlj-exceptions", - ], - }, }, } @@ -129,6 +138,37 @@ cc_library_shared { }, } +cc_library_static { + name: "libc++experimental", + defaults: ["libc++ defaults"], + srcs: [ + "src/experimental/memory_resource.cpp", + ], +} + +cc_library_static { + name: "libc++fs", + defaults: ["libc++ defaults"], + srcs: [ + "src/filesystem/directory_iterator.cpp", + "src/filesystem/operations.cpp", + ], + multilib: { + lib32: { + // off_t usage is constrained to within the libc++ source (not the + // headers), so we can build the filesystem library with a 64-bit + // off_t on LP32 to get large file support without needing all users + // of the library to match. + cflags: ["-D_FILE_OFFSET_BITS=64"], + }, + }, + target: { + windows: { + enabled: false, + }, + }, +} + // This target is used to extract the build commands for a test executable. // See run_tests.py. cc_binary { @@ -151,6 +191,10 @@ cc_binary { // http://llvm.org/bugs/show_bug.cgi?id=21421 "-O0", ], + static_libs: [ + "libc++experimental", + "libc++fs", + ], rtti: true, local_include_dirs: [ "test/support", @@ -176,3 +220,20 @@ cc_binary { gnu_extensions: false, cpp_std: "c++17", } + +python_test { + name: "filesystem_dynamic_test_helper.py", + main: "test/support/filesystem_dynamic_test_helper.py", + srcs: [ + "test/support/filesystem_dynamic_test_helper.py", + ], + version: { + py2: { + enabled: true, + embedded_launcher: true, + }, + py3: { + enabled: false, + }, + }, +} diff --git a/run_tests.py b/run_tests.py index f510c41bc..35b7a861e 100755 --- a/run_tests.py +++ b/run_tests.py @@ -20,6 +20,7 @@ from __future__ import print_function import argparse import logging import os +import posixpath import sys THIS_DIR = os.path.dirname(os.path.realpath(__file__)) @@ -142,6 +143,19 @@ def get_build_cmds(bitness, host): return extract_build_cmds(commands, os.path.basename(target)) +def setup_test_directory(): + """Prepares a device test directory for use by the shell user.""" + stdfs_test_data = os.path.join( + THIS_DIR, 'test/std/input.output/filesystems/Inputs/static_test_env') + device_dir = '/data/local/tmp/libcxx' + dynamic_dir = posixpath.join(device_dir, 'dynamic_test_env') + check_call(['adb', 'shell', 'rm', '-rf', device_dir]) + check_call(['adb', 'shell', 'mkdir', '-p', device_dir]) + check_call(['adb', 'shell', 'mkdir', '-p', dynamic_dir]) + check_call(['adb', 'push', '--sync', stdfs_test_data, device_dir]) + check_call(['adb', 'shell', 'chown', '-R', 'shell:shell', device_dir]) + + def main(): """Program entry point.""" logging.basicConfig(level=logging.INFO) @@ -176,6 +190,9 @@ def main(): have_filter_args = True break # No need to keep scanning. + if not args.host: + setup_test_directory() + lit_args = [ '-sv', android_mode_arg, cxx_under_test_arg, cxx_template_arg, link_template_arg, libcxx_site_cfg_arg, libcxxabi_site_cfg_arg diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp index cbe2b2d09..9030b93a3 100644 --- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp +++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.permissions/permissions.pass.cpp @@ -159,7 +159,7 @@ TEST_CASE(test_no_resolve_symlink_on_symlink) {perms::owner_all, perms::group_all, perm_options::remove}, }; for (auto const& TC : cases) { -#if defined(__APPLE__) || defined(__FreeBSD__) +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__ANDROID__) // On OS X symlink permissions are supported. We should get an empty // error code and the expected permissions. const auto expected_link_perms = TC.expected; diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp index 5f7b30dd6..ace8b7d69 100644 --- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp +++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.proximate/proximate.pass.cpp @@ -72,7 +72,11 @@ TEST_CASE(basic_test) { {cwd, "a", ".."}, {parent_cwd, "a", "../.."}, {"a", cwd, "a"}, +#if !defined(__ANDROID__) + // Android tests are run via a RemoteExecutor, where the parent directory + // is a temporary directory with no fixed name. {"a", parent_cwd, "fs.op.proximate/a"}, +#endif {"/", "a", dot_dot_to_root / ".."}, {"/", "a/b", dot_dot_to_root / "../.."}, {"/", "a/b/", dot_dot_to_root / "../../.."}, diff --git a/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp b/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp index 523e429cf..4f83e0f22 100644 --- a/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp +++ b/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp @@ -112,9 +112,17 @@ TEST_CASE(basic_tests) { std::error_code ec = GetTestEC(); path ret = temp_directory_path(ec); +#if defined(__ANDROID__) + // Android has no globally writable storage and thus this API does not + // work without environment configuration. + TEST_CHECK(ec != GetTestEC()); + TEST_CHECK(ec); + TEST_CHECK(ret == ""); +#else TEST_CHECK(!ec); TEST_CHECK(ret == "/tmp"); TEST_CHECK(is_directory(ret)); +#endif } } diff --git a/utils/libcxx/android/compiler.py b/utils/libcxx/android/compiler.py index 16ed44a88..3e9242a34 100644 --- a/utils/libcxx/android/compiler.py +++ b/utils/libcxx/android/compiler.py @@ -14,6 +14,10 @@ class AndroidCXXCompiler(libcxx.compiler.CXXCompiler): self.link_template = link_template self.build_top = os.getenv('ANDROID_BUILD_TOP') + # The file system tests require a handful of defines that we can't add + # to the Android.bp since they require absolute paths. + self.extra_cflags = [] + def copy(self): return copy.deepcopy(self) @@ -60,7 +64,7 @@ class AndroidCXXCompiler(libcxx.compiler.CXXCompiler): source_files = [source_files] cxx_args = self.cxx_template.replace('%OUT%', out) cxx_args = cxx_args.replace('%SOURCE%', ' '.join(source_files)) - return [self.path] + shlex.split(cxx_args) + return [self.path] + shlex.split(cxx_args) + self.extra_cflags def linkCmd(self, source_files, out=None, flags=None): if out is None: diff --git a/utils/libcxx/android/executors.py b/utils/libcxx/android/executors.py index 7bf3413d1..d3c5d6875 100644 --- a/utils/libcxx/android/executors.py +++ b/utils/libcxx/android/executors.py @@ -16,7 +16,7 @@ class AdbExecutor(libcxx.test.executor.RemoteExecutor): def _remote_temp(self, is_dir): dir_arg = '-d' if is_dir else '' - cmd = 'mktemp -q {} /data/local/tmp/libcxx.XXXXXXXXXX'.format(dir_arg) + cmd = 'mktemp -q {} /data/local/tmp/libcxx/temp.XXXXXX'.format(dir_arg) _, temp_path, err, exitCode = self._execute_command_remote([cmd]) temp_path = temp_path.strip() if exitCode != 0: @@ -32,7 +32,7 @@ class AdbExecutor(libcxx.test.executor.RemoteExecutor): adb_cmd.extend(['-s', self.serial]) delimiter = 'x' - probe_cmd = ' '.join(cmd) + '; echo {}$?'.format(delimiter) + probe_cmd = 'su shell {}; echo {}$?'.format(' '.join(cmd), delimiter) env_cmd = [] if env is not None: diff --git a/utils/libcxx/android/test/config.py b/utils/libcxx/android/test/config.py index 1356f0556..3e1edd42c 100644 --- a/utils/libcxx/android/test/config.py +++ b/utils/libcxx/android/test/config.py @@ -1,5 +1,6 @@ import os import re +import sys import libcxx.test.config import libcxx.android.compiler @@ -9,6 +10,12 @@ import libcxx.android.test.format class Configuration(libcxx.test.config.Configuration): def __init__(self, lit_config, config): super(Configuration, self).__init__(lit_config, config) + self.exec_env = {} + + @property + def is_host(self): + """Returns True if configured to run host tests.""" + return self.lit_config.params.get('android_mode') == 'host' def configure(self): self.configure_src_root() @@ -17,6 +24,10 @@ class Configuration(libcxx.test.config.Configuration): self.configure_cxx() self.configure_triple() self.configure_features() + if self.is_host: + self.configure_filesystem_host() + else: + self.configure_filesystem_device() def print_config_info(self): self.lit_config.note( @@ -29,7 +40,7 @@ class Configuration(libcxx.test.config.Configuration): list(self.config.available_features)) def configure_obj_root(self): - if self.lit_config.params.get('android_mode') == 'host': + if self.is_host: self.libcxx_obj_root = os.getenv('ANDROID_HOST_OUT') else: self.libcxx_obj_root = os.getenv('ANDROID_PRODUCT_OUT') @@ -49,8 +60,53 @@ class Configuration(libcxx.test.config.Configuration): self.config.target_triple = self.cxx.get_triple() + def configure_filesystem_host(self): + # TODO: We shouldn't be writing to the source directory for the host. + static_env = os.path.join(self.libcxx_src_root, 'test', 'std', + 'input.output', 'filesystems', 'Inputs', + 'static_test_env') + static_env = os.path.realpath(static_env) + assert os.path.isdir(static_env) + self.cxx.extra_cflags.append( + '-DLIBCXX_FILESYSTEM_STATIC_TEST_ROOT="{}"'.format(static_env)) + + dynamic_env = os.path.join(self.config.test_exec_root, 'filesystem', + 'Output', 'dynamic_env') + dynamic_env = os.path.realpath(dynamic_env) + if not os.path.isdir(dynamic_env): + os.makedirs(dynamic_env) + self.cxx.extra_cflags.append( + '-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT="{}"'.format(dynamic_env)) + self.exec_env['LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT'] = dynamic_env + + dynamic_helper = os.path.join(self.libcxx_src_root, 'test', 'support', + 'filesystem_dynamic_test_helper.py') + assert os.path.isfile(dynamic_helper) + self.cxx.extra_cflags.append( + '-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER="{} {}"'.format( + sys.executable, dynamic_helper)) + + def configure_filesystem_device(self): + static_env = '/data/local/tmp/libcxx/static_test_env' + self.cxx.extra_cflags.append( + '-DLIBCXX_FILESYSTEM_STATIC_TEST_ROOT="{}"'.format(static_env)) + + dynamic_env = '/data/local/tmp/libcxx/dynamic_test_env' + self.cxx.extra_cflags.append( + '-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT="{}"'.format(dynamic_env)) + self.exec_env['LIBCXX_FILESYSTEM_DYNAMIC_TEST_ROOT'] = dynamic_env + + dynamic_helper = ('/data/nativetest/filesystem_dynamic_test_helper.py/' + 'filesystem_dynamic_test_helper.py') + self.cxx.extra_cflags.append( + '-DLIBCXX_FILESYSTEM_DYNAMIC_TEST_HELPER="{}"'.format( + dynamic_helper)) + def configure_features(self): self.config.available_features.add('long_tests') + self.config.available_features.add('c++experimental') + self.config.available_features.add('c++fs') + self.config.available_features.add('c++filesystem') std_pattern = re.compile(r'-std=(c\+\+\d[0-9x-z])') match = std_pattern.search(self.cxx.cxx_template) if match: @@ -64,12 +120,14 @@ class Configuration(libcxx.test.config.Configuration): self.libcxx_src_root, self.libcxx_obj_root, getattr(self.config, 'device_dir', '/data/local/tmp/'), - getattr(self.config, 'timeout', '60')) + getattr(self.config, 'timeout', '60'), + self.exec_env) elif mode == 'host': return libcxx.android.test.format.HostTestFormat( self.cxx, self.libcxx_src_root, self.libcxx_obj_root, - getattr(self.config, 'timeout', '60')) + getattr(self.config, 'timeout', '60'), + self.exec_env) else: raise RuntimeError('Invalid android_mode: {}'.format(mode)) diff --git a/utils/libcxx/android/test/format.py b/utils/libcxx/android/test/format.py index 228272c18..761c019ab 100644 --- a/utils/libcxx/android/test/format.py +++ b/utils/libcxx/android/test/format.py @@ -29,8 +29,10 @@ class HostTestFormat(libcxx.test.format.LibcxxTestFormat): os.path.join(outdir, 'lib'), os.path.join(outdir, 'lib64'), ]) - default_env = {'LD_LIBRARY_PATH': libpath} - self.exec_env = default_env if exec_env is None else exec_env + env = {'LD_LIBRARY_PATH': libpath} + if exec_env is not None: + env.update(exec_env) + self.exec_env = env class TestFormat(HostTestFormat): @@ -52,32 +54,6 @@ class TestFormat(HostTestFormat): def _wd_path(self, test_name, file_name): return os.path.join(self._working_directory(test_name), file_name) - def _build(self, exec_path, source_path, compile_only=False, - use_verify=False): - # pylint: disable=protected-access - cmd, report, rc = libcxx.test.format.LibcxxTestFormat._build( - self, exec_path, source_path, compile_only, use_verify) - if rc != 0: - return cmd, report, rc - - try: - exec_file = os.path.basename(exec_path) - - adb.mkdir(self._working_directory(exec_file)) - adb.push(exec_path, self._wd_path(exec_file, exec_file)) - - # Push any .dat files in the same directory as the source to the - # working directory. - src_dir = os.path.dirname(source_path) - data_files = [f for f in os.listdir(src_dir) if f.endswith('.dat')] - for data_file in data_files: - df_path = os.path.join(src_dir, data_file) - df_dev_path = self._wd_path(exec_file, data_file) - adb.push(df_path, df_dev_path) - return cmd, report, rc - except adb.AdbError as ex: - return self._make_report(ex.cmd, ex.out, ex.err, ex.exit_code) - def _clean(self, exec_path): exec_file = os.path.basename(exec_path) cmd = ['adb', 'shell', 'rm', '-rf', self._working_directory(exec_file)] |