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:
Chandler Carruth 2012-08-07 08:33:04 +00:00
Родитель 5f8cfa76e8
Коммит f71b73d7a1
5 изменённых файлов: 51 добавлений и 221 удалений

4
CMakeLists.txt Normal file
Просмотреть файл

@ -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")

Просмотреть файл

@ -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.