blob: 512935c3ecb59c80d715c6ae47161fb6df7e68ba [file] [log] [blame]
Daniel Dunbar42ea4632010-09-15 03:57:04 +00001# -*- Python -*-
2
3# Configuration file for the 'lit' test runner.
4
5import os
Michael J. Spencerf5799be2010-12-10 19:47:54 +00006import sys
Daniel Dunbar42ea4632010-09-15 03:57:04 +00007import platform
8import tempfile
9import signal
10import subprocess
11
12class LibcxxTestFormat(lit.formats.FileBasedTest):
13 """
14 Custom test format handler for use with the test format use by libc++.
15
16 Tests fall into two categories:
17 FOO.pass.cpp - Executable test which should compile, run, and exit with
18 code 0.
19 FOO.fail.cpp - Negative test case which is expected to fail compilation.
20 """
21
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000022 def __init__(self, cxx_under_test, cpp_flags, ld_flags):
Daniel Dunbarbc9a8482010-09-15 04:11:29 +000023 self.cxx_under_test = cxx_under_test
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000024 self.cpp_flags = list(cpp_flags)
25 self.ld_flags = list(ld_flags)
Daniel Dunbar42ea4632010-09-15 03:57:04 +000026
27 def execute_command(self, command):
28 p = subprocess.Popen(command, stdin=subprocess.PIPE,
29 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
30 out,err = p.communicate()
31 exitCode = p.wait()
32
33 # Detect Ctrl-C in subprocess.
34 if exitCode == -signal.SIGINT:
35 raise KeyboardInterrupt
36
37 return out, err, exitCode
38
39 def execute(self, test, lit_config):
40 name = test.path_in_suite[-1]
41 source_path = test.getSourcePath()
42
43 # Check what kind of test this is.
44 assert name.endswith('.pass.cpp') or name.endswith('.fail.cpp')
45 expected_compile_fail = name.endswith('.fail.cpp')
46
47 # If this is a compile (failure) test, build it and check for failure.
48 if expected_compile_fail:
49 cmd = [self.cxx_under_test, '-c',
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000050 '-o', '/dev/null', source_path] + self.cpp_flags
Daniel Dunbar42ea4632010-09-15 03:57:04 +000051 out, err, exitCode = self.execute_command(cmd)
52 if exitCode == 1:
53 return lit.Test.PASS, ""
54 else:
55 report = """Command: %s\n""" % ' '.join(["'%s'" % a
56 for a in cmd])
57 report += """Exit Code: %d\n""" % exitCode
58 if out:
59 report += """Standard Output:\n--\n%s--""" % out
60 if err:
61 report += """Standard Error:\n--\n%s--""" % err
62 report += "\n\nExpected compilation to fail!"
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000063 return lit.Test.FAIL, report
Daniel Dunbar42ea4632010-09-15 03:57:04 +000064 else:
65 exec_file = tempfile.NamedTemporaryFile(suffix="exe", delete=False)
66 exec_path = exec_file.name
67 exec_file.close()
68
69 try:
Michael J. Spencerf5799be2010-12-10 19:47:54 +000070 compile_cmd = [self.cxx_under_test, '-o', exec_path,
Daniel Dunbar5f09d9e02010-09-15 04:31:58 +000071 source_path] + self.cpp_flags + self.ld_flags
Michael J. Spencerf5799be2010-12-10 19:47:54 +000072 cmd = compile_cmd
Daniel Dunbar42ea4632010-09-15 03:57:04 +000073 out, err, exitCode = self.execute_command(cmd)
74 if exitCode != 0:
Daniel Dunbar42ea4632010-09-15 03:57:04 +000075 report = """Command: %s\n""" % ' '.join(["'%s'" % a
76 for a in cmd])
77 report += """Exit Code: %d\n""" % exitCode
78 if out:
79 report += """Standard Output:\n--\n%s--""" % out
80 if err:
81 report += """Standard Error:\n--\n%s--""" % err
82 report += "\n\nCompilation failed unexpectedly!"
83 return lit.Test.FAIL, report
84
85 cmd = [exec_path]
Howard Hinnantc1a45fb2012-08-02 18:36:47 +000086 if lit_config.useValgrind:
87 cmd = lit_config.valgrindArgs + cmd
Daniel Dunbar42ea4632010-09-15 03:57:04 +000088 out, err, exitCode = self.execute_command(cmd)
89 if exitCode != 0:
Michael J. Spencerf5799be2010-12-10 19:47:54 +000090 report = """Compiled With: %s\n""" % ' '.join(["'%s'" % a
91 for a in compile_cmd])
92 report += """Command: %s\n""" % ' '.join(["'%s'" % a
Daniel Dunbar42ea4632010-09-15 03:57:04 +000093 for a in cmd])
94 report += """Exit Code: %d\n""" % exitCode
95 if out:
96 report += """Standard Output:\n--\n%s--""" % out
97 if err:
98 report += """Standard Error:\n--\n%s--""" % err
99 report += "\n\nCompiled test failed unexpectedly!"
100 return lit.Test.FAIL, report
101 finally:
102 try:
103 os.remove(exec_path)
104 except:
105 pass
106 return lit.Test.PASS, ""
107
108# name: The name of this test suite.
109config.name = 'libc++'
110
111# suffixes: A list of file extensions to treat as test files.
112config.suffixes = ['.cpp']
113
114# test_source_root: The root path where tests are located.
115config.test_source_root = os.path.dirname(__file__)
116
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000117# Gather various compiler parameters.
Daniel Dunbar42ea4632010-09-15 03:57:04 +0000118cxx_under_test = lit.params.get('cxx_under_test', None)
119if cxx_under_test is None:
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000120 cxx_under_test = getattr(config, 'cxx_under_test', None)
121 if cxx_under_test is None:
122 lit.fatal('must specify user parameter cxx_under_test '
123 '(e.g., --param=cxx_under_test=clang++)')
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000124
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000125libcxx_src_root = lit.params.get('libcxx_src_root', None)
126if libcxx_src_root is None:
127 libcxx_src_root = getattr(config, 'libcxx_src_root', None)
128 if libcxx_src_root is None:
129 libcxx_src_root = os.path.dirname(config.test_source_root)
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000130
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000131libcxx_obj_root = lit.params.get('libcxx_obj_root', None)
132if libcxx_obj_root is None:
133 libcxx_obj_root = getattr(config, 'libcxx_obj_root', None)
134 if libcxx_obj_root is None:
135 libcxx_obj_root = libcxx_src_root
136
137cxx_has_stdcxx0x_flag_str = lit.params.get('cxx_has_stdcxx0x_flag', None)
138if cxx_has_stdcxx0x_flag_str is not None:
139 if cxx_has_stdcxx0x_flag_str in ('1', 'True'):
140 cxx_has_stdcxx0x_flag = True
141 elif cxx_has_stdcxx0x_flag_str in ('', '0', 'False'):
142 cxx_has_stdcxx0x_flag = False
143 else:
144 lit.fatal('user parameter cxx_has_stdcxx0x_flag_str should be 0 or 1')
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000145else:
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000146 cxx_has_stdcxx0x_flag = getattr(config, 'cxx_has_stdcxx0x_flag', True)
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000147
Chandler Carruthce395a92011-01-23 01:05:20 +0000148# Configure extra compiler flags.
Howard Hinnantf1e633c2013-01-14 17:07:27 +0000149include_paths = ['-I' + libcxx_src_root + '/include', '-I' + libcxx_src_root + '/test/support']
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000150library_paths = ['-L' + libcxx_obj_root + '/lib']
Chandler Carruthce395a92011-01-23 01:05:20 +0000151compile_flags = []
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000152if cxx_has_stdcxx0x_flag:
Chandler Carruthce395a92011-01-23 01:05:20 +0000153 compile_flags += ['-std=c++0x']
154
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000155# Configure extra libraries.
156libraries = []
157if sys.platform == 'darwin':
158 libraries += ['-lSystem']
159if sys.platform == 'linux2':
Chandler Carruthce395a92011-01-23 01:05:20 +0000160 libraries += ['-lgcc_eh', '-lsupc++', '-lc', '-lm', '-lrt', '-lgcc_s']
Michael J. Spencerf5799be2010-12-10 19:47:54 +0000161 libraries += ['-Wl,-R', libcxx_obj_root + '/lib']
162
Daniel Dunbar7c4b8532012-11-27 23:56:28 +0000163config.test_format = LibcxxTestFormat(
164 cxx_under_test,
165 cpp_flags = ['-nostdinc++'] + compile_flags + include_paths,
166 ld_flags = ['-nodefaultlibs'] + library_paths + ['-lc++'] + libraries)
Daniel Dunbar42ea4632010-09-15 03:57:04 +0000167
168config.target_triple = None