| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 1 | #!/usr/bin/env python | 
|  | 2 | # | 
|  | 3 | #                     The LLVM Compiler Infrastructure | 
|  | 4 | # | 
|  | 5 | # This file is distributed under the University of Illinois Open Source | 
|  | 6 | # License. See LICENSE.TXT for details. | 
|  | 7 | # | 
|  | 8 | ##===----------------------------------------------------------------------===## | 
|  | 9 | # | 
|  | 10 | # This script attempts to be a drop-in replacement for gcc. | 
|  | 11 | # | 
|  | 12 | ##===----------------------------------------------------------------------===## | 
|  | 13 |  | 
|  | 14 | import sys | 
| Anders Carlsson | dac2b54 | 2008-02-06 19:03:27 +0000 | [diff] [blame] | 15 | import subprocess | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 16 |  | 
|  | 17 | def error(message): | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 18 | print >> sys.stderr, 'ccc: ' + message | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 19 | sys.exit(1) | 
|  | 20 |  | 
| Seo Sanghyeon | d389465 | 2008-04-04 11:02:21 +0000 | [diff] [blame] | 21 | def quote(arg): | 
|  | 22 | if '"' in arg: | 
|  | 23 | return repr(arg) | 
|  | 24 | return arg | 
|  | 25 |  | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 26 | def run(args): | 
| Seo Sanghyeon | d389465 | 2008-04-04 11:02:21 +0000 | [diff] [blame] | 27 | print ' '.join(map(quote, args)) | 
| Anders Carlsson | dac2b54 | 2008-02-06 19:03:27 +0000 | [diff] [blame] | 28 | code = subprocess.call(args) | 
| Bill Wendling | 550ce0f | 2008-02-03 21:27:46 +0000 | [diff] [blame] | 29 | if code > 255: | 
|  | 30 | code = 1 | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 31 | if code: | 
|  | 32 | sys.exit(code) | 
|  | 33 |  | 
|  | 34 | def preprocess(args): | 
| Anders Carlsson | dac2b54 | 2008-02-06 19:03:27 +0000 | [diff] [blame] | 35 | command = 'clang -E'.split() | 
|  | 36 | run(command + args) | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 37 |  | 
|  | 38 | def compile(args): | 
| Anders Carlsson | dac2b54 | 2008-02-06 19:03:27 +0000 | [diff] [blame] | 39 | command = 'clang -emit-llvm-bc'.split() | 
|  | 40 | run(command + args) | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 41 |  | 
|  | 42 | def link(args): | 
| Lauro Ramos Venancio | de808ca | 2008-02-27 18:46:32 +0000 | [diff] [blame] | 43 | command = 'llvm-ld -native -disable-internalize'.split() | 
| Anders Carlsson | dac2b54 | 2008-02-06 19:03:27 +0000 | [diff] [blame] | 44 | run(command + args) | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 45 |  | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 46 | def extension(path): | 
| Seo Sanghyeon | 795aaed | 2008-02-03 03:40:41 +0000 | [diff] [blame] | 47 | return path.split(".")[-1] | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 48 |  | 
|  | 49 | def changeextension(path, newext): | 
| Seo Sanghyeon | 795aaed | 2008-02-03 03:40:41 +0000 | [diff] [blame] | 50 | i = path.rfind('.') | 
|  | 51 | if i < 0: | 
|  | 52 | return path | 
| Bill Wendling | 550ce0f | 2008-02-03 21:27:46 +0000 | [diff] [blame] | 53 | j = path.rfind('/', 0, i) | 
|  | 54 | print path | 
|  | 55 | if j < 0: | 
|  | 56 | return path[:i] + "." + newext | 
|  | 57 | return path[j+1:i] + "." + newext | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 58 |  | 
|  | 59 | def inferlanguage(extension): | 
|  | 60 | if extension == "c": | 
|  | 61 | return "c" | 
| Lauro Ramos Venancio | 279876b | 2008-02-15 22:35:25 +0000 | [diff] [blame] | 62 | elif extension in ["cpp", "cc"]: | 
|  | 63 | return "c++" | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 64 | elif extension == "i": | 
|  | 65 | return "c-cpp-output" | 
|  | 66 | elif extension == "m": | 
|  | 67 | return "objective-c" | 
|  | 68 | elif extension == "mi": | 
|  | 69 | return "objective-c-cpp-output" | 
|  | 70 | else: | 
|  | 71 | return "unknown" | 
|  | 72 |  | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 73 | def main(args): | 
|  | 74 | action = 'link' | 
|  | 75 | output = '' | 
| Seo Sanghyeon | 96b99f7 | 2008-01-25 14:57:54 +0000 | [diff] [blame] | 76 | compile_opts = [] | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 77 | link_opts = [] | 
|  | 78 | files = [] | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 79 | save_temps = 0 | 
|  | 80 | language = '' | 
|  | 81 |  | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 82 | i = 0 | 
|  | 83 | while i < len(args): | 
|  | 84 | arg = args[i] | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 85 |  | 
|  | 86 | # Modes ccc supports | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 87 | if arg == '-E': | 
|  | 88 | action = 'preprocess' | 
|  | 89 | if arg == '-c': | 
|  | 90 | action = 'compile' | 
| Seo Sanghyeon | 96b99f7 | 2008-01-25 14:57:54 +0000 | [diff] [blame] | 91 | if arg.startswith('-print-prog-name'): | 
|  | 92 | action = 'print-prog-name' | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 93 | if arg == '-save-temps': | 
|  | 94 | save_temps = 1 | 
|  | 95 |  | 
|  | 96 | # Options with no arguments that should pass through | 
|  | 97 | if arg in ['-v']: | 
|  | 98 | compile_opts.append(arg) | 
|  | 99 | link_opts.append(arg) | 
|  | 100 |  | 
|  | 101 | # Options with one argument that should be ignored | 
| Ted Kremenek | d0eef02 | 2008-04-21 20:28:01 +0000 | [diff] [blame] | 102 | if arg in ['--param', '-u']: | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 103 | i += 1 | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 104 |  | 
|  | 105 | # Prefix matches for the compile mode | 
|  | 106 | if arg[:2] in ['-D', '-I', '-U', '-F']: | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 107 | if not arg[2:]: | 
|  | 108 | arg += args[i+1] | 
|  | 109 | i += 1 | 
|  | 110 | compile_opts.append(arg) | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 111 | if arg[:5] in ['-std=']: | 
|  | 112 | compile_opts.append(arg) | 
|  | 113 |  | 
| Nuno Lopes | e5d12e8 | 2008-06-17 17:23:14 +0000 | [diff] [blame] | 114 | # Options with one argument that should pass through to compiler | 
|  | 115 | if arg in [ '-include', '-idirafter', '-iprefix', | 
|  | 116 | '-iquote', '-isystem', '-iwithprefix', | 
|  | 117 | '-iwithprefixbefore']: | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 118 | compile_opts.append(arg) | 
|  | 119 | compile_opts.append(args[i+1]) | 
|  | 120 | i += 1 | 
|  | 121 |  | 
| Nuno Lopes | e5d12e8 | 2008-06-17 17:23:14 +0000 | [diff] [blame] | 122 | # Options with one argument that should pass through | 
|  | 123 | if arg in ['-framework']: | 
|  | 124 | link_opts.append(arg) | 
|  | 125 | link_opts.append(args[i+1]) | 
|  | 126 | i += 1 | 
|  | 127 |  | 
|  | 128 | # Options with one argument that should pass through to both | 
|  | 129 | if arg in ['-isysroot', '-arch']: | 
|  | 130 | compile_opts.append(arg) | 
|  | 131 | compile_opts.append(args[i+1]) | 
|  | 132 | link_opts.append(arg) | 
|  | 133 | link_opts.append(args[i+1]) | 
|  | 134 | i += 1 | 
|  | 135 |  | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 136 | # Prefix matches for the link mode | 
|  | 137 | if arg[:2] in ['-l', '-L', '-O', '-F']: | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 138 | if arg == '-O': arg = '-O1' | 
|  | 139 | if arg == '-Os': arg = '-O2' | 
|  | 140 | link_opts.append(arg) | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 141 |  | 
| Chris Lattner | cf719b7 | 2008-06-21 17:46:11 +0000 | [diff] [blame^] | 142 | # Enable threads | 
|  | 143 | if arg == '-pthread': | 
|  | 144 | link_opts.append('-lpthread') | 
|  | 145 |  | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 146 | # Input files | 
|  | 147 | if arg == '-filelist': | 
|  | 148 | f = open(args[i+1]) | 
|  | 149 | for line in f: | 
|  | 150 | files.append(line.strip()) | 
|  | 151 | f.close() | 
|  | 152 | i += 1 | 
|  | 153 | if arg == '-x': | 
|  | 154 | language = args[i+1] | 
| Chris Lattner | cf719b7 | 2008-06-21 17:46:11 +0000 | [diff] [blame^] | 155 | compile_opts.append(arg) | 
|  | 156 | compile_opts.append(args[i+1]) | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 157 | i += 1 | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 158 | if arg[0] != '-': | 
|  | 159 | files.append(arg) | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 160 |  | 
|  | 161 | # Output file | 
|  | 162 | if arg == '-o': | 
|  | 163 | output = args[i+1] | 
|  | 164 | i += 1 | 
|  | 165 |  | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 166 | i += 1 | 
|  | 167 |  | 
| Seo Sanghyeon | 96b99f7 | 2008-01-25 14:57:54 +0000 | [diff] [blame] | 168 | if action == 'print-prog-name': | 
|  | 169 | # assume we can handle everything | 
|  | 170 | print sys.argv[0] | 
|  | 171 | return | 
|  | 172 |  | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 173 | if not files: | 
|  | 174 | error('no input files') | 
|  | 175 |  | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 176 | if action == 'preprocess' or save_temps: | 
|  | 177 | for i, file in enumerate(files): | 
|  | 178 | if not language: | 
|  | 179 | language = inferlanguage(extension(file)) | 
|  | 180 | if save_temps and action != 'preprocess': | 
|  | 181 | # Need a temporary output file | 
|  | 182 | if language == 'c': | 
|  | 183 | poutput = changeextension(file, "i"); | 
|  | 184 | elif language == 'objective-c': | 
|  | 185 | poutput = changeextension(file, "mi"); | 
|  | 186 | else: | 
|  | 187 | poutput = changeextension(file, "tmp." + extension(file)) | 
|  | 188 | files[i] = poutput | 
|  | 189 | else: | 
|  | 190 | poutput = output | 
|  | 191 | if poutput: | 
|  | 192 | args = ['-x', language, '-o', poutput, file] + compile_opts | 
|  | 193 | else: | 
|  | 194 | args = ['-x', language, file] + compile_opts | 
|  | 195 | preprocess(args) | 
|  | 196 | # Discard the explicit language after used once | 
|  | 197 | language = '' | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 198 |  | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 199 | if action == 'compile' or save_temps: | 
|  | 200 | for i, file in enumerate(files): | 
|  | 201 | if not language: | 
|  | 202 | language = inferlanguage(extension(file)) | 
|  | 203 | if save_temps and action != "compile": | 
|  | 204 | # Need a temporary output file | 
|  | 205 | coutput = changeextension(file, "o"); | 
|  | 206 | files[i] = coutput | 
|  | 207 | elif not output: | 
|  | 208 | coutput = changeextension(file, "o") | 
|  | 209 | else: | 
|  | 210 | coutput = output | 
|  | 211 | args = ['-x', language, '-o', coutput, file] + compile_opts | 
|  | 212 | compile(args) | 
|  | 213 | language = '' | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 214 |  | 
|  | 215 | if action == 'link': | 
|  | 216 | for i, file in enumerate(files): | 
| Anders Carlsson | c720d9b | 2008-01-31 23:48:19 +0000 | [diff] [blame] | 217 | ext = extension(file) | 
|  | 218 | if ext != "o" and ext != "a": | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 219 | out = changeextension(file, "o") | 
|  | 220 | args = ['-o', out, file] + compile_opts | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 221 | compile(args) | 
|  | 222 | files[i] = out | 
|  | 223 | if not output: | 
|  | 224 | output = 'a.out' | 
|  | 225 | args = ['-o', output] + link_opts + files | 
|  | 226 | link(args) | 
|  | 227 |  | 
|  | 228 | if __name__ == '__main__': | 
|  | 229 | main(sys.argv[1:]) |