blob: 18b3b2a8ff6b698e33d331045396d53592688e7a [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
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000014import os
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000015import sys
Anders Carlssondac2b542008-02-06 19:03:27 +000016import subprocess
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000017
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000018def checkenv(name, alternate=None):
19 """checkenv(var, alternate=None) - Return the given environment var,
20 or alternate if it is undefined or empty."""
21 v = os.getenv(name)
22 if v and v.strip():
23 return v.strip()
24 return alternate
25
26CCC_ECHO = checkenv('CCC_ECHO','1')
27CCC_NATIVE = checkenv('CCC_NATIVE')
28
29# We want to support use as CC or LD, so we need different defines.
30CLANG = checkenv('CLANG', 'clang')
31LLC = checkenv('LLC', 'llc')
32AS = checkenv('AS', 'as')
33CC = checkenv('CCC_CC', 'cc')
34LD = checkenv('CCC_LD', 'c++')
35
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000036def error(message):
Anders Carlssond125bb12008-01-29 07:21:34 +000037 print >> sys.stderr, 'ccc: ' + message
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000038 sys.exit(1)
39
Seo Sanghyeond3894652008-04-04 11:02:21 +000040def quote(arg):
41 if '"' in arg:
42 return repr(arg)
43 return arg
44
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000045def stripoutput(args):
46 """stripoutput(args) -> (output_name, newargs)
47
48 Remove the -o argument from the arg list and return the output
49 filename and a new argument list. Assumes there will be at most
50 one -o option. If no output argument is found the result is (None,
51 args)."""
52 for i,a in enumerate(args):
53 if a.startswith('-o'):
54 if a=='-o':
55 if i+1<len(args):
56 return args[i+1],args[:i]+args[i+2:]
57 elif a.startswith('-o='):
58 opt,arg = a.split('=',1)
59 return arg,args[:i]+args[i+1:]
60 return None,args
61
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000062def run(args):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000063 if CCC_ECHO:
64 print ' '.join(map(quote, args))
Anders Carlssondac2b542008-02-06 19:03:27 +000065 code = subprocess.call(args)
Bill Wendling550ce0f2008-02-03 21:27:46 +000066 if code > 255:
67 code = 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000068 if code:
69 sys.exit(code)
70
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000071def remove(path):
72 """remove(path) -> bool - Attempt to remove the file at path (if any).
73
74 The result indicates if the remove was successful. A warning is
75 printed if there is an error removing the file."""
76 if os.path.exists(path):
77 try:
78 os.remove(path)
79 except:
80 print >>sys.stderr, 'WARNING: Unable to remove temp "%s"'%(path,)
81 return False
82 return True
83
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000084def preprocess(args):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000085 command = [CLANG,'-E']
Anders Carlssondac2b542008-02-06 19:03:27 +000086 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000087
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000088def compile(args, native, save_temps=False):
89 if native:
90 output,args = stripoutput(args)
91 if not output:
92 raise ValueError,'Expected to always have explicit -o in compile()'
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000093
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000094 # I prefer suffixing these to changing the extension, which is
95 # more likely to overwrite other things. We could of course
96 # use temp files.
97 bc_output = output + '.bc'
98 s_output = output + '.s'
99 command = [CLANG,'-emit-llvm-bc']
100 run(command + args + ['-o', bc_output])
101 # FIXME: What controls relocation model?
102 run([LLC, '-relocation-model=pic', '-f', '-o', s_output, bc_output])
103 run([AS, '-o', output, s_output])
104 if not save_temps:
105 remove(bc_output)
106 remove(s_output)
107 else:
108 command = [CLANG,'-emit-llvm-bc']
109 run(command + args)
110
111def link(args, native):
112 if native:
113 run([LD] + args)
114 else:
115 command = ['llvm-ld', '-native', '-disable-internalize']
116 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000117
Anders Carlssond125bb12008-01-29 07:21:34 +0000118def extension(path):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +0000119 return path.split(".")[-1]
Anders Carlssond125bb12008-01-29 07:21:34 +0000120
121def changeextension(path, newext):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +0000122 i = path.rfind('.')
123 if i < 0:
124 return path
Bill Wendling550ce0f2008-02-03 21:27:46 +0000125 j = path.rfind('/', 0, i)
126 print path
127 if j < 0:
128 return path[:i] + "." + newext
129 return path[j+1:i] + "." + newext
Anders Carlssond125bb12008-01-29 07:21:34 +0000130
131def inferlanguage(extension):
132 if extension == "c":
133 return "c"
Lauro Ramos Venancio279876b2008-02-15 22:35:25 +0000134 elif extension in ["cpp", "cc"]:
135 return "c++"
Anders Carlssond125bb12008-01-29 07:21:34 +0000136 elif extension == "i":
137 return "c-cpp-output"
138 elif extension == "m":
139 return "objective-c"
140 elif extension == "mi":
141 return "objective-c-cpp-output"
142 else:
143 return "unknown"
144
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000145def main(args):
146 action = 'link'
147 output = ''
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000148 compile_opts = []
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000149 link_opts = []
150 files = []
Anders Carlssond125bb12008-01-29 07:21:34 +0000151 save_temps = 0
152 language = ''
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000153 native = CCC_NATIVE
154
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000155 i = 0
156 while i < len(args):
157 arg = args[i]
Anders Carlssond125bb12008-01-29 07:21:34 +0000158
159 # Modes ccc supports
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000160 if arg == '-E':
161 action = 'preprocess'
162 if arg == '-c':
163 action = 'compile'
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000164 if arg.startswith('-print-prog-name'):
165 action = 'print-prog-name'
Anders Carlssond125bb12008-01-29 07:21:34 +0000166 if arg == '-save-temps':
167 save_temps = 1
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000168 if arg == '-emit-llvm' or arg == '--emit-llvm':
169 native = False
Anders Carlssond125bb12008-01-29 07:21:34 +0000170
171 # Options with no arguments that should pass through
172 if arg in ['-v']:
173 compile_opts.append(arg)
174 link_opts.append(arg)
175
176 # Options with one argument that should be ignored
Ted Kremenekd0eef022008-04-21 20:28:01 +0000177 if arg in ['--param', '-u']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000178 i += 1
Anders Carlssond125bb12008-01-29 07:21:34 +0000179
Ted Kremenek16833602008-07-24 03:49:15 +0000180 # Preprocessor options with one argument that should be ignored
181 if arg in ['-MT', '-MF']:
182 i += 1
183
Anders Carlssond125bb12008-01-29 07:21:34 +0000184 # Prefix matches for the compile mode
185 if arg[:2] in ['-D', '-I', '-U', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000186 if not arg[2:]:
187 arg += args[i+1]
188 i += 1
189 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000190 if arg[:5] in ['-std=']:
191 compile_opts.append(arg)
192
Nuno Lopese5d12e82008-06-17 17:23:14 +0000193 # Options with one argument that should pass through to compiler
194 if arg in [ '-include', '-idirafter', '-iprefix',
195 '-iquote', '-isystem', '-iwithprefix',
196 '-iwithprefixbefore']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000197 compile_opts.append(arg)
198 compile_opts.append(args[i+1])
199 i += 1
200
Nuno Lopese5d12e82008-06-17 17:23:14 +0000201 # Options with one argument that should pass through
202 if arg in ['-framework']:
203 link_opts.append(arg)
204 link_opts.append(args[i+1])
205 i += 1
206
207 # Options with one argument that should pass through to both
208 if arg in ['-isysroot', '-arch']:
209 compile_opts.append(arg)
210 compile_opts.append(args[i+1])
211 link_opts.append(arg)
212 link_opts.append(args[i+1])
213 i += 1
214
Anders Carlssond125bb12008-01-29 07:21:34 +0000215 # Prefix matches for the link mode
Nuno Lopes9a184482008-08-10 21:58:01 +0000216 if arg[:2] in ['-l', '-L', '-F', '-R']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000217 link_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000218
Chris Lattnercf719b72008-06-21 17:46:11 +0000219 # Enable threads
220 if arg == '-pthread':
221 link_opts.append('-lpthread')
222
Anders Carlssond125bb12008-01-29 07:21:34 +0000223 # Input files
224 if arg == '-filelist':
225 f = open(args[i+1])
226 for line in f:
227 files.append(line.strip())
228 f.close()
229 i += 1
230 if arg == '-x':
231 language = args[i+1]
232 i += 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000233 if arg[0] != '-':
234 files.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000235
236 # Output file
237 if arg == '-o':
238 output = args[i+1]
239 i += 1
240
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000241 i += 1
242
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000243 if action == 'print-prog-name':
244 # assume we can handle everything
245 print sys.argv[0]
246 return
247
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000248 if not files:
249 error('no input files')
250
Anders Carlssond125bb12008-01-29 07:21:34 +0000251 if action == 'preprocess' or save_temps:
252 for i, file in enumerate(files):
253 if not language:
254 language = inferlanguage(extension(file))
255 if save_temps and action != 'preprocess':
256 # Need a temporary output file
257 if language == 'c':
258 poutput = changeextension(file, "i");
259 elif language == 'objective-c':
260 poutput = changeextension(file, "mi");
261 else:
262 poutput = changeextension(file, "tmp." + extension(file))
263 files[i] = poutput
264 else:
265 poutput = output
266 if poutput:
267 args = ['-x', language, '-o', poutput, file] + compile_opts
268 else:
269 args = ['-x', language, file] + compile_opts
270 preprocess(args)
271 # Discard the explicit language after used once
272 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000273
Anders Carlssond125bb12008-01-29 07:21:34 +0000274 if action == 'compile' or save_temps:
275 for i, file in enumerate(files):
276 if not language:
277 language = inferlanguage(extension(file))
278 if save_temps and action != "compile":
279 # Need a temporary output file
280 coutput = changeextension(file, "o");
281 files[i] = coutput
282 elif not output:
283 coutput = changeextension(file, "o")
284 else:
285 coutput = output
286 args = ['-x', language, '-o', coutput, file] + compile_opts
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000287 compile(args, native, save_temps)
Anders Carlssond125bb12008-01-29 07:21:34 +0000288 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000289
290 if action == 'link':
291 for i, file in enumerate(files):
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000292 ext = extension(file)
Nuno Lopesc46cf492008-08-10 22:17:57 +0000293 if ext != "o" and ext != "a" and ext != "so":
Anders Carlssond125bb12008-01-29 07:21:34 +0000294 out = changeextension(file, "o")
295 args = ['-o', out, file] + compile_opts
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000296 compile(args, native, save_temps)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000297 files[i] = out
298 if not output:
299 output = 'a.out'
300 args = ['-o', output] + link_opts + files
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000301 link(args, native)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000302
303if __name__ == '__main__':
304 main(sys.argv[1:])