blob: a826b005a07cdd58fa6582bf91bf6fe426abfb93 [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
35CCC_ECHO = checkbool('CCC_ECHO')
36CCC_NATIVE = checkbool('CCC_NATIVE','1')
37CCC_FALLBACK = checkbool('CCC_FALLBACK')
Nuno Lopes24653e82008-09-02 10:27:37 +000038CCC_LANGUAGES = checkenv('CCC_LANGUAGES','c,c++,c-cpp-output,objective-c,objective-c++,objective-c-cpp-output')
Daniel Dunbard3d81412008-08-29 21:03:27 +000039if CCC_LANGUAGES:
40 CCC_LANGUAGES = set([s.strip() for s in CCC_LANGUAGES.split(',')])
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000041
42# We want to support use as CC or LD, so we need different defines.
43CLANG = checkenv('CLANG', 'clang')
44LLC = checkenv('LLC', 'llc')
45AS = checkenv('AS', 'as')
46CC = checkenv('CCC_CC', 'cc')
47LD = checkenv('CCC_LD', 'c++')
48
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000049def error(message):
Anders Carlssond125bb12008-01-29 07:21:34 +000050 print >> sys.stderr, 'ccc: ' + message
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000051 sys.exit(1)
52
Seo Sanghyeond3894652008-04-04 11:02:21 +000053def quote(arg):
Daniel Dunbard3d81412008-08-29 21:03:27 +000054 if '"' in arg or ' ' in arg:
Seo Sanghyeond3894652008-04-04 11:02:21 +000055 return repr(arg)
56 return arg
57
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000058def stripoutput(args):
59 """stripoutput(args) -> (output_name, newargs)
60
61 Remove the -o argument from the arg list and return the output
62 filename and a new argument list. Assumes there will be at most
63 one -o option. If no output argument is found the result is (None,
64 args)."""
65 for i,a in enumerate(args):
66 if a.startswith('-o'):
67 if a=='-o':
68 if i+1<len(args):
69 return args[i+1],args[:i]+args[i+2:]
70 elif a.startswith('-o='):
71 opt,arg = a.split('=',1)
72 return arg,args[:i]+args[i+1:]
73 return None,args
74
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000075def run(args):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000076 if CCC_ECHO:
77 print ' '.join(map(quote, args))
Daniel Dunbard3d81412008-08-29 21:03:27 +000078 sys.stdout.flush()
Anders Carlssondac2b542008-02-06 19:03:27 +000079 code = subprocess.call(args)
Bill Wendling550ce0f2008-02-03 21:27:46 +000080 if code > 255:
81 code = 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000082 if code:
83 sys.exit(code)
84
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000085def remove(path):
86 """remove(path) -> bool - Attempt to remove the file at path (if any).
87
88 The result indicates if the remove was successful. A warning is
89 printed if there is an error removing the file."""
90 if os.path.exists(path):
91 try:
92 os.remove(path)
93 except:
94 print >>sys.stderr, 'WARNING: Unable to remove temp "%s"'%(path,)
95 return False
96 return True
97
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000098def preprocess(args):
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +000099 command = [CLANG,'-E']
Anders Carlssondac2b542008-02-06 19:03:27 +0000100 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000101
Daniel Dunbard3d81412008-08-29 21:03:27 +0000102def compile_fallback(args):
103 command = [CC,'-c']
104 run(command + args)
105
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000106def compile(args, native, save_temps=False):
107 if native:
108 output,args = stripoutput(args)
109 if not output:
110 raise ValueError,'Expected to always have explicit -o in compile()'
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000111
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000112 # I prefer suffixing these to changing the extension, which is
113 # more likely to overwrite other things. We could of course
114 # use temp files.
115 bc_output = output + '.bc'
116 s_output = output + '.s'
117 command = [CLANG,'-emit-llvm-bc']
Daniel Dunbard3d81412008-08-29 21:03:27 +0000118 try:
119 run(command + args + ['-o', bc_output])
120 # FIXME: What controls relocation model?
121 run([LLC, '-relocation-model=pic', '-f', '-o', s_output, bc_output])
122 run([AS, '-o', output, s_output])
123 finally:
124 if not save_temps:
125 remove(bc_output)
126 remove(s_output)
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000127 else:
128 command = [CLANG,'-emit-llvm-bc']
129 run(command + args)
130
Daniel Dunbard3d81412008-08-29 21:03:27 +0000131def checked_compile(args, native, language, save_temps):
132 if CCC_LANGUAGES and language and language not in CCC_LANGUAGES:
133 print >>sys.stderr, 'NOTE: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
134 compile_fallback(args)
135 elif CCC_FALLBACK:
136 try:
137 compile(args, native, save_temps)
138 except:
139 print >>sys.stderr, 'WARNING: ccc: Using fallback compiler for: %s'%(' '.join(map(quote, args)),)
140 compile_fallback(args)
141 else:
142 compile(args, native, save_temps)
143
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000144def link(args, native):
145 if native:
Daniel Dunbard3d81412008-08-29 21:03:27 +0000146 run([LD] + args)
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000147 else:
148 command = ['llvm-ld', '-native', '-disable-internalize']
149 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000150
Anders Carlssond125bb12008-01-29 07:21:34 +0000151def extension(path):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +0000152 return path.split(".")[-1]
Anders Carlssond125bb12008-01-29 07:21:34 +0000153
154def changeextension(path, newext):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +0000155 i = path.rfind('.')
156 if i < 0:
157 return path
Bill Wendling550ce0f2008-02-03 21:27:46 +0000158 j = path.rfind('/', 0, i)
Bill Wendling550ce0f2008-02-03 21:27:46 +0000159 if j < 0:
160 return path[:i] + "." + newext
161 return path[j+1:i] + "." + newext
Anders Carlssond125bb12008-01-29 07:21:34 +0000162
163def inferlanguage(extension):
164 if extension == "c":
165 return "c"
Lauro Ramos Venancio279876b2008-02-15 22:35:25 +0000166 elif extension in ["cpp", "cc"]:
167 return "c++"
Anders Carlssond125bb12008-01-29 07:21:34 +0000168 elif extension == "i":
169 return "c-cpp-output"
170 elif extension == "m":
171 return "objective-c"
Daniel Dunbard3d81412008-08-29 21:03:27 +0000172 elif extension == "mm":
173 return "objective-c++"
Anders Carlssond125bb12008-01-29 07:21:34 +0000174 elif extension == "mi":
175 return "objective-c-cpp-output"
Nuno Lopes24653e82008-09-02 10:27:37 +0000176 elif extension == "s":
177 return "assembler"
178 elif extension == "S":
179 return "assembler-with-cpp"
Anders Carlssond125bb12008-01-29 07:21:34 +0000180 else:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000181 return ""
Anders Carlssond125bb12008-01-29 07:21:34 +0000182
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000183def inferaction(args):
184 if '-E' in args:
185 return 'preprocess'
186 if '-c' in args:
187 return 'compile'
188 for arg in args:
189 if arg.startswith('-print-prog-name'):
190 return 'pring-prog-name'
191 return 'link'
192
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000193def main(args):
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000194 action = inferaction(args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000195 output = ''
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000196 compile_opts = []
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000197 link_opts = []
198 files = []
Anders Carlssond125bb12008-01-29 07:21:34 +0000199 save_temps = 0
200 language = ''
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000201 native = CCC_NATIVE
202
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000203 i = 0
204 while i < len(args):
205 arg = args[i]
Anders Carlssond125bb12008-01-29 07:21:34 +0000206
Daniel Dunbar319e7922008-09-30 22:54:22 +0000207 if '=' in arg:
208 argkey,argvalue = arg.split('=',1)
209 else:
210 argkey,argvalue = arg,None
211
Anders Carlssond125bb12008-01-29 07:21:34 +0000212 # Modes ccc supports
Anders Carlssond125bb12008-01-29 07:21:34 +0000213 if arg == '-save-temps':
214 save_temps = 1
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000215 if arg == '-emit-llvm' or arg == '--emit-llvm':
216 native = False
Anders Carlssond125bb12008-01-29 07:21:34 +0000217
218 # Options with no arguments that should pass through
Daniel Dunbard3d81412008-08-29 21:03:27 +0000219 if arg in ['-v', '-fobjc-gc', '-fobjc-gc-only', '-fnext-runtime',
220 '-fgnu-runtime']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000221 compile_opts.append(arg)
222 link_opts.append(arg)
223
224 # Options with one argument that should be ignored
Ted Kremenekd0eef022008-04-21 20:28:01 +0000225 if arg in ['--param', '-u']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000226 i += 1
Anders Carlssond125bb12008-01-29 07:21:34 +0000227
Ted Kremenek16833602008-07-24 03:49:15 +0000228 # Preprocessor options with one argument that should be ignored
229 if arg in ['-MT', '-MF']:
230 i += 1
231
Anders Carlssond125bb12008-01-29 07:21:34 +0000232 # Prefix matches for the compile mode
233 if arg[:2] in ['-D', '-I', '-U', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000234 if not arg[2:]:
235 arg += args[i+1]
236 i += 1
237 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000238 if arg[:5] in ['-std=']:
239 compile_opts.append(arg)
Daniel Dunbar8e45f732008-10-02 17:26:37 +0000240 if argkey in ('-std', '-mmacosx-version-min'):
241 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000242
Nuno Lopese5d12e82008-06-17 17:23:14 +0000243 # Options with one argument that should pass through to compiler
Daniel Dunbar8e45f732008-10-02 17:26:37 +0000244 if arg in [ '-include', '-idirafter', '-iprefix',
Daniel Dunbar319e7922008-09-30 22:54:22 +0000245 '-iquote', '-isystem', '-iwithprefix',
Daniel Dunbar8e45f732008-10-02 17:26:37 +0000246 '-iwithprefixbefore']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000247 compile_opts.append(arg)
248 compile_opts.append(args[i+1])
249 i += 1
250
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000251 # Options with no arguments that should pass through
Daniel Dunbar1bf3f732008-10-01 01:10:22 +0000252 if (arg in ('-dynamiclib', '-bundle', '-headerpad_max_install_names') or
253 arg.startswith('-Wl,')):
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000254 link_opts.append(arg)
255
Nuno Lopese5d12e82008-06-17 17:23:14 +0000256 # Options with one argument that should pass through
Daniel Dunbar75e05712008-09-12 19:42:28 +0000257 if arg in ('-framework', '-multiply_defined', '-bundle_loader',
Daniel Dunbar319e7922008-09-30 22:54:22 +0000258 '-e', '-install_name',
259 '-unexported_symbols_list', '-exported_symbols_list',
260 '-compatibility_version', '-current_version', '-init',
261 '-seg1addr', '-dylib_file'):
Nuno Lopese5d12e82008-06-17 17:23:14 +0000262 link_opts.append(arg)
263 link_opts.append(args[i+1])
264 i += 1
265
266 # Options with one argument that should pass through to both
267 if arg in ['-isysroot', '-arch']:
268 compile_opts.append(arg)
269 compile_opts.append(args[i+1])
270 link_opts.append(arg)
271 link_opts.append(args[i+1])
272 i += 1
Daniel Dunbar75e05712008-09-12 19:42:28 +0000273
274 # Options with three arguments that should pass through
275 if arg in ('-sectorder',):
276 link_opts.extend(args[i:i+4])
277 i += 3
Nuno Lopese5d12e82008-06-17 17:23:14 +0000278
Anders Carlssond125bb12008-01-29 07:21:34 +0000279 # Prefix matches for the link mode
Nuno Lopes9a184482008-08-10 21:58:01 +0000280 if arg[:2] in ['-l', '-L', '-F', '-R']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000281 link_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000282
Chris Lattnercf719b72008-06-21 17:46:11 +0000283 # Enable threads
284 if arg == '-pthread':
285 link_opts.append('-lpthread')
286
Anders Carlssond125bb12008-01-29 07:21:34 +0000287 # Input files
288 if arg == '-filelist':
289 f = open(args[i+1])
290 for line in f:
291 files.append(line.strip())
292 f.close()
293 i += 1
294 if arg == '-x':
295 language = args[i+1]
296 i += 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000297 if arg[0] != '-':
298 files.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000299
300 # Output file
301 if arg == '-o':
302 output = args[i+1]
303 i += 1
304
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000305 i += 1
Daniel Dunbar869f8b62008-09-30 21:20:51 +0000306
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000307 if action == 'print-prog-name':
308 # assume we can handle everything
309 print sys.argv[0]
310 return
311
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000312 if not files:
313 error('no input files')
314
Anders Carlssond125bb12008-01-29 07:21:34 +0000315 if action == 'preprocess' or save_temps:
316 for i, file in enumerate(files):
317 if not language:
318 language = inferlanguage(extension(file))
319 if save_temps and action != 'preprocess':
320 # Need a temporary output file
321 if language == 'c':
322 poutput = changeextension(file, "i");
323 elif language == 'objective-c':
324 poutput = changeextension(file, "mi");
325 else:
326 poutput = changeextension(file, "tmp." + extension(file))
327 files[i] = poutput
328 else:
329 poutput = output
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000330 args = []
331 if language:
332 args.extend(['-x', language])
Anders Carlssond125bb12008-01-29 07:21:34 +0000333 if poutput:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000334 args += ['-o', poutput, file] + compile_opts
Anders Carlssond125bb12008-01-29 07:21:34 +0000335 else:
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000336 args += [file] + compile_opts
Anders Carlssond125bb12008-01-29 07:21:34 +0000337 preprocess(args)
338 # Discard the explicit language after used once
339 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000340
Anders Carlssond125bb12008-01-29 07:21:34 +0000341 if action == 'compile' or save_temps:
342 for i, file in enumerate(files):
343 if not language:
344 language = inferlanguage(extension(file))
345 if save_temps and action != "compile":
346 # Need a temporary output file
347 coutput = changeextension(file, "o");
348 files[i] = coutput
349 elif not output:
350 coutput = changeextension(file, "o")
351 else:
352 coutput = output
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000353 args = []
354 if language:
355 args.extend(['-x', language])
356 args += ['-o', coutput, file] + compile_opts
Daniel Dunbard3d81412008-08-29 21:03:27 +0000357 checked_compile(args, native, language, save_temps)
Anders Carlssond125bb12008-01-29 07:21:34 +0000358 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000359
360 if action == 'link':
361 for i, file in enumerate(files):
Daniel Dunbard3d81412008-08-29 21:03:27 +0000362 if not language:
363 language = inferlanguage(extension(file))
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000364 ext = extension(file)
Nuno Lopesc46cf492008-08-10 22:17:57 +0000365 if ext != "o" and ext != "a" and ext != "so":
Anders Carlssond125bb12008-01-29 07:21:34 +0000366 out = changeextension(file, "o")
Daniel Dunbar7000bf82008-09-30 16:18:31 +0000367 args = []
368 if language:
369 args.extend(['-x', language])
370 args = ['-o', out, file] + compile_opts
Daniel Dunbard3d81412008-08-29 21:03:27 +0000371 checked_compile(args, native, language, save_temps)
372 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000373 files[i] = out
374 if not output:
375 output = 'a.out'
376 args = ['-o', output] + link_opts + files
Daniel Dunbar4b5c4f22008-08-23 22:15:15 +0000377 link(args, native)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000378
379if __name__ == '__main__':
380 main(sys.argv[1:])