1# -*- Python -*- 2 3import os 4import platform 5import re 6import subprocess 7 8 9# Configuration file for the 'lit' test runner. 10 11# name: The name of this test suite. 12config.name = 'Clang' 13 14# Tweak PATH for Win32 15if platform.system() == 'Windows': 16 # Seek sane tools in directories and set to $PATH. 17 path = getattr(config, 'lit_tools_dir', None) 18 path = lit.getToolsPath(path, 19 config.environment['PATH'], 20 ['cmp.exe', 'grep.exe', 'sed.exe']) 21 if path is not None: 22 path = os.path.pathsep.join((path, 23 config.environment['PATH'])) 24 config.environment['PATH'] = path 25 26# testFormat: The test format to use to interpret tests. 27# 28# For now we require '&&' between commands, until they get globally killed and 29# the test runner updated. 30execute_external = (platform.system() != 'Windows' 31 or lit.getBashPath() not in [None, ""]) 32config.test_format = lit.formats.ShTest(execute_external) 33 34# suffixes: A list of file extensions to treat as test files. 35config.suffixes = ['.c', '.cpp', '.m', '.mm', '.cu', '.ll', '.cl', '.s'] 36 37# test_source_root: The root path where tests are located. 38config.test_source_root = os.path.dirname(__file__) 39 40# test_exec_root: The root path where tests should be run. 41clang_obj_root = getattr(config, 'clang_obj_root', None) 42if clang_obj_root is not None: 43 config.test_exec_root = os.path.join(clang_obj_root, 'test') 44 45# Set llvm_{src,obj}_root for use by others. 46config.llvm_src_root = getattr(config, 'llvm_src_root', None) 47config.llvm_obj_root = getattr(config, 'llvm_obj_root', None) 48 49# Clear some environment variables that might affect Clang. 50# 51# This first set of vars are read by Clang, but shouldn't affect tests 52# that aren't specifically looking for these features, or are required 53# simply to run the tests at all. 54# 55# FIXME: Should we have a tool that enforces this? 56 57# safe_env_vars = ('TMPDIR', 'TEMP', 'TMP', 'USERPROFILE', 'PWD', 58# 'MACOSX_DEPLOYMENT_TARGET', 'IPHONEOS_DEPLOYMENT_TARGET', 59# 'IOS_SIMULATOR_DEPLOYMENT_TARGET', 60# 'VCINSTALLDIR', 'VC100COMNTOOLS', 'VC90COMNTOOLS', 61# 'VC80COMNTOOLS') 62possibly_dangerous_env_vars = ['COMPILER_PATH', 'RC_DEBUG_OPTIONS', 63 'CINDEXTEST_PREAMBLE_FILE', 'LIBRARY_PATH', 64 'CPATH', 'C_INCLUDE_PATH', 'CPLUS_INCLUDE_PATH', 65 'OBJC_INCLUDE_PATH', 'OBJCPLUS_INCLUDE_PATH', 66 'LIBCLANG_TIMING', 'LIBCLANG_OBJTRACKING', 67 'LIBCLANG_LOGGING', 'LIBCLANG_BGPRIO_INDEX', 68 'LIBCLANG_BGPRIO_EDIT', 'LIBCLANG_NOTHREADS', 69 'LIBCLANG_RESOURCE_USAGE', 70 'LIBCLANG_CODE_COMPLETION_LOGGING'] 71# Clang/Win32 may refer to %INCLUDE%. vsvarsall.bat sets it. 72if platform.system() != 'Windows': 73 possibly_dangerous_env_vars.append('INCLUDE') 74for name in possibly_dangerous_env_vars: 75 if name in config.environment: 76 del config.environment[name] 77 78# Tweak the PATH to include the tools dir and the scripts dir. 79if clang_obj_root is not None: 80 llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) 81 if not llvm_tools_dir: 82 lit.fatal('No LLVM tools dir set!') 83 path = os.path.pathsep.join((llvm_tools_dir, config.environment['PATH'])) 84 config.environment['PATH'] = path 85 86 llvm_libs_dir = getattr(config, 'llvm_libs_dir', None) 87 if not llvm_libs_dir: 88 lit.fatal('No LLVM libs dir set!') 89 path = os.path.pathsep.join((llvm_libs_dir, 90 config.environment.get('LD_LIBRARY_PATH',''))) 91 config.environment['LD_LIBRARY_PATH'] = path 92 93### 94 95# Check that the object root is known. 96if config.test_exec_root is None: 97 # Otherwise, we haven't loaded the site specific configuration (the user is 98 # probably trying to run on a test file directly, and either the site 99 # configuration hasn't been created by the build system, or we are in an 100 # out-of-tree build situation). 101 102 # Check for 'clang_site_config' user parameter, and use that if available. 103 site_cfg = lit.params.get('clang_site_config', None) 104 if site_cfg and os.path.exists(site_cfg): 105 lit.load_config(config, site_cfg) 106 raise SystemExit 107 108 # Try to detect the situation where we are using an out-of-tree build by 109 # looking for 'llvm-config'. 110 # 111 # FIXME: I debated (i.e., wrote and threw away) adding logic to 112 # automagically generate the lit.site.cfg if we are in some kind of fresh 113 # build situation. This means knowing how to invoke the build system though, 114 # and I decided it was too much magic. We should solve this by just having 115 # the .cfg files generated during the configuration step. 116 117 llvm_config = lit.util.which('llvm-config', config.environment['PATH']) 118 if not llvm_config: 119 lit.fatal('No site specific configuration available!') 120 121 # Get the source and object roots. 122 llvm_src_root = lit.util.capture(['llvm-config', '--src-root']).strip() 123 llvm_obj_root = lit.util.capture(['llvm-config', '--obj-root']).strip() 124 clang_src_root = os.path.join(llvm_src_root, "tools", "clang") 125 clang_obj_root = os.path.join(llvm_obj_root, "tools", "clang") 126 127 # Validate that we got a tree which points to here, using the standard 128 # tools/clang layout. 129 this_src_root = os.path.dirname(config.test_source_root) 130 if os.path.realpath(clang_src_root) != os.path.realpath(this_src_root): 131 lit.fatal('No site specific configuration available!') 132 133 # Check that the site specific configuration exists. 134 site_cfg = os.path.join(clang_obj_root, 'test', 'lit.site.cfg') 135 if not os.path.exists(site_cfg): 136 lit.fatal('No site specific configuration available! You may need to ' 137 'run "make test" in your Clang build directory.') 138 139 # Okay, that worked. Notify the user of the automagic, and reconfigure. 140 lit.note('using out-of-tree build at %r' % clang_obj_root) 141 lit.load_config(config, site_cfg) 142 raise SystemExit 143 144### 145 146# Discover the 'clang' and 'clangcc' to use. 147 148import os 149 150def inferClang(PATH): 151 # Determine which clang to use. 152 clang = os.getenv('CLANG') 153 154 # If the user set clang in the environment, definitely use that and don't 155 # try to validate. 156 if clang: 157 return clang 158 159 # Otherwise look in the path. 160 clang = lit.util.which('clang', PATH) 161 162 if not clang: 163 lit.fatal("couldn't find 'clang' program, try setting " 164 "CLANG in your environment") 165 166 return clang 167 168# When running under valgrind, we mangle '-vg' onto the end of the triple so we 169# can check it with XFAIL and XTARGET. 170if lit.useValgrind: 171 config.target_triple += '-vg' 172 173config.clang = inferClang(config.environment['PATH']).replace('\\', '/') 174if not lit.quiet: 175 lit.note('using clang: %r' % config.clang) 176 177# Note that when substituting %clang_cc1 also fill in the include directory of 178# the builtin headers. Those are part of even a freestanding environment, but 179# Clang relies on the driver to locate them. 180def getClangBuiltinIncludeDir(clang): 181 # FIXME: Rather than just getting the version, we should have clang print 182 # out its resource dir here in an easy to scrape form. 183 cmd = subprocess.Popen([clang, '-print-file-name=include'], 184 stdout=subprocess.PIPE) 185 if not cmd.stdout: 186 lit.fatal("Couldn't find the include dir for Clang ('%s')" % clang) 187 return cmd.stdout.read().strip() 188 189config.substitutions.append( ('%clang_cc1', '%s -cc1 -internal-isystem %s' 190 % (config.clang, 191 getClangBuiltinIncludeDir(config.clang))) ) 192 193config.substitutions.append( ('%clangxx', ' ' + config.clang + 194 ' -ccc-clang-cxx -ccc-cxx ')) 195config.substitutions.append( ('%clang', ' ' + config.clang + ' ') ) 196config.substitutions.append( ('%test_debuginfo', ' ' + config.llvm_src_root + '/utils/test_debuginfo.pl ') ) 197 198# FIXME: Find nicer way to prohibit this. 199config.substitutions.append( 200 (' clang ', """*** Do not use 'clang' in tests, use '%clang'. ***""") ) 201config.substitutions.append( 202 (' clang\+\+ ', """*** Do not use 'clang++' in tests, use '%clangxx'. ***""")) 203config.substitutions.append( 204 (' clang-cc ', 205 """*** Do not use 'clang-cc' in tests, use '%clang_cc1'. ***""") ) 206config.substitutions.append( 207 (' clang -cc1 ', 208 """*** Do not use 'clang -cc1' in tests, use '%clang_cc1'. ***""") ) 209config.substitutions.append( 210 (' %clang-cc1 ', 211 """*** invalid substitution, use '%clang_cc1'. ***""") ) 212 213### 214 215# Set available features we allow tests to conditionalize on. 216# 217# As of 2011.08, crash-recovery tests still do not pass on FreeBSD. 218if platform.system() not in ['FreeBSD']: 219 config.available_features.add('crash-recovery') 220 221# Shell execution 222if platform.system() not in ['Windows'] or lit.getBashPath() != '': 223 config.available_features.add('shell') 224 225# Registered Targets 226def get_llc_props(tool): 227 set_of_targets = set() 228 enable_assertions = False 229 230 cmd = subprocess.Popen([tool, '-version'], stdout=subprocess.PIPE) 231 232 # Parse the stdout to get the list of registered targets. 233 parse_targets = False 234 for line in cmd.stdout: 235 if parse_targets: 236 m = re.match( r'(.*) - ', line) 237 if m is not None: 238 set_of_targets.add(m.group(1).strip() + '-registered-target') 239 else: 240 break 241 elif "Registered Targets:" in line: 242 parse_targets = True 243 244 if re.search(r'with assertions', line): 245 enable_assertions = True 246 247 return {"set_of_targets": set_of_targets, 248 "enable_assertions": enable_assertions} 249 250llc_props = get_llc_props(os.path.join(llvm_tools_dir, 'llc')) 251if len(llc_props['set_of_targets']) > 0: 252 config.available_features.update(llc_props['set_of_targets']) 253else: 254 lit.fatal('No Targets Registered with the LLVM Tools!') 255 256if llc_props['enable_assertions']: 257 config.available_features.add('asserts') 258