blob: 489424e3b353797e815c3545916fc497905815ee [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
Daniel Dunbar1bf3f732008-10-01 01:10:22 +000026def checkbool(name, default=False):
27 v = os.getenv(name)
28 if v:
29 try:
30 return bool(int(v))
31 except:
32 pass
33 return default
34
Daniel Dunbarcb529252008-10-15 21:52:00 +000035CCC_LOG = checkenv('CCC_LOG')
Daniel Dunbar1bf3f732008-10-01 01:10:22 +000036CCC_ECHO = checkbool('CCC_ECHO')
37CCC_NATIVE = checkbool('CCC_NATIVE','1')
38CCC_FALLBACK = checkbool('CCC_FALLBACK')
Chris Lattnera778d7d2008-10-22 17:29:21 +000039CCC_LANGUAGES = checkenv('CCC_LANGUAGES','c,c++,c-cpp-output,objective-c,objective-c++,objective-c-cpp-output,assembler-with-cpp')
Daniel Dunbard3d81412008-08-29 21:03:27 +000040if CCC_LANGUAGES:
41 CCC_LANGUAGES = set([s.strip() for s in CCC_LANGUAGES.split(',')])
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000042
43# We want to support use as CC or LD, so we need different defines.
44CLANG = checkenv('CLANG', 'clang')
45LLC = checkenv('LLC', 'llc')
46AS = checkenv('AS', 'as')
47CC = checkenv('CCC_CC', 'cc')
48LD = checkenv('CCC_LD', 'c++')
49
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000050def error(message):
Anders Carlssond125bb12008-01-29 07:21:34 +000051 print >> sys.stderr, 'ccc: ' + message
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000052 sys.exit(1)
53
Seo Sanghyeond3894652008-04-04 11:02:21 +000054def quote(arg):
Daniel Dunbard3d81412008-08-29 21:03:27 +000055 if '"' in arg or ' ' in arg:
Seo Sanghyeond3894652008-04-04 11:02:21 +000056 return repr(arg)
57 return arg
58
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000059def stripoutput(args):
60 """stripoutput(args) -> (output_name, newargs)
61
62 Remove the -o argument from the arg list and return the output
63 filename and a new argument list. Assumes there will be at most
64 one -o option. If no output argument is found the result is (None,
65 args)."""
66 for i,a in enumerate(args):
67 if a.startswith('-o'):
68 if a=='-o':
69 if i+1<len(args):
70 return args[i+1],args[:i]+args[i+2:]
71 elif a.startswith('-o='):
72 opt,arg = a.split('=',1)
73 return arg,args[:i]+args[i+1:]
74 return None,args
75
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000076def run(args):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000077 if CCC_ECHO:
78 print ' '.join(map(quote, args))
Daniel Dunbard3d81412008-08-29 21:03:27 +000079 sys.stdout.flush()
Anders Carlssondac2b542008-02-06 19:03:27 +000080 code = subprocess.call(args)
Bill Wendling550ce0f2008-02-03 21:27:46 +000081 if code > 255:
82 code = 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000083 if code:
84 sys.exit(code)
85
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000086def remove(path):
87 """remove(path) -> bool - Attempt to remove the file at path (if any).
88
89 The result indicates if the remove was successful. A warning is
90 printed if there is an error removing the file."""
91 if os.path.exists(path):
92 try:
93 os.remove(path)
94 except:
95 print >>sys.stderr, 'WARNING: Unable to remove temp "%s"'%(path,)
96 return False
97 return True
98
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000099def preprocess(args):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000100 command = [CLANG,'-E']
Anders Carlssondac2b542008-02-06 19:03:27 +0000101 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000102
Daniel Dunbarcb529252008-10-15 21:52:00 +0000103def syntaxonly(args):
104 command = [CLANG,'-fsyntax-only']
105 run(command + args)
106
Daniel Dunbard3d81412008-08-29 21:03:27 +0000107def compile_fallback(args):
108 command = [CC,'-c']
109 run(command + args)
110
Daniel Dunbar91dce082009-01-07 00:03:20 +0000111def compile(args, native, save_temps=False, asm_opts=[]):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000112 if native:
113 output,args = stripoutput(args)
114 if not output:
115 raise ValueError,'Expected to always have explicit -o in compile()'
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000116
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000117 # I prefer suffixing these to changing the extension, which is
118 # more likely to overwrite other things. We could of course
119 # use temp files.
120 bc_output = output + '.bc'
121 s_output = output + '.s'
122 command = [CLANG,'-emit-llvm-bc']
Daniel Dunbard3d81412008-08-29 21:03:27 +0000123 try:
124 run(command + args + ['-o', bc_output])
125 # FIXME: What controls relocation model?
126 run([LLC, '-relocation-model=pic', '-f', '-o', s_output, bc_output])
Daniel Dunbar91dce082009-01-07 00:03:20 +0000127 run([AS, '-o', output, s_output] + asm_opts)
Daniel Dunbard3d81412008-08-29 21:03:27 +0000128 finally:
129 if not save_temps:
130 remove(bc_output)
131 remove(s_output)
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000132 else:
133 command = [CLANG,'-emit-llvm-bc']
134 run(command + args)
135
Daniel Dunbar91dce082009-01-07 00:03:20 +0000136def checked_compile(args, native, language, save_temps, asm_opts):
Daniel Dunbard3d81412008-08-29 21:03:27 +0000137 if CCC_LANGUAGES and language and language not in CCC_LANGUAGES:
Daniel Dunbarcb529252008-10-15 21:52:00 +0000138 log('fallback', args)
Daniel Dunbard3d81412008-08-29 21:03:27 +0000139 print >>sys.stderr, 'NOTE: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
140 compile_fallback(args)
141 elif CCC_FALLBACK:
142 try:
Daniel Dunbar91dce082009-01-07 00:03:20 +0000143 compile(args, native, save_temps, asm_opts)
Daniel Dunbard3d81412008-08-29 21:03:27 +0000144 except:
Daniel Dunbarcb529252008-10-15 21:52:00 +0000145 log('fallback-on-fail', args)
Daniel Dunbard3d81412008-08-29 21:03:27 +0000146 print >>sys.stderr, 'WARNING: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
147 compile_fallback(args)
148 else:
Daniel Dunbar91dce082009-01-07 00:03:20 +0000149 compile(args, native, save_temps, asm_opts)
Daniel Dunbard3d81412008-08-29 21:03:27 +0000150
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000151def link(args, native):
152 if native:
Daniel Dunbard3d81412008-08-29 21:03:27 +0000153 run([LD] + args)
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000154 else:
155 command = ['llvm-ld', '-native', '-disable-internalize']
156 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000157
Anders Carlssond125bb12008-01-29 07:21:34 +0000158def extension(path):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +0000159 return path.split(".")[-1]
Anders Carlssond125bb12008-01-29 07:21:34 +0000160
161def changeextension(path, newext):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +0000162 i = path.rfind('.')
163 if i < 0:
164 return path
Bill Wendling550ce0f2008-02-03 21:27:46 +0000165 j = path.rfind('/', 0, i)
Bill Wendling550ce0f2008-02-03 21:27:46 +0000166 if j < 0:
167 return path[:i] + "." + newext
168 return path[j+1:i] + "." + newext
Anders Carlssond125bb12008-01-29 07:21:34 +0000169
170def inferlanguage(extension):
171 if extension == "c":
172 return "c"
Lauro Ramos Venancio279876b2008-02-15 22:35:25 +0000173 elif extension in ["cpp", "cc"]:
174 return "c++"
Anders Carlssond125bb12008-01-29 07:21:34 +0000175 elif extension == "i":
176 return "c-cpp-output"
177 elif extension == "m":
178 return "objective-c"
Daniel Dunbard3d81412008-08-29 21:03:27 +0000179 elif extension == "mm":
180 return "objective-c++"
Anders Carlssond125bb12008-01-29 07:21:34 +0000181 elif extension == "mi":
182 return "objective-c-cpp-output"
Nuno Lopes24653e82008-09-02 10:27:37 +0000183 elif extension == "s":
184 return "assembler"
185 elif extension == "S":
186 return "assembler-with-cpp"
Anders Carlssond125bb12008-01-29 07:21:34 +0000187 else:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000188 return ""
Anders Carlssond125bb12008-01-29 07:21:34 +0000189
Daniel Dunbarcb529252008-10-15 21:52:00 +0000190def log(name, item):
191 if CCC_LOG:
192 f = open(CCC_LOG,'a')
193 print >>f, (name, item)
194 f.close()
195
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000196def inferaction(args):
197 if '-E' in args:
198 return 'preprocess'
Daniel Dunbarcb529252008-10-15 21:52:00 +0000199 if '-fsyntax-only' in args:
200 return 'syntax-only'
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000201 if '-c' in args:
202 return 'compile'
203 for arg in args:
204 if arg.startswith('-print-prog-name'):
205 return 'pring-prog-name'
206 return 'link'
207
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000208def main(args):
Daniel Dunbarcb529252008-10-15 21:52:00 +0000209 log('invoke', args)
210
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000211 action = inferaction(args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000212 output = ''
Daniel Dunbar91dce082009-01-07 00:03:20 +0000213 asm_opts = []
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000214 compile_opts = []
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000215 link_opts = []
216 files = []
Anders Carlssond125bb12008-01-29 07:21:34 +0000217 save_temps = 0
218 language = ''
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000219 native = CCC_NATIVE
220
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000221 i = 0
222 while i < len(args):
223 arg = args[i]
Anders Carlssond125bb12008-01-29 07:21:34 +0000224
Daniel Dunbar319e7922008-09-30 22:54:22 +0000225 if '=' in arg:
226 argkey,argvalue = arg.split('=',1)
227 else:
228 argkey,argvalue = arg,None
229
Anders Carlssond125bb12008-01-29 07:21:34 +0000230 # Modes ccc supports
Anders Carlssond125bb12008-01-29 07:21:34 +0000231 if arg == '-save-temps':
232 save_temps = 1
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000233 if arg == '-emit-llvm' or arg == '--emit-llvm':
234 native = False
Anders Carlssond125bb12008-01-29 07:21:34 +0000235
236 # Options with no arguments that should pass through
Daniel Dunbard3d81412008-08-29 21:03:27 +0000237 if arg in ['-v', '-fobjc-gc', '-fobjc-gc-only', '-fnext-runtime',
238 '-fgnu-runtime']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000239 compile_opts.append(arg)
240 link_opts.append(arg)
241
242 # Options with one argument that should be ignored
Ted Kremenekd0eef022008-04-21 20:28:01 +0000243 if arg in ['--param', '-u']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000244 i += 1
Anders Carlssond125bb12008-01-29 07:21:34 +0000245
Ted Kremenek16833602008-07-24 03:49:15 +0000246 # Preprocessor options with one argument that should be ignored
247 if arg in ['-MT', '-MF']:
248 i += 1
249
Anders Carlssond125bb12008-01-29 07:21:34 +0000250 # Prefix matches for the compile mode
251 if arg[:2] in ['-D', '-I', '-U', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000252 if not arg[2:]:
253 arg += args[i+1]
254 i += 1
255 compile_opts.append(arg)
Daniel Dunbar8e45f732008-10-02 17:26:37 +0000256 if argkey in ('-std', '-mmacosx-version-min'):
257 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000258
Daniel Dunbarfa538e72008-10-19 02:41:16 +0000259 # Special case debug options to only pass -g to clang. This is
260 # wrong.
261 if arg in ('-g', '-gdwarf-2'):
262 compile_opts.append('-g')
Daniel Dunbarfa538e72008-10-19 02:41:16 +0000263
Nuno Lopese5d12e82008-06-17 17:23:14 +0000264 # Options with one argument that should pass through to compiler
Daniel Dunbar8e45f732008-10-02 17:26:37 +0000265 if arg in [ '-include', '-idirafter', '-iprefix',
Daniel Dunbar319e7922008-09-30 22:54:22 +0000266 '-iquote', '-isystem', '-iwithprefix',
Daniel Dunbar8e45f732008-10-02 17:26:37 +0000267 '-iwithprefixbefore']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000268 compile_opts.append(arg)
269 compile_opts.append(args[i+1])
270 i += 1
271
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000272 # Options with no arguments that should pass through
Daniel Dunbarcb529252008-10-15 21:52:00 +0000273 if (arg in ('-dynamiclib', '-bundle', '-headerpad_max_install_names',
274 '-nostdlib', '-static', '-dynamic', '-r') or
Daniel Dunbar1bf3f732008-10-01 01:10:22 +0000275 arg.startswith('-Wl,')):
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000276 link_opts.append(arg)
277
Nuno Lopese5d12e82008-06-17 17:23:14 +0000278 # Options with one argument that should pass through
Daniel Dunbar75e05712008-09-12 19:42:28 +0000279 if arg in ('-framework', '-multiply_defined', '-bundle_loader',
Daniel Dunbarfa538e72008-10-19 02:41:16 +0000280 '-weak_framework',
Daniel Dunbar319e7922008-09-30 22:54:22 +0000281 '-e', '-install_name',
282 '-unexported_symbols_list', '-exported_symbols_list',
283 '-compatibility_version', '-current_version', '-init',
Anders Carlssone90b0ac2009-01-05 01:24:39 +0000284 '-seg1addr', '-dylib_file', '-Xlinker', '-undefined'):
Nuno Lopese5d12e82008-06-17 17:23:14 +0000285 link_opts.append(arg)
286 link_opts.append(args[i+1])
287 i += 1
288
289 # Options with one argument that should pass through to both
290 if arg in ['-isysroot', '-arch']:
291 compile_opts.append(arg)
292 compile_opts.append(args[i+1])
293 link_opts.append(arg)
294 link_opts.append(args[i+1])
Daniel Dunbar91dce082009-01-07 00:03:20 +0000295 asm_opts.append(arg)
296 asm_opts.append(args[i+1])
Nuno Lopese5d12e82008-06-17 17:23:14 +0000297 i += 1
Daniel Dunbar75e05712008-09-12 19:42:28 +0000298
299 # Options with three arguments that should pass through
300 if arg in ('-sectorder',):
301 link_opts.extend(args[i:i+4])
302 i += 3
Nuno Lopese5d12e82008-06-17 17:23:14 +0000303
Anders Carlssond125bb12008-01-29 07:21:34 +0000304 # Prefix matches for the link mode
Nuno Lopes9a184482008-08-10 21:58:01 +0000305 if arg[:2] in ['-l', '-L', '-F', '-R']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000306 link_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000307
Chris Lattnercf719b72008-06-21 17:46:11 +0000308 # Enable threads
309 if arg == '-pthread':
310 link_opts.append('-lpthread')
311
Anders Carlssond125bb12008-01-29 07:21:34 +0000312 # Input files
313 if arg == '-filelist':
314 f = open(args[i+1])
315 for line in f:
316 files.append(line.strip())
317 f.close()
318 i += 1
319 if arg == '-x':
320 language = args[i+1]
Fariborz Jahanian9142bc92009-02-03 23:59:32 +0000321 compile_opts.append(arg)
322 compile_opts.append(args[i+1])
Anders Carlssond125bb12008-01-29 07:21:34 +0000323 i += 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000324 if arg[0] != '-':
325 files.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000326
327 # Output file
328 if arg == '-o':
329 output = args[i+1]
330 i += 1
331
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000332 i += 1
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000333
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000334 if action == 'print-prog-name':
335 # assume we can handle everything
336 print sys.argv[0]
337 return
338
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000339 if not files:
340 error('no input files')
341
Anders Carlssond125bb12008-01-29 07:21:34 +0000342 if action == 'preprocess' or save_temps:
343 for i, file in enumerate(files):
344 if not language:
345 language = inferlanguage(extension(file))
346 if save_temps and action != 'preprocess':
347 # Need a temporary output file
348 if language == 'c':
349 poutput = changeextension(file, "i");
350 elif language == 'objective-c':
351 poutput = changeextension(file, "mi");
352 else:
353 poutput = changeextension(file, "tmp." + extension(file))
354 files[i] = poutput
355 else:
356 poutput = output
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000357 args = []
358 if language:
359 args.extend(['-x', language])
Anders Carlssond125bb12008-01-29 07:21:34 +0000360 if poutput:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000361 args += ['-o', poutput, file] + compile_opts
Anders Carlssond125bb12008-01-29 07:21:34 +0000362 else:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000363 args += [file] + compile_opts
Anders Carlssond125bb12008-01-29 07:21:34 +0000364 preprocess(args)
365 # Discard the explicit language after used once
366 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000367
Daniel Dunbarcb529252008-10-15 21:52:00 +0000368 if action == 'syntax-only':
369 for i, file in enumerate(files):
370 if not language:
371 language = inferlanguage(extension(file))
372 args = []
373 if language:
374 args.extend(['-x', language])
375 args += [file] + compile_opts
376 syntaxonly(args)
377 language = ''
378
Anders Carlssond125bb12008-01-29 07:21:34 +0000379 if action == 'compile' or save_temps:
380 for i, file in enumerate(files):
381 if not language:
382 language = inferlanguage(extension(file))
383 if save_temps and action != "compile":
384 # Need a temporary output file
385 coutput = changeextension(file, "o");
386 files[i] = coutput
387 elif not output:
388 coutput = changeextension(file, "o")
389 else:
390 coutput = output
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000391 args = []
392 if language:
393 args.extend(['-x', language])
394 args += ['-o', coutput, file] + compile_opts
Daniel Dunbar91dce082009-01-07 00:03:20 +0000395 checked_compile(args, native, language, save_temps, asm_opts)
Anders Carlssond125bb12008-01-29 07:21:34 +0000396 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000397
398 if action == 'link':
399 for i, file in enumerate(files):
Daniel Dunbard3d81412008-08-29 21:03:27 +0000400 if not language:
401 language = inferlanguage(extension(file))
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000402 ext = extension(file)
Nuno Lopesc46cf492008-08-10 22:17:57 +0000403 if ext != "o" and ext != "a" and ext != "so":
Anders Carlssond125bb12008-01-29 07:21:34 +0000404 out = changeextension(file, "o")
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000405 args = []
406 if language:
407 args.extend(['-x', language])
408 args = ['-o', out, file] + compile_opts
Daniel Dunbar91dce082009-01-07 00:03:20 +0000409 checked_compile(args, native, language, save_temps, asm_opts)
Daniel Dunbard3d81412008-08-29 21:03:27 +0000410 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000411 files[i] = out
412 if not output:
413 output = 'a.out'
Daniel Dunbar1b6ff6f2008-11-18 17:38:30 +0000414 args = ['-o', output] + files + link_opts
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000415 link(args, native)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000416
417if __name__ == '__main__':
418 main(sys.argv[1:])