From 118232f2b4e2aba344708b437385ba08b9ac4980 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Tue, 7 Aug 2012 08:33:04 +0000 Subject: [PATCH] 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. llvm-svn: 161404 --- clang-tools-extra/CMakeLists.txt | 4 + clang-tools-extra/test/CMakeLists.txt | 105 +++---------- clang-tools-extra/test/lit.cfg | 148 ++---------------- clang-tools-extra/test/lit.site.cfg.in | 4 +- .../test/remove-cstr-calls/basic.cpp | 11 +- 5 files changed, 51 insertions(+), 221 deletions(-) create mode 100644 clang-tools-extra/CMakeLists.txt diff --git a/clang-tools-extra/CMakeLists.txt b/clang-tools-extra/CMakeLists.txt new file mode 100644 index 000000000000..5876cb5c0402 --- /dev/null +++ b/clang-tools-extra/CMakeLists.txt @@ -0,0 +1,4 @@ +add_subdirectory(remove-cstr-calls) + +# Add the common testsuite after all the tools. +add_subdirectory(test) diff --git a/clang-tools-extra/test/CMakeLists.txt b/clang-tools-extra/test/CMakeLists.txt index 8184c3d3638a..b93f951405d9 100644 --- a/clang-tools-extra/test/CMakeLists.txt +++ b/clang-tools-extra/test/CMakeLists.txt @@ -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") diff --git a/clang-tools-extra/test/lit.cfg b/clang-tools-extra/test/lit.cfg index 1fc6059326d8..77a711287b68 100644 --- a/clang-tools-extra/test/lit.cfg +++ b/clang-tools-extra/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') diff --git a/clang-tools-extra/test/lit.site.cfg.in b/clang-tools-extra/test/lit.site.cfg.in index df90b81055f8..88aaa6c421c8 100644 --- a/clang-tools-extra/test/lit.site.cfg.in +++ b/clang-tools-extra/test/lit.site.cfg.in @@ -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") diff --git a/clang-tools-extra/test/remove-cstr-calls/basic.cpp b/clang-tools-extra/test/remove-cstr-calls/basic.cpp index 216441f40a5b..f0f5ed5b4ea1 100644 --- a/clang-tools-extra/test/remove-cstr-calls/basic.cpp +++ b/clang-tools-extra/test/remove-cstr-calls/basic.cpp @@ -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.