blob: 68081222a856c2451c40adad48d12035aa9f8176 [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
Seo Sanghyeond3894652008-04-04 11:02:21 +000021def quote(arg):
22 if '"' in arg:
23 return repr(arg)
24 return arg
25
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000026def run(args):
Seo Sanghyeond3894652008-04-04 11:02:21 +000027 print ' '.join(map(quote, args))
Anders Carlssondac2b542008-02-06 19:03:27 +000028 code = subprocess.call(args)
Bill Wendling550ce0f2008-02-03 21:27:46 +000029 if code > 255:
30 code = 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000031 if code:
32 sys.exit(code)
33
34def preprocess(args):
Anders Carlssondac2b542008-02-06 19:03:27 +000035 command = 'clang -E'.split()
36 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000037
38def compile(args):
Anders Carlssondac2b542008-02-06 19:03:27 +000039 command = 'clang -emit-llvm-bc'.split()
40 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000041
42def link(args):
Lauro Ramos Venanciode808ca2008-02-27 18:46:32 +000043 command = 'llvm-ld -native -disable-internalize'.split()
Anders Carlssondac2b542008-02-06 19:03:27 +000044 run(command + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000045
Anders Carlssond125bb12008-01-29 07:21:34 +000046def extension(path):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000047 return path.split(".")[-1]
Anders Carlssond125bb12008-01-29 07:21:34 +000048
49def changeextension(path, newext):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000050 i = path.rfind('.')
51 if i < 0:
52 return path
Bill Wendling550ce0f2008-02-03 21:27:46 +000053 j = path.rfind('/', 0, i)
54 print path
55 if j < 0:
56 return path[:i] + "." + newext
57 return path[j+1:i] + "." + newext
Anders Carlssond125bb12008-01-29 07:21:34 +000058
59def inferlanguage(extension):
60 if extension == "c":
61 return "c"
Lauro Ramos Venancio279876b2008-02-15 22:35:25 +000062 elif extension in ["cpp", "cc"]:
63 return "c++"
Anders Carlssond125bb12008-01-29 07:21:34 +000064 elif extension == "i":
65 return "c-cpp-output"
66 elif extension == "m":
67 return "objective-c"
68 elif extension == "mi":
69 return "objective-c-cpp-output"
70 else:
71 return "unknown"
72
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000073def main(args):
74 action = 'link'
75 output = ''
Seo Sanghyeon96b99f72008-01-25 14:57:54 +000076 compile_opts = []
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000077 link_opts = []
78 files = []
Anders Carlssond125bb12008-01-29 07:21:34 +000079 save_temps = 0
80 language = ''
81
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000082 i = 0
83 while i < len(args):
84 arg = args[i]
Anders Carlssond125bb12008-01-29 07:21:34 +000085
86 # Modes ccc supports
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000087 if arg == '-E':
88 action = 'preprocess'
89 if arg == '-c':
90 action = 'compile'
Seo Sanghyeon96b99f72008-01-25 14:57:54 +000091 if arg.startswith('-print-prog-name'):
92 action = 'print-prog-name'
Anders Carlssond125bb12008-01-29 07:21:34 +000093 if arg == '-save-temps':
94 save_temps = 1
95
96 # Options with no arguments that should pass through
97 if arg in ['-v']:
98 compile_opts.append(arg)
99 link_opts.append(arg)
100
101 # Options with one argument that should be ignored
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000102 if arg in ['--param', '-arch', '-u']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000103 i += 1
Anders Carlssond125bb12008-01-29 07:21:34 +0000104
105 # Prefix matches for the compile mode
106 if arg[:2] in ['-D', '-I', '-U', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000107 if not arg[2:]:
108 arg += args[i+1]
109 i += 1
110 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000111 if arg[:5] in ['-std=']:
112 compile_opts.append(arg)
113
114 # Options with one argument that should pass through
Ted Kremenek39a79732008-04-19 18:42:26 +0000115 if arg in ['-include', '-isysroot']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000116 compile_opts.append(arg)
117 compile_opts.append(args[i+1])
118 i += 1
119
120 # Prefix matches for the link mode
121 if arg[:2] in ['-l', '-L', '-O', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000122 if arg == '-O': arg = '-O1'
123 if arg == '-Os': arg = '-O2'
124 link_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000125
126 # Options with one argument that should pass through
Ted Kremenek39a79732008-04-19 18:42:26 +0000127 if arg in ['-framework', '-isysroot']:
Anders Carlssond125bb12008-01-29 07:21:34 +0000128 link_opts.append(arg)
129 link_opts.append(args[i+1])
130 i += 1
131
132 # Input files
133 if arg == '-filelist':
134 f = open(args[i+1])
135 for line in f:
136 files.append(line.strip())
137 f.close()
138 i += 1
139 if arg == '-x':
140 language = args[i+1]
141 i += 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000142 if arg[0] != '-':
143 files.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000144
145 # Output file
146 if arg == '-o':
147 output = args[i+1]
148 i += 1
149
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000150 i += 1
151
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000152 if action == 'print-prog-name':
153 # assume we can handle everything
154 print sys.argv[0]
155 return
156
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000157 if not files:
158 error('no input files')
159
Anders Carlssond125bb12008-01-29 07:21:34 +0000160 if action == 'preprocess' or save_temps:
161 for i, file in enumerate(files):
162 if not language:
163 language = inferlanguage(extension(file))
164 if save_temps and action != 'preprocess':
165 # Need a temporary output file
166 if language == 'c':
167 poutput = changeextension(file, "i");
168 elif language == 'objective-c':
169 poutput = changeextension(file, "mi");
170 else:
171 poutput = changeextension(file, "tmp." + extension(file))
172 files[i] = poutput
173 else:
174 poutput = output
175 if poutput:
176 args = ['-x', language, '-o', poutput, file] + compile_opts
177 else:
178 args = ['-x', language, file] + compile_opts
179 preprocess(args)
180 # Discard the explicit language after used once
181 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000182
Anders Carlssond125bb12008-01-29 07:21:34 +0000183 if action == 'compile' or save_temps:
184 for i, file in enumerate(files):
185 if not language:
186 language = inferlanguage(extension(file))
187 if save_temps and action != "compile":
188 # Need a temporary output file
189 coutput = changeextension(file, "o");
190 files[i] = coutput
191 elif not output:
192 coutput = changeextension(file, "o")
193 else:
194 coutput = output
195 args = ['-x', language, '-o', coutput, file] + compile_opts
196 compile(args)
197 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000198
199 if action == 'link':
200 for i, file in enumerate(files):
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000201 ext = extension(file)
202 if ext != "o" and ext != "a":
Anders Carlssond125bb12008-01-29 07:21:34 +0000203 out = changeextension(file, "o")
204 args = ['-o', out, file] + compile_opts
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000205 compile(args)
206 files[i] = out
207 if not output:
208 output = 'a.out'
209 args = ['-o', output] + link_opts + files
210 link(args)
211
212if __name__ == '__main__':
213 main(sys.argv[1:])