blob: 5b54c476c2dd73516d39ec0f47920f0fcd5b4b66 [file] [log] [blame]
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +00001#!/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
14import sys
Anders Carlssondac2b542008-02-06 19:03:27 +000015import subprocess
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000016
17def error(message):
Anders Carlssond125bb12008-01-29 07:21:34 +000018 print >> sys.stderr, 'ccc: ' + message
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000019 sys.exit(1)
20
21def run(args):
Anders Carlssondac2b542008-02-06 19:03:27 +000022 print >> sys.stderr, ' '.join(args)
23 code = subprocess.call(args)
Bill Wendling550ce0f2008-02-03 21:27:46 +000024 if code > 255:
25 code = 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000026 if code:
27 sys.exit(code)
28
29def preprocess(args):
Anders Carlssondac2b542008-02-06 19:03:27 +000030 command = 'clang -E'.split()
31 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000032
33def compile(args):
Anders Carlssondac2b542008-02-06 19:03:27 +000034 command = 'clang -emit-llvm-bc'.split()
35 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000036
37def link(args):
Lauro Ramos Venanciode808ca2008-02-27 18:46:32 +000038 command = 'llvm-ld -native -disable-internalize'.split()
Anders Carlssondac2b542008-02-06 19:03:27 +000039 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000040
Anders Carlssond125bb12008-01-29 07:21:34 +000041def extension(path):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000042 return path.split(".")[-1]
Anders Carlssond125bb12008-01-29 07:21:34 +000043
44def changeextension(path, newext):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000045 i = path.rfind('.')
46 if i < 0:
47 return path
Bill Wendling550ce0f2008-02-03 21:27:46 +000048 j = path.rfind('/', 0, i)
49 print path
50 if j < 0:
51 return path[:i] + "." + newext
52 return path[j+1:i] + "." + newext
Anders Carlssond125bb12008-01-29 07:21:34 +000053
54def inferlanguage(extension):
55 if extension == "c":
56 return "c"
Lauro Ramos Venancio279876b2008-02-15 22:35:25 +000057 elif extension in ["cpp", "cc"]:
58 return "c++"
Anders Carlssond125bb12008-01-29 07:21:34 +000059 elif extension == "i":
60 return "c-cpp-output"
61 elif extension == "m":
62 return "objective-c"
63 elif extension == "mi":
64 return "objective-c-cpp-output"
65 else:
66 return "unknown"
67
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000068def main(args):
69 action = 'link'
70 output = ''
Seo Sanghyeon96b99f72008-01-25 14:57:54 +000071 compile_opts = []
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000072 link_opts = []
73 files = []
Anders Carlssond125bb12008-01-29 07:21:34 +000074 save_temps = 0
75 language = ''
76
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000077 i = 0
78 while i < len(args):
79 arg = args[i]
Anders Carlssond125bb12008-01-29 07:21:34 +000080
81 # Modes ccc supports
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000082 if arg == '-E':
83 action = 'preprocess'
84 if arg == '-c':
85 action = 'compile'
Seo Sanghyeon96b99f72008-01-25 14:57:54 +000086 if arg.startswith('-print-prog-name'):
87 action = 'print-prog-name'
Anders Carlssond125bb12008-01-29 07:21:34 +000088 if arg == '-save-temps':
89 save_temps = 1
90
91 # Options with no arguments that should pass through
92 if arg in ['-v']:
93 compile_opts.append(arg)
94 link_opts.append(arg)
95
96 # Options with one argument that should be ignored
Anders Carlssonc720d9b2008-01-31 23:48:19 +000097 if arg in ['--param', '-arch', '-u']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000098 i += 1
Anders Carlssond125bb12008-01-29 07:21:34 +000099
100 # Prefix matches for the compile mode
101 if arg[:2] in ['-D', '-I', '-U', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000102 if not arg[2:]:
103 arg += args[i+1]
104 i += 1
105 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000106 if arg[:5] in ['-std=']:
107 compile_opts.append(arg)
108
109 # Options with one argument that should pass through
110 if arg in ['-include']:
111 compile_opts.append(arg)
112 compile_opts.append(args[i+1])
113 i += 1
114
115 # Prefix matches for the link mode
116 if arg[:2] in ['-l', '-L', '-O', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000117 if arg == '-O': arg = '-O1'
118 if arg == '-Os': arg = '-O2'
119 link_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000120
121 # Options with one argument that should pass through
122 if arg in ['-framework']:
123 link_opts.append(arg)
124 link_opts.append(args[i+1])
125 i += 1
126
127 # Input files
128 if arg == '-filelist':
129 f = open(args[i+1])
130 for line in f:
131 files.append(line.strip())
132 f.close()
133 i += 1
134 if arg == '-x':
135 language = args[i+1]
136 i += 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000137 if arg[0] != '-':
138 files.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000139
140 # Output file
141 if arg == '-o':
142 output = args[i+1]
143 i += 1
144
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000145 i += 1
146
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000147 if action == 'print-prog-name':
148 # assume we can handle everything
149 print sys.argv[0]
150 return
151
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000152 if not files:
153 error('no input files')
154
Anders Carlssond125bb12008-01-29 07:21:34 +0000155 if action == 'preprocess' or save_temps:
156 for i, file in enumerate(files):
157 if not language:
158 language = inferlanguage(extension(file))
159 if save_temps and action != 'preprocess':
160 # Need a temporary output file
161 if language == 'c':
162 poutput = changeextension(file, "i");
163 elif language == 'objective-c':
164 poutput = changeextension(file, "mi");
165 else:
166 poutput = changeextension(file, "tmp." + extension(file))
167 files[i] = poutput
168 else:
169 poutput = output
170 if poutput:
171 args = ['-x', language, '-o', poutput, file] + compile_opts
172 else:
173 args = ['-x', language, file] + compile_opts
174 preprocess(args)
175 # Discard the explicit language after used once
176 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000177
Anders Carlssond125bb12008-01-29 07:21:34 +0000178 if action == 'compile' or save_temps:
179 for i, file in enumerate(files):
180 if not language:
181 language = inferlanguage(extension(file))
182 if save_temps and action != "compile":
183 # Need a temporary output file
184 coutput = changeextension(file, "o");
185 files[i] = coutput
186 elif not output:
187 coutput = changeextension(file, "o")
188 else:
189 coutput = output
190 args = ['-x', language, '-o', coutput, file] + compile_opts
191 compile(args)
192 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000193
194 if action == 'link':
195 for i, file in enumerate(files):
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000196 ext = extension(file)
197 if ext != "o" and ext != "a":
Anders Carlssond125bb12008-01-29 07:21:34 +0000198 out = changeextension(file, "o")
199 args = ['-o', out, file] + compile_opts
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000200 compile(args)
201 files[i] = out
202 if not output:
203 output = 'a.out'
204 args = ['-o', output] + link_opts + files
205 link(args)
206
207if __name__ == '__main__':
208 main(sys.argv[1:])