blob: d8023fd9e165f43d8875ac423d11cb95184f652c [file] [log] [blame]
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +00001# -*- Python -*-
2
3# Configuration file for the 'lit' test runner.
4
5import os
Michael J. Spencer626916f2010-12-10 19:47:54 +00006import sys
Daniel Dunbarf5eadcd2010-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 Dunbar611581b2010-09-15 04:31:58 +000022 def __init__(self, cxx_under_test, cpp_flags, ld_flags):
Daniel Dunbar7e0c57b2010-09-15 04:11:29 +000023 self.cxx_under_test = cxx_under_test
Daniel Dunbar611581b2010-09-15 04:31:58 +000024 self.cpp_flags = list(cpp_flags)
25 self.ld_flags = list(ld_flags)
Daniel Dunbarf5eadcd2010-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 Dunbar611581b2010-09-15 04:31:58 +000050 '-o', '/dev/null', source_path] + self.cpp_flags
Daniel Dunbarf5eadcd2010-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 Dunbar611581b2010-09-15 04:31:58 +000063 return lit.Test.FAIL, report
Daniel Dunbarf5eadcd2010-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. Spencer626916f2010-12-10 19:47:54 +000070 compile_cmd = [self.cxx_under_test, '-o', exec_path,
Daniel Dunbar611581b2010-09-15 04:31:58 +000071 source_path] + self.cpp_flags + self.ld_flags
Michael J. Spencer626916f2010-12-10 19:47:54 +000072 cmd = compile_cmd
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +000073 out, err, exitCode = self.execute_command(cmd)
74 if exitCode != 0:
Daniel Dunbarf5eadcd2010-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]
86 out, err, exitCode = self.execute_command(cmd)
87 if exitCode != 0:
Michael J. Spencer626916f2010-12-10 19:47:54 +000088 report = """Compiled With: %s\n""" % ' '.join(["'%s'" % a
89 for a in compile_cmd])
90 report += """Command: %s\n""" % ' '.join(["'%s'" % a
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +000091 for a in cmd])
92 report += """Exit Code: %d\n""" % exitCode
93 if out:
94 report += """Standard Output:\n--\n%s--""" % out
95 if err:
96 report += """Standard Error:\n--\n%s--""" % err
97 report += "\n\nCompiled test failed unexpectedly!"
98 return lit.Test.FAIL, report
99 finally:
100 try:
101 os.remove(exec_path)
102 except:
103 pass
104 return lit.Test.PASS, ""
105
106# name: The name of this test suite.
107config.name = 'libc++'
108
109# suffixes: A list of file extensions to treat as test files.
110config.suffixes = ['.cpp']
111
112# test_source_root: The root path where tests are located.
113config.test_source_root = os.path.dirname(__file__)
114
115# FIXME: Would be nice to Use -stdlib=libc++ option with Clang's that accept it.
116cxx_under_test = lit.params.get('cxx_under_test', None)
117if cxx_under_test is None:
Michael J. Spencer626916f2010-12-10 19:47:54 +0000118 cxx_under_test = getattr(config, 'cxx_under_test', None)
119 if cxx_under_test is None:
120 lit.fatal('must specify user parameter cxx_under_test '
121 '(e.g., --param=cxx_under_test=clang++)')
122include_paths = []
123library_paths = []
124
125libcxx_src_root = getattr(config, 'libcxx_src_root', None)
126if libcxx_src_root is not None:
127 include_paths += ['-I' + libcxx_src_root + '/include']
128else:
129 include_paths += ['-I/usr/include/c++/v1']
130
131libcxx_obj_root = getattr(config, 'libcxx_obj_root', None)
132if libcxx_obj_root is not None:
133 library_paths += ['-L' + libcxx_obj_root + '/lib']
134else:
135 libcxx_obj_root = "/usr"
136
Chandler Carruthe76496c2011-01-23 01:05:20 +0000137# Configure extra compiler flags.
138compile_flags = []
139if getattr(config, 'cxx_has_stdcxx0x_flag', False):
140 compile_flags += ['-std=c++0x']
141
Michael J. Spencer626916f2010-12-10 19:47:54 +0000142# Configure extra libraries.
143libraries = []
144if sys.platform == 'darwin':
145 libraries += ['-lSystem']
146if sys.platform == 'linux2':
Chandler Carruthe76496c2011-01-23 01:05:20 +0000147 libraries += ['-lgcc_eh', '-lsupc++', '-lc', '-lm', '-lrt', '-lgcc_s']
Michael J. Spencer626916f2010-12-10 19:47:54 +0000148 libraries += ['-Wl,-R', libcxx_obj_root + '/lib']
149
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000150config.test_format = LibcxxTestFormat(cxx_under_test,
Chandler Carruthe76496c2011-01-23 01:05:20 +0000151 cpp_flags = ['-nostdinc++'] + compile_flags + include_paths,
Michael J. Spencer626916f2010-12-10 19:47:54 +0000152 ld_flags = ['-nodefaultlibs'] + library_paths + ['-lc++'] + libraries)
Daniel Dunbarf5eadcd2010-09-15 03:57:04 +0000153
154config.target_triple = None