blob: e3ee17226cb8fe2654e873a4ca24705abdd0cb06 [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')
Daniel Dunbard3d81412008-08-29 21:03:27 +000028CCC_FALLBACK = checkenv('CCC_FALLBACK')
Nuno Lopes24653e82008-09-02 10:27:37 +000029CCC_LANGUAGES = checkenv('CCC_LANGUAGES','c,c++,c-cpp-output,objective-c,objective-c++,objective-c-cpp-output')
Daniel Dunbard3d81412008-08-29 21:03:27 +000030if CCC_LANGUAGES:
31 CCC_LANGUAGES = set([s.strip() for s in CCC_LANGUAGES.split(',')])
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000032
33# We want to support use as CC or LD, so we need different defines.
34CLANG = checkenv('CLANG', 'clang')
35LLC = checkenv('LLC', 'llc')
36AS = checkenv('AS', 'as')
37CC = checkenv('CCC_CC', 'cc')
38LD = checkenv('CCC_LD', 'c++')
39
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000040def error(message):
Anders Carlssond125bb12008-01-29 07:21:34 +000041 print >> sys.stderr, 'ccc: ' + message
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000042 sys.exit(1)
43
Seo Sanghyeond3894652008-04-04 11:02:21 +000044def quote(arg):
Daniel Dunbard3d81412008-08-29 21:03:27 +000045 if '"' in arg or ' ' in arg:
Seo Sanghyeond3894652008-04-04 11:02:21 +000046 return repr(arg)
47 return arg
48
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000049def stripoutput(args):
50 """stripoutput(args) -> (output_name, newargs)
51
52 Remove the -o argument from the arg list and return the output
53 filename and a new argument list. Assumes there will be at most
54 one -o option. If no output argument is found the result is (None,
55 args)."""
56 for i,a in enumerate(args):
57 if a.startswith('-o'):
58 if a=='-o':
59 if i+1<len(args):
60 return args[i+1],args[:i]+args[i+2:]
61 elif a.startswith('-o='):
62 opt,arg = a.split('=',1)
63 return arg,args[:i]+args[i+1:]
64 return None,args
65
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000066def run(args):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000067 if CCC_ECHO:
68 print ' '.join(map(quote, args))
Daniel Dunbard3d81412008-08-29 21:03:27 +000069 sys.stdout.flush()
Anders Carlssondac2b542008-02-06 19:03:27 +000070 code = subprocess.call(args)
Bill Wendling550ce0f2008-02-03 21:27:46 +000071 if code > 255:
72 code = 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000073 if code:
74 sys.exit(code)
75
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000076def remove(path):
77 """remove(path) -> bool - Attempt to remove the file at path (if any).
78
79 The result indicates if the remove was successful. A warning is
80 printed if there is an error removing the file."""
81 if os.path.exists(path):
82 try:
83 os.remove(path)
84 except:
85 print >>sys.stderr, 'WARNING: Unable to remove temp "%s"'%(path,)
86 return False
87 return True
88
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000089def preprocess(args):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000090 command = [CLANG,'-E']
Anders Carlssondac2b542008-02-06 19:03:27 +000091 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000092
Daniel Dunbard3d81412008-08-29 21:03:27 +000093def compile_fallback(args):
94 command = [CC,'-c']
95 run(command + args)
96
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000097def compile(args, native, save_temps=False):
98 if native:
99 output,args = stripoutput(args)
100 if not output:
101 raise ValueError,'Expected to always have explicit -o in compile()'
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000102
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000103 # I prefer suffixing these to changing the extension, which is
104 # more likely to overwrite other things. We could of course
105 # use temp files.
106 bc_output = output + '.bc'
107 s_output = output + '.s'
108 command = [CLANG,'-emit-llvm-bc']
Daniel Dunbard3d81412008-08-29 21:03:27 +0000109 try:
110 run(command + args + ['-o', bc_output])
111 # FIXME: What controls relocation model?
112 run([LLC, '-relocation-model=pic', '-f', '-o', s_output, bc_output])
113 run([AS, '-o', output, s_output])
114 finally:
115 if not save_temps:
116 remove(bc_output)
117 remove(s_output)
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000118 else:
119 command = [CLANG,'-emit-llvm-bc']
120 run(command + args)
121
Daniel Dunbard3d81412008-08-29 21:03:27 +0000122def checked_compile(args, native, language, save_temps):
123 if CCC_LANGUAGES and language and language not in CCC_LANGUAGES:
124 print >>sys.stderr, 'NOTE: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
125 compile_fallback(args)
126 elif CCC_FALLBACK:
127 try:
128 compile(args, native, save_temps)
129 except:
130 print >>sys.stderr, 'WARNING: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
131 compile_fallback(args)
132 else:
133 compile(args, native, save_temps)
134
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000135def link(args, native):
136 if native:
Daniel Dunbard3d81412008-08-29 21:03:27 +0000137 run([LD] + args)
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000138 else:
139 command = ['llvm-ld', '-native', '-disable-internalize']
140 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000141
Anders Carlssond125bb12008-01-29 07:21:34 +0000142def extension(path):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +0000143 return path.split(".")[-1]
Anders Carlssond125bb12008-01-29 07:21:34 +0000144
145def changeextension(path, newext):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +0000146 i = path.rfind('.')
147 if i < 0:
148 return path
Bill Wendling550ce0f2008-02-03 21:27:46 +0000149 j = path.rfind('/', 0, i)
Bill Wendling550ce0f2008-02-03 21:27:46 +0000150 if j < 0:
151 return path[:i] + "." + newext
152 return path[j+1:i] + "." + newext
Anders Carlssond125bb12008-01-29 07:21:34 +0000153
154def inferlanguage(extension):
155 if extension == "c":
156 return "c"
Lauro Ramos Venancio279876b2008-02-15 22:35:25 +0000157 elif extension in ["cpp", "cc"]:
158 return "c++"
Anders Carlssond125bb12008-01-29 07:21:34 +0000159 elif extension == "i":
160 return "c-cpp-output"
161 elif extension == "m":
162 return "objective-c"
Daniel Dunbard3d81412008-08-29 21:03:27 +0000163 elif extension == "mm":
164 return "objective-c++"
Anders Carlssond125bb12008-01-29 07:21:34 +0000165 elif extension == "mi":
166 return "objective-c-cpp-output"
Nuno Lopes24653e82008-09-02 10:27:37 +0000167 elif extension == "s":
168 return "assembler"
169 elif extension == "S":
170 return "assembler-with-cpp"
Anders Carlssond125bb12008-01-29 07:21:34 +0000171 else:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000172 return ""
Anders Carlssond125bb12008-01-29 07:21:34 +0000173
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000174def inferaction(args):
175 if '-E' in args:
176 return 'preprocess'
177 if '-c' in args:
178 return 'compile'
179 for arg in args:
180 if arg.startswith('-print-prog-name'):
181 return 'pring-prog-name'
182 return 'link'
183
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000184def main(args):
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000185 action = inferaction(args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000186 output = ''
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000187 compile_opts = []
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000188 link_opts = []
189 files = []
Anders Carlssond125bb12008-01-29 07:21:34 +0000190 save_temps = 0
191 language = ''
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000192 native = CCC_NATIVE
193
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000194 i = 0
195 while i < len(args):
196 arg = args[i]
Anders Carlssond125bb12008-01-29 07:21:34 +0000197
Daniel Dunbar319e7922008-09-30 22:54:22 +0000198 if '=' in arg:
199 argkey,argvalue = arg.split('=',1)
200 else:
201 argkey,argvalue = arg,None
202
Anders Carlssond125bb12008-01-29 07:21:34 +0000203 # Modes ccc supports
Anders Carlssond125bb12008-01-29 07:21:34 +0000204 if arg == '-save-temps':
205 save_temps = 1
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000206 if arg == '-emit-llvm' or arg == '--emit-llvm':
207 native = False
Anders Carlssond125bb12008-01-29 07:21:34 +0000208
209 # Options with no arguments that should pass through
Daniel Dunbard3d81412008-08-29 21:03:27 +0000210 if arg in ['-v', '-fobjc-gc', '-fobjc-gc-only', '-fnext-runtime',
211 '-fgnu-runtime']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000212 compile_opts.append(arg)
213 link_opts.append(arg)
214
215 # Options with one argument that should be ignored
Ted Kremenekd0eef022008-04-21 20:28:01 +0000216 if arg in ['--param', '-u']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000217 i += 1
Anders Carlssond125bb12008-01-29 07:21:34 +0000218
Ted Kremenek16833602008-07-24 03:49:15 +0000219 # Preprocessor options with one argument that should be ignored
220 if arg in ['-MT', '-MF']:
221 i += 1
222
Anders Carlssond125bb12008-01-29 07:21:34 +0000223 # Prefix matches for the compile mode
224 if arg[:2] in ['-D', '-I', '-U', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000225 if not arg[2:]:
226 arg += args[i+1]
227 i += 1
228 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000229 if arg[:5] in ['-std=']:
230 compile_opts.append(arg)
231
Nuno Lopese5d12e82008-06-17 17:23:14 +0000232 # Options with one argument that should pass through to compiler
Daniel Dunbar319e7922008-09-30 22:54:22 +0000233 if argkey in [ '-include', '-idirafter', '-iprefix',
234 '-iquote', '-isystem', '-iwithprefix',
235 '-iwithprefixbefore', '-mmacosx-version-min']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000236 compile_opts.append(arg)
237 compile_opts.append(args[i+1])
238 i += 1
239
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000240 # Options with no arguments that should pass through
Daniel Dunbar319e7922008-09-30 22:54:22 +0000241 if arg in ('-dynamiclib', '-bundle', '-headerpad_max_install_names'):
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000242 link_opts.append(arg)
243
Nuno Lopese5d12e82008-06-17 17:23:14 +0000244 # Options with one argument that should pass through
Daniel Dunbar75e05712008-09-12 19:42:28 +0000245 if arg in ('-framework', '-multiply_defined', '-bundle_loader',
Daniel Dunbar319e7922008-09-30 22:54:22 +0000246 '-e', '-install_name',
247 '-unexported_symbols_list', '-exported_symbols_list',
248 '-compatibility_version', '-current_version', '-init',
249 '-seg1addr', '-dylib_file'):
Nuno Lopese5d12e82008-06-17 17:23:14 +0000250 link_opts.append(arg)
251 link_opts.append(args[i+1])
252 i += 1
253
254 # Options with one argument that should pass through to both
255 if arg in ['-isysroot', '-arch']:
256 compile_opts.append(arg)
257 compile_opts.append(args[i+1])
258 link_opts.append(arg)
259 link_opts.append(args[i+1])
260 i += 1
Daniel Dunbar75e05712008-09-12 19:42:28 +0000261
262 # Options with three arguments that should pass through
263 if arg in ('-sectorder',):
264 link_opts.extend(args[i:i+4])
265 i += 3
Nuno Lopese5d12e82008-06-17 17:23:14 +0000266
Anders Carlssond125bb12008-01-29 07:21:34 +0000267 # Prefix matches for the link mode
Nuno Lopes9a184482008-08-10 21:58:01 +0000268 if arg[:2] in ['-l', '-L', '-F', '-R']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000269 link_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000270
Chris Lattnercf719b72008-06-21 17:46:11 +0000271 # Enable threads
272 if arg == '-pthread':
273 link_opts.append('-lpthread')
274
Anders Carlssond125bb12008-01-29 07:21:34 +0000275 # Input files
276 if arg == '-filelist':
277 f = open(args[i+1])
278 for line in f:
279 files.append(line.strip())
280 f.close()
281 i += 1
282 if arg == '-x':
283 language = args[i+1]
284 i += 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000285 if arg[0] != '-':
286 files.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000287
288 # Output file
289 if arg == '-o':
290 output = args[i+1]
291 i += 1
292
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000293 i += 1
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000294
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000295 if action == 'print-prog-name':
296 # assume we can handle everything
297 print sys.argv[0]
298 return
299
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000300 if not files:
301 error('no input files')
302
Anders Carlssond125bb12008-01-29 07:21:34 +0000303 if action == 'preprocess' or save_temps:
304 for i, file in enumerate(files):
305 if not language:
306 language = inferlanguage(extension(file))
307 if save_temps and action != 'preprocess':
308 # Need a temporary output file
309 if language == 'c':
310 poutput = changeextension(file, "i");
311 elif language == 'objective-c':
312 poutput = changeextension(file, "mi");
313 else:
314 poutput = changeextension(file, "tmp." + extension(file))
315 files[i] = poutput
316 else:
317 poutput = output
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000318 args = []
319 if language:
320 args.extend(['-x', language])
Anders Carlssond125bb12008-01-29 07:21:34 +0000321 if poutput:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000322 args += ['-o', poutput, file] + compile_opts
Anders Carlssond125bb12008-01-29 07:21:34 +0000323 else:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000324 args += [file] + compile_opts
Anders Carlssond125bb12008-01-29 07:21:34 +0000325 preprocess(args)
326 # Discard the explicit language after used once
327 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000328
Anders Carlssond125bb12008-01-29 07:21:34 +0000329 if action == 'compile' or save_temps:
330 for i, file in enumerate(files):
331 if not language:
332 language = inferlanguage(extension(file))
333 if save_temps and action != "compile":
334 # Need a temporary output file
335 coutput = changeextension(file, "o");
336 files[i] = coutput
337 elif not output:
338 coutput = changeextension(file, "o")
339 else:
340 coutput = output
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000341 args = []
342 if language:
343 args.extend(['-x', language])
344 args += ['-o', coutput, file] + compile_opts
Daniel Dunbard3d81412008-08-29 21:03:27 +0000345 checked_compile(args, native, language, save_temps)
Anders Carlssond125bb12008-01-29 07:21:34 +0000346 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000347
348 if action == 'link':
349 for i, file in enumerate(files):
Daniel Dunbard3d81412008-08-29 21:03:27 +0000350 if not language:
351 language = inferlanguage(extension(file))
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000352 ext = extension(file)
Nuno Lopesc46cf492008-08-10 22:17:57 +0000353 if ext != "o" and ext != "a" and ext != "so":
Anders Carlssond125bb12008-01-29 07:21:34 +0000354 out = changeextension(file, "o")
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000355 args = []
356 if language:
357 args.extend(['-x', language])
358 args = ['-o', out, file] + compile_opts
Daniel Dunbard3d81412008-08-29 21:03:27 +0000359 checked_compile(args, native, language, save_temps)
360 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000361 files[i] = out
362 if not output:
363 output = 'a.out'
364 args = ['-o', output] + link_opts + files
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000365 link(args, native)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000366
367if __name__ == '__main__':
368 main(sys.argv[1:])