Add a root CMakeLists.txt and fix up all the test build stuff.
With this we can build and test the remove-cstr-calls tool which should serve as a good example of how to add tools and their tests to the repository. git-svn-id: https://llvm.org/svn/llvm-project/clang-tools-extra/trunk@161404 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
5f8cfa76e8
Коммит
f71b73d7a1
|
@ -0,0 +1,4 @@
|
|||
add_subdirectory(remove-cstr-calls)
|
||||
|
||||
# Add the common testsuite after all the tools.
|
||||
add_subdirectory(test)
|
|
@ -1,93 +1,34 @@
|
|||
# Test runner infrastructure for Clang. This configures the Clang test trees
|
||||
# for use by Lit, and delegates to LLVM's lit test handlers.
|
||||
# Test runner infrastructure for Clang-based tools. This configures the Clang
|
||||
# test trees for use by Lit, and delegates to LLVM's lit test handlers.
|
||||
#
|
||||
# If this is a stand-alone Clang build, we fake up our own Lit support here
|
||||
# rather than relying on LLVM's.
|
||||
# Note that currently we don't support stand-alone builds of Clang, you must
|
||||
# be building Clang from within a combined LLVM+Clang checkout..
|
||||
|
||||
set(CLANG_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
set(CLANG_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..")
|
||||
set(CLANG_TOOLS_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
set(CLANG_TOOLS_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/..")
|
||||
|
||||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
|
||||
)
|
||||
|
||||
configure_lit_site_cfg(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
|
||||
option(CLANG_TOOLS_TEST_USE_VG "Run Clang tools' tests under Valgrind" OFF)
|
||||
if(CLANG_TOOLS_TEST_USE_VG)
|
||||
set(CLANG_TOOLS_TEST_EXTRA_ARGS ${CLANG_TEST_EXTRA_ARGS} "--vg")
|
||||
endif()
|
||||
|
||||
set(CLANG_TOOLS_TEST_DEPS
|
||||
# Base line deps.
|
||||
clang clang-headers FileCheck count not
|
||||
|
||||
# Individual tools we test.
|
||||
remove-cstr-calls
|
||||
)
|
||||
|
||||
if( PATH_TO_LLVM_BUILD )
|
||||
set(CLANG_TEST_EXTRA_ARGS "--path=${CLANG_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}")
|
||||
endif()
|
||||
add_lit_testsuite(check-clang-tools "Running the Clang extra tools' regression tests"
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
DEPENDS ${CLANG_TOOLS_TEST_DEPS}
|
||||
ARGS ${CLANG_TOOLS_TEST_EXTRA_ARGS}
|
||||
)
|
||||
set_target_properties(check-clang-tools PROPERTIES FOLDER "Clang extra tools' tests")
|
||||
|
||||
option(CLANG_TEST_USE_VG "Run Clang tests under Valgrind" OFF)
|
||||
if(CLANG_TEST_USE_VG)
|
||||
set(CLANG_TEST_EXTRA_ARGS ${CLANG_TEST_EXTRA_ARGS} "--vg")
|
||||
endif ()
|
||||
|
||||
if( NOT CLANG_BUILT_STANDALONE )
|
||||
|
||||
set(CLANG_TEST_DEPS
|
||||
clang clang-headers
|
||||
c-index-test diagtool arcmt-test c-arcmt-test
|
||||
clang-check
|
||||
llvm-dis llc opt FileCheck count not
|
||||
)
|
||||
set(CLANG_TEST_PARAMS
|
||||
clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
|
||||
)
|
||||
|
||||
if(LLVM_INCLUDE_TESTS)
|
||||
list(APPEND CLANG_TEST_DEPS ClangUnitTests)
|
||||
list(APPEND CLANG_TEST_PARAMS
|
||||
clang_unit_site_config=${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg
|
||||
)
|
||||
endif()
|
||||
add_lit_testsuite(check-clang "Running the Clang regression tests"
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
PARAMS ${CLANG_TEST_PARAMS}
|
||||
DEPENDS ${CLANG_TEST_DEPS}
|
||||
ARGS ${CLANG_TEST_EXTRA_ARGS}
|
||||
)
|
||||
set_target_properties(check-clang PROPERTIES FOLDER "Clang tests")
|
||||
|
||||
else()
|
||||
|
||||
include(FindPythonInterp)
|
||||
if(PYTHONINTERP_FOUND)
|
||||
if( LLVM_MAIN_SRC_DIR )
|
||||
set(LIT "${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py")
|
||||
else()
|
||||
set(LIT "${PATH_TO_LLVM_BUILD}/bin/${CMAKE_CFG_INTDIR}/llvm-lit")
|
||||
# Installed LLVM does not contain ${CMAKE_CFG_INTDIR} in paths.
|
||||
if( NOT EXISTS ${LIT} )
|
||||
set(LIT "${PATH_TO_LLVM_BUILD}/bin/llvm-lit")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
set(LIT_ARGS "${CLANG_TEST_EXTRA_ARGS} ${LLVM_LIT_ARGS}")
|
||||
separate_arguments(LIT_ARGS)
|
||||
|
||||
add_custom_target(check-clang
|
||||
COMMAND ${PYTHON_EXECUTABLE}
|
||||
${LIT}
|
||||
--param clang_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg
|
||||
--param build_config=${CMAKE_CFG_INTDIR}
|
||||
--param build_mode=${RUNTIME_BUILD_MODE}
|
||||
${LIT_ARGS}
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
COMMENT "Running Clang regression tests"
|
||||
DEPENDS clang clang-headers
|
||||
c-index-test diagtool arcmt-test c-arcmt-test
|
||||
clang-check
|
||||
)
|
||||
set_target_properties(check-clang PROPERTIES FOLDER "Clang tests")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
# Add a legacy target spelling: clang-test
|
||||
add_custom_target(clang-test)
|
||||
add_dependencies(clang-test check-clang)
|
||||
set_target_properties(clang-test PROPERTIES FOLDER "Clang tests")
|
||||
|
|
148
test/lit.cfg
148
test/lit.cfg
|
@ -9,7 +9,7 @@ import subprocess
|
|||
# Configuration file for the 'lit' test runner.
|
||||
|
||||
# name: The name of this test suite.
|
||||
config.name = 'Clang'
|
||||
config.name = 'Clang Tools'
|
||||
|
||||
# Tweak PATH for Win32
|
||||
if platform.system() == 'Windows':
|
||||
|
@ -38,13 +38,10 @@ config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s']
|
|||
config.test_source_root = os.path.dirname(__file__)
|
||||
|
||||
# test_exec_root: The root path where tests should be run.
|
||||
clang_obj_root = getattr(config, 'clang_obj_root', None)
|
||||
if clang_obj_root is not None:
|
||||
config.test_exec_root = os.path.join(clang_obj_root, 'test')
|
||||
|
||||
# Set llvm_{src,obj}_root for use by others.
|
||||
config.llvm_src_root = getattr(config, 'llvm_src_root', None)
|
||||
config.llvm_obj_root = getattr(config, 'llvm_obj_root', None)
|
||||
clang_tools_binary_dir = getattr(config, 'clang_tools_binary_dir', None)
|
||||
if not clang_tools_binary_dir:
|
||||
lit.fatal('No Clang tools binary dir set!')
|
||||
config.test_exec_root = os.path.join(clang_tools_binary_dir, 'test')
|
||||
|
||||
# Clear some environment variables that might affect Clang.
|
||||
#
|
||||
|
@ -76,101 +73,27 @@ for name in possibly_dangerous_env_vars:
|
|||
del config.environment[name]
|
||||
|
||||
# Tweak the PATH to include the tools dir and the scripts dir.
|
||||
if clang_obj_root is not None:
|
||||
llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
|
||||
if not llvm_tools_dir:
|
||||
lit.fatal('No LLVM tools dir set!')
|
||||
path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
|
||||
config.environment['PATH'] = path
|
||||
llvm_tools_dir = getattr(config, 'llvm_tools_dir', None)
|
||||
if not llvm_tools_dir:
|
||||
lit.fatal('No LLVM tools dir set!')
|
||||
path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH']))
|
||||
config.environment['PATH'] = path
|
||||
|
||||
llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
|
||||
if not llvm_libs_dir:
|
||||
lit.fatal('No LLVM libs dir set!')
|
||||
path = os.path.pathsep.join((llvm_libs_dir,
|
||||
config.environment.get('LD_LIBRARY_PATH','')))
|
||||
config.environment['LD_LIBRARY_PATH'] = path
|
||||
llvm_libs_dir = getattr(config, 'llvm_libs_dir', None)
|
||||
if not llvm_libs_dir:
|
||||
lit.fatal('No LLVM libs dir set!')
|
||||
path = os.path.pathsep.join((llvm_libs_dir,
|
||||
config.environment.get('LD_LIBRARY_PATH','')))
|
||||
config.environment['LD_LIBRARY_PATH'] = path
|
||||
|
||||
###
|
||||
|
||||
# Check that the object root is known.
|
||||
if config.test_exec_root is None:
|
||||
# Otherwise, we haven't loaded the site specific configuration (the user is
|
||||
# probably trying to run on a test file directly, and either the site
|
||||
# configuration hasn't been created by the build system, or we are in an
|
||||
# out-of-tree build situation).
|
||||
|
||||
# Check for 'clang_site_config' user parameter, and use that if available.
|
||||
site_cfg = lit.params.get('clang_site_config', None)
|
||||
if site_cfg and os.path.exists(site_cfg):
|
||||
lit.load_config(config, site_cfg)
|
||||
raise SystemExit
|
||||
|
||||
# Try to detect the situation where we are using an out-of-tree build by
|
||||
# looking for 'llvm-config'.
|
||||
#
|
||||
# FIXME: I debated (i.e., wrote and threw away) adding logic to
|
||||
# automagically generate the lit.site.cfg if we are in some kind of fresh
|
||||
# build situation. This means knowing how to invoke the build system though,
|
||||
# and I decided it was too much magic. We should solve this by just having
|
||||
# the .cfg files generated during the configuration step.
|
||||
|
||||
llvm_config = lit.util.which('llvm-config', config.environment['PATH'])
|
||||
if not llvm_config:
|
||||
lit.fatal('No site specific configuration available!')
|
||||
|
||||
# Get the source and object roots.
|
||||
llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip()
|
||||
llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip()
|
||||
clang_src_root = os.path.join(llvm_src_root, "tools", "clang")
|
||||
clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang")
|
||||
|
||||
# Validate that we got a tree which points to here, using the standard
|
||||
# tools/clang layout.
|
||||
this_src_root = os.path.dirname(config.test_source_root)
|
||||
if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root):
|
||||
lit.fatal('No site specific configuration available!')
|
||||
|
||||
# Check that the site specific configuration exists.
|
||||
site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg')
|
||||
if not os.path.exists(site_cfg):
|
||||
lit.fatal('No site specific configuration available! You may need to '
|
||||
'run "make test" in your Clang build directory.')
|
||||
|
||||
# Okay, that worked. Notify the user of the automagic, and reconfigure.
|
||||
lit.note('using out-of-tree build at %r' % clang_obj_root)
|
||||
lit.load_config(config, site_cfg)
|
||||
raise SystemExit
|
||||
|
||||
###
|
||||
|
||||
# Discover the 'clang' and 'clangcc' to use.
|
||||
|
||||
import os
|
||||
|
||||
def inferClang(PATH):
|
||||
# Determine which clang to use.
|
||||
clang = os.getenv('CLANG')
|
||||
|
||||
# If the user set clang in the environment, definitely use that and don't
|
||||
# try to validate.
|
||||
if clang:
|
||||
return clang
|
||||
|
||||
# Otherwise look in the path.
|
||||
clang = lit.util.which('clang', PATH)
|
||||
|
||||
if not clang:
|
||||
lit.fatal("couldn't find 'clang' program, try setting "
|
||||
"CLANG in your environment")
|
||||
|
||||
return clang
|
||||
|
||||
# When running under valgrind, we mangle '-vg' onto the end of the triple so we
|
||||
# can check it with XFAIL and XTARGET.
|
||||
if lit.useValgrind:
|
||||
config.target_triple += '-vg'
|
||||
|
||||
config.clang = inferClang(config.environment['PATH']).replace('\\', '/')
|
||||
config.clang = llvm_tools_dir + "/clang"
|
||||
if not lit.quiet:
|
||||
lit.note('using clang: %r' % config.clang)
|
||||
|
||||
|
@ -178,8 +101,6 @@ if not lit.quiet:
|
|||
# the builtin headers. Those are part of even a freestanding environment, but
|
||||
# Clang relies on the driver to locate them.
|
||||
def getClangBuiltinIncludeDir(clang):
|
||||
# FIXME: Rather than just getting the version, we should have clang print
|
||||
# out its resource dir here in an easy to scrape form.
|
||||
cmd = subprocess.Popen([clang, '-print-file-name=include'],
|
||||
stdout=subprocess.PIPE)
|
||||
if not cmd.stdout:
|
||||
|
@ -193,7 +114,6 @@ config.substitutions.append( ('%clang_cc1', '%s -cc1 -internal-isystem %s'
|
|||
config.substitutions.append( ('%clangxx', ' ' + config.clang +
|
||||
' -ccc-clang-cxx -ccc-cxx '))
|
||||
config.substitutions.append( ('%clang', ' ' + config.clang + ' ') )
|
||||
config.substitutions.append( ('%test_debuginfo', ' ' + config.llvm_src_root + '/utils/test_debuginfo.pl ') )
|
||||
|
||||
# FIXME: Find nicer way to prohibit this.
|
||||
config.substitutions.append(
|
||||
|
@ -225,37 +145,3 @@ if platform.system() not in ['Windows'] or lit.getBashPath() != '':
|
|||
# ANSI escape sequences in non-dump terminal
|
||||
if platform.system() not in ['Windows']:
|
||||
config.available_features.add('ansi-escape-sequences')
|
||||
|
||||
# Registered Targets
|
||||
def get_llc_props(tool):
|
||||
set_of_targets = set()
|
||||
enable_assertions = False
|
||||
|
||||
cmd = subprocess.Popen([tool, '-version'], stdout=subprocess.PIPE)
|
||||
|
||||
# Parse the stdout to get the list of registered targets.
|
||||
parse_targets = False
|
||||
for line in cmd.stdout:
|
||||
if parse_targets:
|
||||
m = re.match( r'(.*) - ', line)
|
||||
if m is not None:
|
||||
set_of_targets.add(m.group(1).strip() + '-registered-target')
|
||||
else:
|
||||
break
|
||||
elif "Registered Targets:" in line:
|
||||
parse_targets = True
|
||||
|
||||
if re.search(r'with assertions', line):
|
||||
enable_assertions = True
|
||||
|
||||
return {"set_of_targets": set_of_targets,
|
||||
"enable_assertions": enable_assertions}
|
||||
|
||||
llc_props = get_llc_props(os.path.join(llvm_tools_dir, 'llc'))
|
||||
if len(llc_props['set_of_targets']) > 0:
|
||||
config.available_features.update(llc_props['set_of_targets'])
|
||||
else:
|
||||
lit.fatal('No Targets Registered with the LLVM Tools!')
|
||||
|
||||
if llc_props['enable_assertions']:
|
||||
config.available_features.add('asserts')
|
||||
|
|
|
@ -5,7 +5,7 @@ config.llvm_obj_root = "@LLVM_BINARY_DIR@"
|
|||
config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
|
||||
config.llvm_libs_dir = "@LLVM_LIBS_DIR@"
|
||||
config.lit_tools_dir = "@LLVM_LIT_TOOLS_DIR@"
|
||||
config.clang_obj_root = "@CLANG_BINARY_DIR@"
|
||||
config.clang_tools_binary_dir = "@CLANG_TOOLS_BINARY_DIR@"
|
||||
config.target_triple = "@TARGET_TRIPLE@"
|
||||
|
||||
# Support substitution of the tools and libs dirs with user parameters. This is
|
||||
|
@ -18,4 +18,4 @@ except KeyError,e:
|
|||
lit.fatal("unable to find %r parameter, use '--param=%s=VALUE'" % (key,key))
|
||||
|
||||
# Let the main config do the real work.
|
||||
lit.load_config(config, "@CLANG_SOURCE_DIR@/test/lit.cfg")
|
||||
lit.load_config(config, "@CLANG_TOOLS_SOURCE_DIR@/test/lit.cfg")
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
// RUN: rm -rf %t
|
||||
// RUN: mkdir %t
|
||||
// RUN: echo '[{"directory":".","command":"clang++ -c %t/test.cpp","file":"%t/test.cpp"}]' > %t/compile_commands.json
|
||||
// RUN: cp "%s" "%t/test.cpp"
|
||||
// RUN: remove-cstr-calls "%t" "%t/test.cpp"
|
||||
// RUN: cat "%t/test.cpp" | FileCheck %s
|
||||
// RUN: echo '[{"directory":".","command":"clang++ -c %T/test.cpp","file":"%T/test.cpp"}]' > %T/compile_commands.json
|
||||
// RUN: cp "%s" "%T/test.cpp"
|
||||
// RUN: remove-cstr-calls "%T" "%T/test.cpp"
|
||||
// RUN: cat "%T/test.cpp" | FileCheck %s
|
||||
// REQUIRES: shell
|
||||
// FIXME: implement a mode for refactoring tools that takes input from stdin
|
||||
// and writes output to stdout for easier testing of tools.
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче