Misc changes
http://reviews.llvm.org/D7542
Files:
CMakeLists.txt
cmake/Modules/CodeCoverage.cmake
cmake/Modules/GetCompilerRTOptions.cmake
lib/CMakeLists.txt
test/CMakeLists.txt
test/libcxx/clang_utils.py
test/libcxx/compiler.py
test/libcxx/test/config.py
test/lit.site.cfg.in
EMAIL PREFERENCES
http://reviews.llvm.org/settings/panel/emailpreferences/
Index: CMakeLists.txt
===================================================================
--- CMakeLists.txt
+++ CMakeLists.txt
@@ -10,6 +10,9 @@
if(POLICY CMP0042)
cmake_policy(SET CMP0042 NEW) # Set MACOSX_RPATH=YES by default
endif()
+if(POLICY CMP0040)
+ cmake_policy(SET CMP0040 NEW) # Require add_custom_target(TARGET...)
+endif()
set(PACKAGE_NAME libcxx)
set(PACKAGE_VERSION trunk-svn)
@@ -61,8 +64,10 @@
This option may only be used when LIBCXX_ENABLE_THREADS=OFF." ON)
option(LIBCXX_INSTALL_HEADERS "Install the libc++ headers." ON)
option(LIBCXX_INSTALL_SUPPORT_HEADERS "Install libc++ support headers." ON)
+option(LIBCXX_GENERATE_COVERAGE "Enable generating code coverage." OFF)
set(LIBCXX_SYSROOT "" CACHE STRING "Use alternate sysroot.")
set(LIBCXX_GCC_TOOLCHAIN "" CACHE STRING "Use alternate GCC toolchain.")
+set(LIBCXX_CLANG_RESOURCE_DIR "" CACHE STRING "The Clang resource directory root.")
if (LIBCXX_BUILT_STANDALONE)
set(LLVM_USE_SANITIZER "" CACHE STRING
"Define the sanitizer used to build the library and tests")
@@ -96,9 +101,12 @@
# Declare libc++ configuration variables.
# They are intended for use as follows:
+# LIBCXX_TARGET_FLAGS: Compile and link flags that affect the output target or
+# arch. ex: -m32 -target
# LIBCXX_CXX_FLAGS: General flags for both the compiler and linker.
# LIBCXX_COMPILE_FLAGS: Compile only flags.
# LIBCXX_LINK_FLAGS: Linker only flags.
+set(LIBCXX_TARGET_FLAGS "")
set(LIBCXX_CXX_FLAGS "")
set(LIBCXX_COMPILE_FLAGS "")
set(LIBCXX_LINK_FLAGS "")
@@ -107,6 +115,11 @@
include(config-ix)
# Configure ABI library
include(HandleLibCXXABI)
+# Configure coverage options.
+if (LIBCXX_GENERATE_COVERAGE)
+ include(CodeCoverage)
+ set(CMAKE_BUILD_TYPE "COVERAGE" CACHE STRING "" FORCE)
+endif()
#===============================================================================
# Setup Compiler Flags
@@ -213,7 +226,7 @@
if (CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT WIN32)
if (LIBCXX_BUILD_32_BITS)
message(STATUS "Building 32 bits executables and libraries.")
- list(APPEND LIBCXX_CXX_FLAGS "-m32")
+ list(APPEND LIBCXX_TARGET_FLAGS "-m32")
endif()
elseif(LIBCXX_BUILD_32_BITS)
message(FATAL_ERROR "LIBCXX_BUILD_32_BITS=ON is not supported on this platform.")
@@ -268,14 +281,35 @@
endif()
endif()
-append_if(LIBCXX_CXX_FLAGS LIBCXX_TARGET_TRIPLE
+append_if(LIBCXX_TARGET_FLAGS LIBCXX_TARGET_TRIPLE
"-target ${LIBCXX_TARGET_TRIPLE}")
-append_if(LIBCXX_CXX_FLAGS LIBCXX_SYSROOT "--sysroot ${LIBCXX_SYSROOT}")
-append_if(LIBCXX_CXX_FLAGS LIBCXX_GCC_TOOLCHAIN
+
+append_if(LIBCXX_TARGET_FLAGS LIBCXX_SYSROOT "--sysroot ${LIBCXX_SYSROOT}")
+append_if(LIBCXX_TARGET_FLAGS LIBCXX_GCC_TOOLCHAIN
"-gcc-toolchain ${LIBCXX_GCC_TOOLCHAIN}")
+if (LLVM_USE_SANITIZER AND LIBCXX_GENERATE_COVERAGE)
+ message(FATAL_ERROR "LLVM_USE_SANITIZER cannot be used with LIBCXX_GENERATE_COVERAGE")
+endif()
+
+# We need to probe and manually link the sanitizer libraries on OS X.
+if (APPLE AND LLVM_USE_SANITIZER)
+ set(LIBCXX_COMPILER_RT_OPTION "${LLVM_USE_SANITIZER}")
+elseif(LIBCXX_GENERATE_COVERAGE)
+ set(LIBCXX_COMPILER_RT_OPTION "Profile")
+endif()
+
+# Manually link the required sanitizer libraries.
+if (DEFINED LIBCXX_COMPILER_RT_OPTION)
+ include(GetCompilerRTOptions)
+ get_compiler_rt_option(LIBCXX_COMPILER_RT_LINK_LIBRARIES
+ "${LIBCXX_COMPILER_RT_OPTION}"
+ "${LIBCXX_TARGET_FLAGS}")
+endif()
+
string(REPLACE ";" " " LIBCXX_CXX_FLAGS "${LIBCXX_CXX_FLAGS}")
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_FLAGS}")
+string(REPLACE ";" " " LIBCXX_TARGET_FLAGS "${LIBCXX_TARGET_FLAGS}")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LIBCXX_CXX_FLAGS} ${LIBCXX_TARGET_FLAGS}")
#===============================================================================
# Setup Source Code
Index: cmake/Modules/CodeCoverage.cmake
===================================================================
--- /dev/null
+++ cmake/Modules/CodeCoverage.cmake
@@ -0,0 +1,36 @@
+find_program(CODE_COVERAGE_LCOV lcov)
+if (NOT CODE_COVERAGE_LCOV)
+ message(FATAL_ERROR "Cannot find lcov...")
+endif()
+
+find_program(CODE_COVERAGE_GENHTML genhtml)
+if (NOT CODE_COVERAGE_GENHTML)
+ message(FATAL_ERROR "Cannot find genhtml...")
+endif()
+
+set(CMAKE_CXX_FLAGS_COVERAGE "-g -O0 --coverage")
+
+function(setup_lcov_test_target_coverage target_name output_dir capture_dirs source_dirs)
+ file(MAKE_DIRECTORY ${output_dir})
+
+ set(CAPTURE_DIRS "")
+ foreach(cdir ${capture_dirs})
+ list(APPEND CAPTURE_DIRS "-d;${cdir}")
+ endforeach()
+
+ set(EXTRACT_DIRS "")
+ foreach(sdir ${source_dirs})
+ list(APPEND EXTRACT_DIRS "'${sdir}/*'")
+ endforeach()
+
+ message(STATUS "Capture Directories: ${CAPTURE_DIRS}")
+ message(STATUS "Extract Directories: ${EXTRACT_DIRS}")
+
+ add_custom_target(generate-lib${target_name}-coverage
+ COMMAND ${CODE_COVERAGE_LCOV} --capture ${CAPTURE_DIRS} -o test_coverage.info
+ COMMAND ${CODE_COVERAGE_LCOV} --extract test_coverage.info ${EXTRACT_DIRS} -o test_coverage.info
+ COMMAND ${CODE_COVERAGE_GENHTML} --demangle-cpp test_coverage.info -o test_coverage
+ COMMAND ${CMAKE_COMMAND} -E remove test_coverage.info
+ WORKING_DIRECTORY ${output_dir}
+ COMMENT "Generating coverage results")
+endfunction()
\ No newline at end of file
Index: cmake/Modules/GetCompilerRTOptions.cmake
===================================================================
--- /dev/null
+++ cmake/Modules/GetCompilerRTOptions.cmake
@@ -0,0 +1,49 @@
+# An internal method to setup the python enviroment.
+macro(_setup_python)
+ if (LIT_EXECUTABLE)
+ get_filename_component(LIT_MODULE_PATH ${LIT_EXECUTABLE} DIRECTORY)
+ else()
+ set(LIT_MODULE_PATH "${CMAKE_SOURCE_DIR}/utils/lit")
+ endif()
+ if (NOT IS_DIRECTORY ${LIT_MODULE_PATH})
+ message(FATAL_ERROR "Failed to find the LIT module.")
+ endif()
+ set(LIBCXX_PYTHONPATH "${LIT_MODULE_PATH}:${LIBCXX_SOURCE_DIR}/test:$ENV{PYTHONPATH}")
+ set(ENV{PYTHONPATH} "${LIBCXX_PYTHONPATH}")
+ include(FindPythonInterp)
+ if(NOT PYTHONINTERP_FOUND)
+ message(FATAL_ERROR "Failed to find python executable")
+ endif()
+endmacro()
+
+#===============================================================================
+# Get CompilerRT link flags
+#===============================================================================
+#
+# get_compiler_rt_option: Get link flags for a given compiler-rt library.
+#
+# Parameters:
+# output_var: The variable to write the list of flags to.
+# opt: The compiler-rt configuration to get the flags for. It can be one of
+# Profile, Address, Memory, MemoryWithOrigins, Undefined, Thread.
+# extra_flags: A list of extra compiler flags used to help find the
+# compiler_rt libraries.
+function(get_compiler_rt_option output_var opt extra_flags)
+ if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
+ message(FATAL_ERROR
+ "GetCompilerRTOptions can only be used with a Clang compiler")
+ endif()
+ _setup_python()
+ separate_arguments(extra_flags)
+ foreach(e ${extra_flags})
+ list(APPEND EXTRA_FLAGS "--flag;${e}")
+ endforeach()
+ execute_process(COMMAND ${PYTHON_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/test/libcxx/clang_utils.py --cxx ${CMAKE_CXX_COMPILER} ${EXTRA_FLAGS} ${opt}
+ RESULT_VARIABLE RES_VAR
+ OUTPUT_VARIABLE OUTPUT_VAR)
+ if (NOT RES_VAR EQUAL 0)
+ message(FATAL_ERROR "get_compiler_rt_option failed to get link options for ${opt}")
+ endif()
+ string(STRIP "${OUTPUT_VAR}" OUTPUT_VAR)
+ set(${output_var} "${OUTPUT_VAR}" PARENT_SCOPE)
+endfunction()
Index: lib/CMakeLists.txt
===================================================================
--- lib/CMakeLists.txt
+++ lib/CMakeLists.txt
@@ -1,3 +1,5 @@
+set(LIBCXX_LIB_CMAKEFILES_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}" PARENT_SCOPE)
+
# Get sources
file(GLOB LIBCXX_SOURCES ../src/*.cpp)
if(WIN32)
@@ -50,12 +52,14 @@
if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH)
target_link_libraries(cxx "-L${LIBCXX_CXX_ABI_LIBRARY_PATH}")
endif()
+target_link_libraries(cxx ${LIBCXX_COMPILER_RT_LINK_LIBRARIES})
target_link_libraries(cxx ${libraries})
# Setup flags.
append_if(LIBCXX_COMPILE_FLAGS LIBCXX_HAS_FPIC_FLAG -fPIC)
append_if(LIBCXX_LINK_FLAGS LIBCXX_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs)
+
if ( APPLE )
if ( CMAKE_OSX_DEPLOYMENT_TARGET STREQUAL "10.6" )
list(APPEND LIBCXX_COMPILE_FLAGS "-U__STRICT_ANSI__")
Index: test/CMakeLists.txt
===================================================================
--- test/CMakeLists.txt
+++ test/CMakeLists.txt
@@ -44,6 +44,7 @@
pythonize_bool(LIBCXX_BUILD_32_BITS)
pythonize_bool(LIBCXX_ENABLE_THREADS)
pythonize_bool(LIBCXX_ENABLE_MONOTONIC_CLOCK)
+ pythonize_bool(LIBCXX_GENERATE_COVERAGE)
set(AUTO_GEN_COMMENT "## Autogenerated by libcxx configuration.\n# Do not edit!")
@@ -59,6 +60,14 @@
DEPENDS cxx
COMMENT "Running libcxx tests"
${cmake_3_2_USES_TERMINAL})
+
+ if (LIBCXX_GENERATE_COVERAGE)
+ include(CodeCoverage)
+ set(output_dir "${CMAKE_CURRENT_BINARY_DIR}/coverage")
+ set(capture_dirs "${LIBCXX_LIB_CMAKEFILES_DIR}/cxx.dir/;${CMAKE_CURRENT_BINARY_DIR}")
+ set(extract_dirs "${LIBCXX_SOURCE_DIR}/include;${LIBCXX_SOURCE_DIR}/src")
+ setup_lcov_test_target_coverage("cxx" "${output_dir}" "${capture_dirs}" "${extract_dirs}")
+ endif()
else()
message(WARNING
"LIT_EXECUTABLE not set, no check-libcxx target will be available!")
Index: test/libcxx/clang_utils.py
===================================================================
--- /dev/null
+++ test/libcxx/clang_utils.py
@@ -0,0 +1,354 @@
+"""
+clang_utils - Utilities for linking with the clang compiler.
+"""
+
+import os
+import libcxx.compiler
+
+
+class BasicClangLinkDriver(object):
+ """
+ BasicClangLinkDriver - A linker driver that mimics how clang links
+ compiler-rt
+ """
+ def __init__(self, cxx):
+ self.cxx = cxx
+ if cxx.type is None or 'clang' not in cxx.type:
+ raise RuntimeError('Compiler is not a clang variant')
+ search_paths = self.cxx.getLibrarySearchPaths()
+ if not search_paths:
+ raise RuntimeError('Failed to get search paths')
+ self.clang_resource_dir = search_paths[0]
+ if not os.path.isdir(self.clang_resource_dir):
+ raise RuntimeError('Clang resource directory does not exist')
+ self.target_info = self.cxx.getTargetInfo()
+ sys = self.target_info.sys
+ if sys.startswith('darwin'):
+ self.target_info.sys = 'darwin'
+ self.clang_library_dir = os.path.join(
+ self.clang_resource_dir, 'lib', self.target_info.sys)
+ if not os.path.isdir(self.clang_library_dir):
+ raise RuntimeError('clang library path does not exist: %s' %
+ self.clang_library_dir)
+
+ def getClangResourceDir(self):
+ """
+ Return clangs root resource dir.
+
+ If clang is /path/to/bin/clang++ then the resource dir is usually
+ /path/to/bin/../lib/clang/<X>.<Y>.<Z>/
+ """
+ return self.clang_resource_dir
+
+ def getClangLibraryDir(self):
+ """
+ Return clangs library dir. This directory contains the compiler-rt
+ libraries.
+
+ If clang is /path/to/bin/clang++ then the library dir is usually
+ /path/to/bin/../lib/clang/<X>.<Y>.<Z>/lib/<platform>
+ """
+ return self.clang_library_dir
+
+ def getStaticCompilerRTLibrary(self, suffix, required=False):
+ """
+ Return the full path to a static clang_rt library or None if it doesn't
+ exist.
+
+ If required is True then the function will throw if the library is not
+ found.
+ """
+ libname = 'libclang_rt.%s.a' % suffix
+ libpath = os.path.join(self.clang_library_dir, libname)
+ if os.path.isfile(libpath):
+ return libpath
+ elif required:
+ raise RuntimeError('Required library %s not found at %s' %
+ (libname, libpath))
+ else:
+ return None
+
+ def getStaticCompilerRTLibraryWithArch(self, name, required=False):
+ """
+ Return the full path to a static architecture specific clang_rt library
+ or None if it doesn't exist.
+
+ If required is True then the function will throw if the library is not
+ found.
+ """
+ return self.getStaticCompilerRTLibrary(
+ '%s-%s' % (name, self.target_info.arch), required=required)
+
+ def getSharedCompilerRTLibrary(self, suffix, required=False):
+ """
+ Return the full path to a shared clang_rt library or None if it doesn't
+ exist.
+
+ If required is True then the function will throw if the library is not
+ found.
+ """
+ libname = 'libclang_rt.%s' % suffix
+ if self.target_info.sys == 'darwin':
+ libname += '.dylib'
+ else:
+ libname += '.so'
+ libpath = os.path.join(self.clang_library_dir, libname)
+ if os.path.isfile(libpath):
+ return libpath
+ elif required:
+ raise RuntimeError('Required library %s not found at %s' %
+ (libname, libpath))
+ else:
+ return None
+
+ def getSharedCompilerRTLibraryWithArch(self, name, required=False):
+ """
+ Return the full path to a shared architecture specific clang_rt library
+ or None if it doesn't exist.
+
+ If required is True then the function will throw if the library is not
+ found.
+ """
+ return self.getSharedCompilerRTLibrary(
+ '%s-%s' % (name, self.target_info.arch), required=required)
+
+ def getCompilerRTLibrary(self, name):
+ """
+ Return the full path to a shared or static clang_rt library. Throw if
+ the library doesn't exist.
+
+ This function will try looking for the shared library first and if that
+ is not found will search for the static version.
+ """
+ ret = self.getSharedCompilerRTLibrary(name)
+ if ret is None:
+ ret = self.getStaticCompilerRTLibrary(name)
+ if ret is None:
+ raise RuntimeError('Failed to find library for name: %s' % name)
+ return ret
+
+ def getCompilerRTLibraryWithArch(self, name):
+ """
+ Return the full path to a shared or static architecture specific
+ clang_rt library. Throw if the library doesn't exist.
+
+ This function will try looking for the shared library first and if that
+ is not found will search for the static version.
+ """
+ ret = self.getSharedCompilerRTLibraryWithArch(name)
+ if ret is None:
+ ret = self.getStaticCompilerRTLibraryWithArch(name)
+ if ret is None:
+ raise RuntimeError('Failed to find library for name: %s' % name)
+ return ret
+
+ def getProfileRTLinkOptions(self):
+ """
+ Return a list of link options for ProfileRt
+ """
+ raise NotImplementedError("abstract method for %s" % type(self))
+
+ def getASanLinkOptions(self):
+ """
+ Return a list of link options for ASAN
+ """
+ raise NotImplementedError("abstract method for %s" % type(self))
+
+ def getMSanLinkOptions(self):
+ """
+ Return a list of link options for MSAN
+ """
+ raise NotImplementedError("abstract method for %s" % type(self))
+
+ def getUBSanLinkOptions(self):
+ """
+ Return a list of link options for UBSAN
+ """
+ raise NotImplementedError("abstract method for %s" % type(self))
+
+ def getTSanLinkOptions(self):
+ """
+ Return a list of link options for TSAN
+ """
+ raise NotImplementedError("abstract method for %s" % type(self))
+
+
+class DarwinClangLinkDriver(BasicClangLinkDriver):
+ """
+ The implementation of BasicClangLinkDriver for stock clang on OS X.
+ """
+ def __init__(self, cxx):
+ super(DarwinClangLinkDriver, self).__init__(cxx)
+
+ def getProfileRTLinkOptions(self):
+ return [
+ self.getCompilerRTLibrary('profile_osx'),
+ ]
+
+ def getASanLinkOptions(self):
+ return [
+ self.getCompilerRTLibrary('asan_osx_dynamic')
+ ]
+
+ def getMSanLinkOptions(self):
+ raise RuntimeError("MSan not supported")
+
+ def getUBSanLinkOptions(self):
+ return [
+ self.getCompilerRTLibrary('ubsan_osx')
+ ]
+
+ def getTSanLinkOptions(self):
+ raise RuntimeError("TSan not supported")
+
+
+class DarwinAppleClangLinkDriver(BasicClangLinkDriver):
+ """
+ The implementation of BasicClangLinkDriver for apple clang on OS X.
+ """
+ def __init__(self, cxx):
+ super(DarwinAppleClangLinkDriver, self).__init__(cxx)
+
+ def getProfileRTLinkOptions(self):
+ return [
+ self.getCompilerRTLibrary('profile_osx'),
+ '-lSystem',
+ self.getCompilerRTLibrary('osx')
+ ]
+
+ def getASanLinkOptions(self):
+ return [
+ self.getCompilerRTLibrary('asan_osx_dynamic'),
+ '-lSystem',
+ self.getCompilerRTLibrary('osx')
+ ]
+
+ def getMSanLinkOptions(self):
+ raise RuntimeError("MSan not supported")
+
+ def getUBSanLinkOptions(self):
+ return [
+ self.getCompilerRTLibrary('ubsan_osx'),
+ '-lSystem',
+ self.getCompilerRTLibrary('osx')
+ ]
+
+ def getTSanLinkOptions(self):
+ raise RuntimeError("TSan not supported")
+
+
+class LinuxClangLinkDriver(BasicClangLinkDriver):
+ """
+ The implementation of BasicClangLinkDriver for clang on linux.
+ """
+ def __init__(self, cxx):
+ super(LinuxClangLinkDriver, self).__init__(cxx)
+
+ def _getStaticLib(self, name):
+ return self.getStaticCompilerRTLibraryWithArch(name, required=True)
+
+ def _getWholeStaticLib(self, name):
+ libpath = self._getStaticLib(name)
+ return ['-Wl,--whole-archive', libpath, '-Wl,--no-whole-archive']
+
+ def _getWholeStaticLibWithSyms(self, name):
+ libpath = self._getStaticLib(name)
+ return ['-Wl,--whole-archive', libpath, '-Wl,--no-whole-archive',
+ '-Wl,--dynamic-list=' + libpath + '.syms']
+
+ def getProfileRTLinkOptions(self):
+ return [
+ self._getStaticLib('profile')
+ ]
+
+ def getASanLinkOptions(self):
+ args = []
+ args += self._getWholeStaticLibWithSyms('asan')
+ args += self._getWholeStaticLibWithSyms('asan_cxx')
+ return args
+
+ def getMSanLinkOptions(self):
+ return self._getWholeStaticLibWithSyms('msan')
+
+ def getUBSanLinkOptions(self):
+ args = []
+ args += self._getWholeStaticLib('san')
+ args += self._getWholeStaticLibWithSyms('ubsan')
+ args += self._getWholeStaticLibWithSyms('ubsan_cxx')
+ return args
+
+ def getTSanLinkOptions(self):
+ return self._getWholeStaticLibWithSyms('tsan')
+
+
+def getClangLinkDriver(cxx):
+ """
+ Return the implementation of the Clang linker driver for a giver platform
+ and compiler.
+ """
+ if cxx.type is None:
+ raise RuntimeError('Compiler type could not be determined')
+ elif 'clang' not in cxx.type:
+ raise RuntimeError('Compiler %s is not clang' % cxx.type)
+ elif cxx.type == 'apple-clang':
+ return DarwinAppleClangLinkDriver(cxx)
+ else: # cxx.type == 'clang'
+ trip = cxx.getTriple()
+ if 'darwin' in trip:
+ return DarwinClangLinkDriver(cxx)
+ elif 'linux' in trip:
+ return LinuxClangLinkDriver(cxx)
+ else:
+ raise RuntimeError('Unsupported target: %s' % trip)
+ assert False
+
+
+def main():
+ """
+ Print a semi-colon list of compiler-rt link flags based on the compiler
+ and arguments.
+
+ clang-utils.py [--cxx compiler] [--flag cxx_flag]... Spec
+ options:
+ --cxx - The cxx compiler to use
+ --flag - A list of extra flags to configure with
+ Spec - One of Profile, Address, Memory, MemoryWithAddress, Undefined,
+ Thread.
+ """
+ from optparse import OptionParser
+ parser = OptionParser("usage: %prog [options] {CompilerRT Spec}")
+ parser.add_option('-c', '--cxx', dest='compiler',
+ help='The compiler to use',
+ type=str, action='store', default='clang++')
+ parser.add_option("-f", "--flag", dest="extraFlags",
+ metavar="NAME=VAL",
+ help="Add 'NAME' = 'VAL' to the flags used",
+ type=str, action='append', default=[])
+ (opts, args) = parser.parse_args()
+ cxx = libcxx.compiler.CXXCompiler(opts.compiler, flags=opts.extraFlags)
+ driver = getClangLinkDriver(cxx)
+ if len(args) != 1:
+ print('Invalid args: %s' % args)
+ raise SystemExit(1)
+ spec = args[0]
+ info_specs = {
+ 'Profile': driver.getProfileRTLinkOptions,
+ 'Address': driver.getASanLinkOptions,
+ 'Memory': driver.getMSanLinkOptions,
+ 'MemoryWithAddress': driver.getMSanLinkOptions,
+ 'Undefined': driver.getUBSanLinkOptions,
+ 'Thread': driver.getUBSanLinkOptions
+ }
+ if spec not in info_specs.keys():
+ print('%s is not a valid spec' % spec)
+ raise SystemExit(1)
+ try:
+ out = ';'.join(info_specs[spec]())
+ print(out)
+ except RuntimeError as e:
+ print('%s Exception thrown' % e)
+ SystemError(1)
+
+if __name__ == '__main__':
+ main()
+ raise SystemExit
Index: test/libcxx/compiler.py
===================================================================
--- test/libcxx/compiler.py
+++ test/libcxx/compiler.py
@@ -1,8 +1,17 @@
import os
+import re
import lit.util
import libcxx.util
+class TargetInfo:
+ def __init__(self, arch=None, sys=None, vendor=None, abi=None):
+ self.arch = arch
+ self.sys = sys
+ self.vendor = vendor
+ self.abi = abi
+
+
class CXXCompiler(object):
def __init__(self, path, flags=None, compile_flags=None, link_flags=None,
use_ccache=False):
@@ -133,4 +142,41 @@
def getTriple(self):
cmd = [self.path] + self.flags + ['-dumpmachine']
- return lit.util.capture(cmd).strip()
+ out, err, rc = lit.util.executeCommand(cmd)
+ if rc != 0:
+ raise Exception()
+ return out.strip()
+
+ def getTargetInfo(self):
+ triple = self.getTriple()
+ parts = triple.split('-')
+ assert len(parts) == 3 or len(parts) == 4
+ info = TargetInfo(parts[0])
+ if len(parts) == 3:
+ if parts[1] in ['apple'] or parts[2] in ['linux']:
+ info.vendor = parts[1]
+ info.sys = parts[2]
+ else:
+ info.vendor = 'unknown'
+ info.sys = parts[1]
+ info.abi = parts[2]
+ if info.sys == 'linux':
+ info.abi = 'gnu'
+ else:
+ info.vendor = parts[1]
+ info.sys = parts[2]
+ info.abi = parts[3]
+ return info
+
+ kSearchDirsRe = re.compile('libraries: =([^\n]*)\n')
+
+ def getLibrarySearchPaths(self):
+ cmd = [self.path] + self.flags + ['-print-search-dirs']
+ out, err, rc = lit.util.executeCommand(cmd)
+ if rc != 0:
+ raise Exception()
+ match = CXXCompiler.kSearchDirsRe.search(out)
+ assert match is not None
+ dir_list = match.group(1).strip().split(':')
+ assert len(dir_list) != 0
+ return dir_list
Index: test/libcxx/test/config.py
===================================================================
--- test/libcxx/test/config.py
+++ test/libcxx/test/config.py
@@ -11,6 +11,7 @@
from libcxx.test.format import LibcxxTestFormat
from libcxx.compiler import CXXCompiler
+from libcxx.clang_utils import getClangLinkDriver
def loadSiteConfig(lit_config, config, param_name, env_name):
@@ -94,6 +95,7 @@
self.configure_link_flags()
self.configure_warnings()
self.configure_sanitizer()
+ self.configure_coverage()
self.configure_substitutions()
self.configure_features()
@@ -343,7 +345,9 @@
def configure_compile_flags_header_includes(self):
support_path = os.path.join(self.libcxx_src_root, 'test/support')
self.cxx.compile_flags += ['-I' + support_path]
- self.cxx.compile_flags += ['-include', os.path.join(support_path, 'nasty_macros.hpp')]
+ self.cxx.compile_flags += [
+ '-include', os.path.join(support_path, 'nasty_macros.hpp')
+ ]
libcxx_headers = self.get_lit_conf(
'libcxx_headers', os.path.join(self.libcxx_src_root, 'include'))
if not os.path.isdir(libcxx_headers):
@@ -462,8 +466,8 @@
enable_warnings = self.get_lit_bool('enable_warnings', False)
if enable_warnings:
self.cxx.compile_flags += ['-Wsystem-headers', '-Wall', '-Werror']
- if ('clang' in self.config.available_features or
- 'apple-clang' in self.config.available_features):
+ if ('clang' in self.config.available_features
+ or 'apple-clang' in self.config.available_features):
self.cxx.compile_flags += ['-Wno-user-defined-literals']
def configure_sanitizer(self):
@@ -481,18 +485,30 @@
symbolizer_search_paths)
# Setup the sanitizer compile flags
self.cxx.flags += ['-g', '-fno-omit-frame-pointer']
+ manual_link = ('darwin' in self.config.target_triple and
+ '-nodefaultlibs' in self.cxx.link_flags)
+ link_cxx = CXXCompiler(self.cxx.path, self.cxx.flags)
+ link_driver = getClangLinkDriver(link_cxx)
+ if manual_link:
+ self.cxx.link_flags += [
+ '-Wl,-rpath,' + link_driver.getClangLibraryDir()
+ ]
if sys.platform.startswith('linux'):
self.cxx.link_flags += ['-ldl']
if san == 'Address':
self.cxx.flags += ['-fsanitize=address']
if llvm_symbolizer is not None:
self.env['ASAN_SYMBOLIZER_PATH'] = llvm_symbolizer
+ if manual_link:
+ self.cxx.link_flags += link_driver.getASanLinkOptions()
self.config.available_features.add('asan')
elif san == 'Memory' or san == 'MemoryWithOrigins':
self.cxx.flags += ['-fsanitize=memory']
if san == 'MemoryWithOrigins':
self.cxx.compile_flags += [
'-fsanitize-memory-track-origins']
+ if manual_link:
+ self.cxx.link_flags += link_driver.getMSanLinkOptions()
if llvm_symbolizer is not None:
self.env['MSAN_SYMBOLIZER_PATH'] = llvm_symbolizer
self.config.available_features.add('msan')
@@ -501,14 +517,29 @@
'-fno-sanitize=vptr,function',
'-fno-sanitize-recover']
self.cxx.compile_flags += ['-O3']
+ if manual_link:
+ self.cxx.link_flags += link_driver.getUBSanLinkOptions()
self.config.available_features.add('ubsan')
elif san == 'Thread':
self.cxx.flags += ['-fsanitize=thread']
+ if manual_link:
+ self.cxx.link_flags += link_driver.getTSanLinkOptions()
self.config.available_features.add('tsan')
else:
self.lit_config.fatal('unsupported value for '
'use_sanitizer: {0}'.format(san))
+ def configure_coverage(self):
+ self.generate_coverage = self.get_lit_bool('generate_coverage', False)
+ if self.generate_coverage:
+ self.cxx.flags += ['-g', '--coverage']
+ self.cxx.compile_flags += ['-O0']
+ if '-nodefaultlibs' in self.cxx.link_flags:
+ other_cxx = CXXCompiler(self.cxx.path, self.cxx.flags)
+ link_driver = getClangLinkDriver(other_cxx)
+ self.cxx.link_flags = (link_driver.getProfileRTLinkOptions()
+ + self.cxx.link_flags)
+
def configure_substitutions(self):
sub = self.config.substitutions
# Configure compiler substitions
Index: test/lit.site.cfg.in
===================================================================
--- test/lit.site.cfg.in
+++ test/lit.site.cfg.in
@@ -17,6 +17,7 @@
config.target_triple = "@LIBCXX_TARGET_TRIPLE@"
config.sysroot = "@LIBCXX_SYSROOT@"
config.gcc_toolchain = "@LIBCXX_GCC_TOOLCHAIN@"
+config.generate_coverage = "@LIBCXX_GENERATE_COVERAGE@"
# Let the main config do the real work.
lit_config.load_config(config, "@LIBCXX_SOURCE_DIR@/test/lit.cfg")
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits