Framework to allow testing of static libc++abi

These changes make linking against static libraries more explicit. Instead
of using -lc++ and -lc++abi in the tests, an absolute path to the library is
provided instead.

The choices of shared vs. static, and the choices of library paths for both
libcxx and libcxxabi needed to be exchanged for this to work. In other words,
libcxx tests need to know the library path of libcxxabi, and whether libcxxabi
is a static or shared library.

Some Mac specific logic for testing against libc++abi had to be moved from
libcxxabi's config.py, as it was overriding choices made in libcxx's config.py.
That logic is now in libcxx's target_info.py.

Testing a static libcxx on Linux will now automatically link in librt most of
the time. Previously, lots of pthread tests would fail because of an
unresolved clock_gettime.

http://reviews.llvm.org/D16544

llvm-svn: 266730
This commit is contained in:
Ben Craig 2016-04-19 12:49:05 +00:00
parent e9fdfd868a
commit 0142a9da81
4 changed files with 41 additions and 23 deletions

View File

@ -14,6 +14,7 @@ pythonize_bool(LIBCXX_ENABLE_RTTI)
pythonize_bool(LIBCXX_ENABLE_SHARED)
pythonize_bool(LIBCXX_BUILD_32_BITS)
pythonize_bool(LIBCXX_GENERATE_COVERAGE)
pythonize_bool(LIBCXXABI_ENABLE_SHARED)
pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER)
pythonize_bool(LIBCXX_HAS_ATOMIC_LIB)
@ -23,6 +24,13 @@ if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY OR LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
set(LIBCXX_CXX_ABI_LIBNAME "none")
endif()
# By default, for non-standalone builds, libcxx and libcxxabi share a library
# directory.
if (NOT LIBCXX_CXX_ABI_LIBRARY_PATH)
set(LIBCXX_CXX_ABI_LIBRARY_PATH "${LIBCXX_LIBRARY_DIR}" CACHE PATH
"The path to libc++abi library.")
endif()
set(LIBCXX_TARGET_INFO "libcxx.test.target_info.LocalTI" CACHE STRING
"TargetInfo to use when setting up test environment.")
set(LIBCXX_EXECUTOR "None" CACHE STRING

View File

@ -439,21 +439,7 @@ class Configuration(object):
self.cxx.link_flags += shlex.split(link_flags_str)
def configure_link_flags_cxx_library_path(self):
libcxx_library = self.get_lit_conf('libcxx_library')
# Configure libc++ library paths.
if libcxx_library is not None:
# Check that the given value for libcxx_library is valid.
if not os.path.isfile(libcxx_library):
self.lit_config.fatal(
"libcxx_library='%s' is not a valid file." %
libcxx_library)
if self.use_system_cxx_lib:
self.lit_config.fatal(
"Conflicting options: 'libcxx_library' cannot be used "
"with 'use_system_cxx_lib=true'")
self.cxx.link_flags += ['-Wl,-rpath,' +
os.path.dirname(libcxx_library)]
elif not self.use_system_cxx_lib and self.cxx_library_root:
if not self.use_system_cxx_lib and self.cxx_library_root:
self.cxx.link_flags += ['-L' + self.cxx_library_root,
'-Wl,-rpath,' + self.cxx_library_root]
@ -465,11 +451,16 @@ class Configuration(object):
'-Wl,-rpath,' + self.abi_library_root]
def configure_link_flags_cxx_library(self):
libcxx_library = self.get_lit_conf('libcxx_library')
if libcxx_library:
self.cxx.link_flags += [libcxx_library]
else:
libcxx_shared = self.get_lit_bool('enable_shared', default=True)
if libcxx_shared:
self.cxx.link_flags += ['-lc++']
else:
cxx_library_root = self.get_lit_conf('cxx_library_root')
if cxx_library_root:
abs_path = os.path.join(cxx_library_root, 'libc++.a')
self.cxx.link_flags += [abs_path]
else:
self.cxx.link_flags += ['-lc++']
def configure_link_flags_abi_library(self):
cxx_abi = self.get_lit_conf('cxx_abi', 'libcxxabi')
@ -479,7 +470,16 @@ class Configuration(object):
self.cxx.link_flags += ['-lsupc++']
elif cxx_abi == 'libcxxabi':
if self.target_info.allow_cxxabi_link():
self.cxx.link_flags += ['-lc++abi']
libcxxabi_shared = self.get_lit_bool('libcxxabi_shared', default=True)
if libcxxabi_shared:
self.cxx.link_flags += ['-lc++abi']
else:
cxxabi_library_root = self.get_lit_conf('abi_library_path')
if cxxabi_library_root:
abs_path = os.path.join(cxxabi_library_root, 'libc++abi.a')
self.cxx.link_flags += [abs_path]
else:
self.cxx.link_flags += ['-lc++abi']
elif cxx_abi == 'libcxxrt':
self.cxx.link_flags += ['-lcxxrt']
elif cxx_abi == 'none':

View File

@ -90,11 +90,8 @@ class DarwinLocalTI(DefaultTargetInfo):
def configure_env(self, env):
library_paths = []
# Configure the library path for libc++
libcxx_library = self.full_config.get_lit_conf('libcxx_library')
if self.full_config.use_system_cxx_lib:
pass
elif libcxx_library:
library_paths += [os.path.dirname(libcxx_library)]
elif self.full_config.cxx_library_root:
library_paths += [self.full_config.cxx_library_root]
# Configure the abi library path
@ -104,6 +101,15 @@ class DarwinLocalTI(DefaultTargetInfo):
env['DYLD_LIBRARY_PATH'] = ':'.join(library_paths)
def allow_cxxabi_link(self):
# FIXME: PR27405
# libc++ *should* export all of the symbols found in libc++abi on OS X.
# For this reason LibcxxConfiguration will not link libc++abi in OS X.
# However __cxa_throw_bad_new_array_length doesn't get exported into
# libc++ yet so we still need to explicitly link libc++abi when testing
# libc++abi
# See PR22654.
if(self.full_config.get_lit_conf('name', '') == 'libc++abi'):
return True
# Don't link libc++abi explicitly on OS X because the symbols
# should be available in libc++ directly.
return False
@ -162,11 +168,14 @@ class LinuxLocalTI(DefaultTargetInfo):
enable_threads = ('libcpp-has-no-threads' not in
self.full_config.config.available_features)
llvm_unwinder = self.full_config.get_lit_bool('llvm_unwinder', False)
shared_libcxx = self.full_config.get_lit_bool('enable_shared', True)
flags += ['-lm']
if not llvm_unwinder:
flags += ['-lgcc_s', '-lgcc']
if enable_threads:
flags += ['-lpthread']
if not shared_libcxx:
flags += ['-lrt']
flags += ['-lc']
if llvm_unwinder:
flags += ['-lunwind', '-ldl']

View File

@ -21,6 +21,7 @@ config.target_info = "@LIBCXX_TARGET_INFO@"
config.executor = "@LIBCXX_EXECUTOR@"
config.llvm_unwinder = "@LIBCXXABI_USE_LLVM_UNWINDER@"
config.use_libatomic = "@LIBCXX_HAS_ATOMIC_LIB@"
config.libcxxabi_shared = "@LIBCXXABI_ENABLE_SHARED@"
# Let the main config do the real work.
lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/test/lit.cfg")