| 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 | 
 | 15 | import subprocess | 
 | 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 |  | 
 | 21 | def run(args): | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 22 |     print >> sys.stderr, ' '.join(args) | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 23 |     code = subprocess.call(args) | 
 | 24 |     if code: | 
 | 25 |         sys.exit(code) | 
 | 26 |  | 
 | 27 | def preprocess(args): | 
 | 28 |     command = 'clang -E'.split() | 
 | 29 |     run(command + args) | 
 | 30 |  | 
 | 31 | def compile(args): | 
 | 32 |     command = 'clang -emit-llvm-bc'.split() | 
 | 33 |     run(command + args) | 
 | 34 |  | 
 | 35 | def link(args): | 
 | 36 |     command = 'llvm-ld -native'.split() | 
 | 37 |     run(command + args) | 
 | 38 |  | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 39 | def extension(path): | 
 | 40 |     return path.rpartition(".")[2] | 
 | 41 |  | 
 | 42 | def changeextension(path, newext): | 
 | 43 |     components = path.rpartition(".") | 
 | 44 |     return "".join([components[0], components[1], newext]) | 
 | 45 |  | 
 | 46 | def inferlanguage(extension): | 
 | 47 |     if extension == "c": | 
 | 48 |         return "c" | 
 | 49 |     elif extension == "i": | 
 | 50 |         return "c-cpp-output" | 
 | 51 |     elif extension == "m": | 
 | 52 |         return "objective-c" | 
 | 53 |     elif extension == "mi": | 
 | 54 |         return "objective-c-cpp-output" | 
 | 55 |     else: | 
 | 56 |         return "unknown" | 
 | 57 |  | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 58 | def main(args): | 
 | 59 |     action = 'link' | 
 | 60 |     output = '' | 
| Seo Sanghyeon | 96b99f7 | 2008-01-25 14:57:54 +0000 | [diff] [blame] | 61 |     compile_opts = [] | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 62 |     link_opts = [] | 
 | 63 |     files = [] | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 64 |     save_temps = 0 | 
 | 65 |     language = '' | 
 | 66 |      | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 67 |     i = 0 | 
 | 68 |     while i < len(args): | 
 | 69 |         arg = args[i] | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 70 |  | 
 | 71 |         # Modes ccc supports | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 72 |         if arg == '-E': | 
 | 73 |             action = 'preprocess' | 
 | 74 |         if arg == '-c': | 
 | 75 |             action = 'compile' | 
| Seo Sanghyeon | 96b99f7 | 2008-01-25 14:57:54 +0000 | [diff] [blame] | 76 |         if arg.startswith('-print-prog-name'): | 
 | 77 |             action = 'print-prog-name' | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 78 |         if arg == '-save-temps': | 
 | 79 |             save_temps = 1 | 
 | 80 |  | 
 | 81 |         # Options with no arguments that should pass through | 
 | 82 |         if arg in ['-v']: | 
 | 83 |             compile_opts.append(arg) | 
 | 84 |             link_opts.append(arg) | 
 | 85 |          | 
 | 86 |         # Options with one argument that should be ignored | 
| Anders Carlsson | c720d9b | 2008-01-31 23:48:19 +0000 | [diff] [blame] | 87 |         if arg in ['--param', '-arch', '-u']: | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 88 |             i += 1 | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 89 |  | 
 | 90 |         # Prefix matches for the compile mode | 
 | 91 |         if arg[:2] in ['-D', '-I', '-U', '-F']: | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 92 |             if not arg[2:]: | 
 | 93 |                 arg += args[i+1] | 
 | 94 |                 i += 1 | 
 | 95 |             compile_opts.append(arg) | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 96 |         if arg[:5] in ['-std=']: | 
 | 97 |             compile_opts.append(arg) | 
 | 98 |  | 
 | 99 |         # Options with one argument that should pass through | 
 | 100 |         if arg in ['-include']: | 
 | 101 |             compile_opts.append(arg) | 
 | 102 |             compile_opts.append(args[i+1]) | 
 | 103 |             i += 1 | 
 | 104 |  | 
 | 105 |         # Prefix matches for the link mode | 
 | 106 |         if arg[:2] in ['-l', '-L', '-O', '-F']: | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 107 |             if arg == '-O': arg = '-O1' | 
 | 108 |             if arg == '-Os': arg = '-O2' | 
 | 109 |             link_opts.append(arg) | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 110 |  | 
 | 111 |         # Options with one argument that should pass through | 
 | 112 |         if arg in ['-framework']: | 
 | 113 |             link_opts.append(arg) | 
 | 114 |             link_opts.append(args[i+1]) | 
 | 115 |             i += 1 | 
 | 116 |  | 
 | 117 |         # Input files | 
 | 118 |         if arg == '-filelist': | 
 | 119 |             f = open(args[i+1]) | 
 | 120 |             for line in f: | 
 | 121 |                 files.append(line.strip()) | 
 | 122 |             f.close() | 
 | 123 |             i += 1 | 
 | 124 |         if arg == '-x': | 
 | 125 |             language = args[i+1] | 
 | 126 |             i += 1 | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 127 |         if arg[0] != '-': | 
 | 128 |             files.append(arg) | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 129 |  | 
 | 130 |         # Output file | 
 | 131 |         if arg == '-o': | 
 | 132 |             output = args[i+1] | 
 | 133 |             i += 1 | 
 | 134 |  | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 135 |         i += 1 | 
 | 136 |  | 
| Seo Sanghyeon | 96b99f7 | 2008-01-25 14:57:54 +0000 | [diff] [blame] | 137 |     if action == 'print-prog-name': | 
 | 138 |         # assume we can handle everything | 
 | 139 |         print sys.argv[0] | 
 | 140 |         return | 
 | 141 |  | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 142 |     if not files: | 
 | 143 |         error('no input files') | 
 | 144 |  | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 145 |     if action == 'preprocess' or save_temps: | 
 | 146 |         for i, file in enumerate(files): | 
 | 147 |             if not language: | 
 | 148 |                 language = inferlanguage(extension(file)) | 
 | 149 |             if save_temps and action != 'preprocess': | 
 | 150 |                 # Need a temporary output file | 
 | 151 |                 if language == 'c': | 
 | 152 |                     poutput = changeextension(file, "i"); | 
 | 153 |                 elif language == 'objective-c': | 
 | 154 |                     poutput = changeextension(file, "mi"); | 
 | 155 |                 else: | 
 | 156 |                     poutput = changeextension(file, "tmp." + extension(file)) | 
 | 157 |                 files[i] = poutput | 
 | 158 |             else: | 
 | 159 |                 poutput = output | 
 | 160 |             if poutput: | 
 | 161 |                 args = ['-x', language, '-o', poutput, file] + compile_opts | 
 | 162 |             else: | 
 | 163 |                 args = ['-x', language, file] + compile_opts | 
 | 164 |             preprocess(args) | 
 | 165 |             # Discard the explicit language after used once | 
 | 166 |             language = '' | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 167 |  | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 168 |     if action == 'compile' or save_temps: | 
 | 169 |         for i, file in enumerate(files): | 
 | 170 |             if not language: | 
 | 171 |                 language = inferlanguage(extension(file)) | 
 | 172 |             if save_temps and action != "compile": | 
 | 173 |                 # Need a temporary output file | 
 | 174 |                 coutput = changeextension(file, "o"); | 
 | 175 |                 files[i] = coutput | 
 | 176 |             elif not output: | 
 | 177 |                 coutput = changeextension(file, "o") | 
 | 178 |             else: | 
 | 179 |                 coutput = output | 
 | 180 |             args = ['-x', language, '-o', coutput, file] + compile_opts | 
 | 181 |             compile(args) | 
 | 182 |             language = '' | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 183 |  | 
 | 184 |     if action == 'link': | 
 | 185 |         for i, file in enumerate(files): | 
| Anders Carlsson | c720d9b | 2008-01-31 23:48:19 +0000 | [diff] [blame] | 186 |             ext = extension(file) | 
 | 187 |             if ext != "o" and ext != "a": | 
| Anders Carlsson | d125bb1 | 2008-01-29 07:21:34 +0000 | [diff] [blame] | 188 |                 out = changeextension(file, "o") | 
 | 189 |                 args = ['-o', out, file] + compile_opts | 
| Seo Sanghyeon | 2bfa533 | 2008-01-10 01:43:47 +0000 | [diff] [blame] | 190 |                 compile(args) | 
 | 191 |                 files[i] = out | 
 | 192 |         if not output: | 
 | 193 |             output = 'a.out' | 
 | 194 |         args = ['-o', output] + link_opts + files | 
 | 195 |         link(args) | 
 | 196 |  | 
 | 197 | if __name__ == '__main__': | 
 | 198 |     main(sys.argv[1:]) |