blob: b9d4652273f8f9b4efd0f0e9a72f0ffa5dcd729b [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):
Anders Carlssondac2b542008-02-06 19:03:27 +000038 command = 'llvm-ld -native'.split()
39 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"
57 elif extension == "i":
58 return "c-cpp-output"
59 elif extension == "m":
60 return "objective-c"
61 elif extension == "mi":
62 return "objective-c-cpp-output"
63 else:
64 return "unknown"
65
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000066def main(args):
67 action = 'link'
68 output = ''
Seo Sanghyeon96b99f72008-01-25 14:57:54 +000069 compile_opts = []
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000070 link_opts = []
71 files = []
Anders Carlssond125bb12008-01-29 07:21:34 +000072 save_temps = 0
73 language = ''
74
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000075 i = 0
76 while i < len(args):
77 arg = args[i]
Anders Carlssond125bb12008-01-29 07:21:34 +000078
79 # Modes ccc supports
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000080 if arg == '-E':
81 action = 'preprocess'
82 if arg == '-c':
83 action = 'compile'
Seo Sanghyeon96b99f72008-01-25 14:57:54 +000084 if arg.startswith('-print-prog-name'):
85 action = 'print-prog-name'
Anders Carlssond125bb12008-01-29 07:21:34 +000086 if arg == '-save-temps':
87 save_temps = 1
88
89 # Options with no arguments that should pass through
90 if arg in ['-v']:
91 compile_opts.append(arg)
92 link_opts.append(arg)
93
94 # Options with one argument that should be ignored
Anders Carlssonc720d9b2008-01-31 23:48:19 +000095 if arg in ['--param', '-arch', '-u']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000096 i += 1
Anders Carlssond125bb12008-01-29 07:21:34 +000097
98 # Prefix matches for the compile mode
99 if arg[:2] in ['-D', '-I', '-U', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000100 if not arg[2:]:
101 arg += args[i+1]
102 i += 1
103 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000104 if arg[:5] in ['-std=']:
105 compile_opts.append(arg)
106
107 # Options with one argument that should pass through
108 if arg in ['-include']:
109 compile_opts.append(arg)
110 compile_opts.append(args[i+1])
111 i += 1
112
113 # Prefix matches for the link mode
114 if arg[:2] in ['-l', '-L', '-O', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000115 if arg == '-O': arg = '-O1'
116 if arg == '-Os': arg = '-O2'
117 link_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000118
119 # Options with one argument that should pass through
120 if arg in ['-framework']:
121 link_opts.append(arg)
122 link_opts.append(args[i+1])
123 i += 1
124
125 # Input files
126 if arg == '-filelist':
127 f = open(args[i+1])
128 for line in f:
129 files.append(line.strip())
130 f.close()
131 i += 1
132 if arg == '-x':
133 language = args[i+1]
134 i += 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000135 if arg[0] != '-':
136 files.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000137
138 # Output file
139 if arg == '-o':
140 output = args[i+1]
141 i += 1
142
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000143 i += 1
144
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000145 if action == 'print-prog-name':
146 # assume we can handle everything
147 print sys.argv[0]
148 return
149
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000150 if not files:
151 error('no input files')
152
Anders Carlssond125bb12008-01-29 07:21:34 +0000153 if action == 'preprocess' or save_temps:
154 for i, file in enumerate(files):
155 if not language:
156 language = inferlanguage(extension(file))
157 if save_temps and action != 'preprocess':
158 # Need a temporary output file
159 if language == 'c':
160 poutput = changeextension(file, "i");
161 elif language == 'objective-c':
162 poutput = changeextension(file, "mi");
163 else:
164 poutput = changeextension(file, "tmp." + extension(file))
165 files[i] = poutput
166 else:
167 poutput = output
168 if poutput:
169 args = ['-x', language, '-o', poutput, file] + compile_opts
170 else:
171 args = ['-x', language, file] + compile_opts
172 preprocess(args)
173 # Discard the explicit language after used once
174 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000175
Anders Carlssond125bb12008-01-29 07:21:34 +0000176 if action == 'compile' or save_temps:
177 for i, file in enumerate(files):
178 if not language:
179 language = inferlanguage(extension(file))
180 if save_temps and action != "compile":
181 # Need a temporary output file
182 coutput = changeextension(file, "o");
183 files[i] = coutput
184 elif not output:
185 coutput = changeextension(file, "o")
186 else:
187 coutput = output
188 args = ['-x', language, '-o', coutput, file] + compile_opts
189 compile(args)
190 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000191
192 if action == 'link':
193 for i, file in enumerate(files):
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000194 ext = extension(file)
195 if ext != "o" and ext != "a":
Anders Carlssond125bb12008-01-29 07:21:34 +0000196 out = changeextension(file, "o")
197 args = ['-o', out, file] + compile_opts
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000198 compile(args)
199 files[i] = out
200 if not output:
201 output = 'a.out'
202 args = ['-o', output] + link_opts + files
203 link(args)
204
205if __name__ == '__main__':
206 main(sys.argv[1:])