blob: f902313731ae993a1e38ccfd57e118fa39d56602 [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
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000014import os
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000015import sys
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):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000022 cmd = ' '.join(args)
23 print >> sys.stderr, cmd
24 code = os.system(cmd)
Bill Wendling550ce0f2008-02-03 21:27:46 +000025 if code > 255:
26 code = 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000027 if code:
28 sys.exit(code)
29
30def preprocess(args):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000031 run(['clang -E'] + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000032
33def compile(args):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000034 run(['clang -emit-llvm-bc'] + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000035
36def link(args):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000037 run(['llvm-ld -native'] + args)
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000038
Anders Carlssond125bb12008-01-29 07:21:34 +000039def extension(path):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000040 return path.split(".")[-1]
Anders Carlssond125bb12008-01-29 07:21:34 +000041
42def changeextension(path, newext):
Seo Sanghyeon795aaed2008-02-03 03:40:41 +000043 i = path.rfind('.')
44 if i < 0:
45 return path
Bill Wendling550ce0f2008-02-03 21:27:46 +000046 j = path.rfind('/', 0, i)
47 print path
48 if j < 0:
49 return path[:i] + "." + newext
50 return path[j+1:i] + "." + newext
Anders Carlssond125bb12008-01-29 07:21:34 +000051
52def inferlanguage(extension):
53 if extension == "c":
54 return "c"
55 elif extension == "i":
56 return "c-cpp-output"
57 elif extension == "m":
58 return "objective-c"
59 elif extension == "mi":
60 return "objective-c-cpp-output"
61 else:
62 return "unknown"
63
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000064def main(args):
65 action = 'link'
66 output = ''
Seo Sanghyeon96b99f72008-01-25 14:57:54 +000067 compile_opts = []
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000068 link_opts = []
69 files = []
Anders Carlssond125bb12008-01-29 07:21:34 +000070 save_temps = 0
71 language = ''
72
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000073 i = 0
74 while i < len(args):
75 arg = args[i]
Anders Carlssond125bb12008-01-29 07:21:34 +000076
77 # Modes ccc supports
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000078 if arg == '-E':
79 action = 'preprocess'
80 if arg == '-c':
81 action = 'compile'
Seo Sanghyeon96b99f72008-01-25 14:57:54 +000082 if arg.startswith('-print-prog-name'):
83 action = 'print-prog-name'
Anders Carlssond125bb12008-01-29 07:21:34 +000084 if arg == '-save-temps':
85 save_temps = 1
86
87 # Options with no arguments that should pass through
88 if arg in ['-v']:
89 compile_opts.append(arg)
90 link_opts.append(arg)
91
92 # Options with one argument that should be ignored
Anders Carlssonc720d9b2008-01-31 23:48:19 +000093 if arg in ['--param', '-arch', '-u']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000094 i += 1
Anders Carlssond125bb12008-01-29 07:21:34 +000095
96 # Prefix matches for the compile mode
97 if arg[:2] in ['-D', '-I', '-U', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +000098 if not arg[2:]:
99 arg += args[i+1]
100 i += 1
101 compile_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000102 if arg[:5] in ['-std=']:
103 compile_opts.append(arg)
104
105 # Options with one argument that should pass through
106 if arg in ['-include']:
107 compile_opts.append(arg)
108 compile_opts.append(args[i+1])
109 i += 1
110
111 # Prefix matches for the link mode
112 if arg[:2] in ['-l', '-L', '-O', '-F']:
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000113 if arg == '-O': arg = '-O1'
114 if arg == '-Os': arg = '-O2'
115 link_opts.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000116
117 # Options with one argument that should pass through
118 if arg in ['-framework']:
119 link_opts.append(arg)
120 link_opts.append(args[i+1])
121 i += 1
122
123 # Input files
124 if arg == '-filelist':
125 f = open(args[i+1])
126 for line in f:
127 files.append(line.strip())
128 f.close()
129 i += 1
130 if arg == '-x':
131 language = args[i+1]
132 i += 1
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000133 if arg[0] != '-':
134 files.append(arg)
Anders Carlssond125bb12008-01-29 07:21:34 +0000135
136 # Output file
137 if arg == '-o':
138 output = args[i+1]
139 i += 1
140
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000141 i += 1
142
Seo Sanghyeon96b99f72008-01-25 14:57:54 +0000143 if action == 'print-prog-name':
144 # assume we can handle everything
145 print sys.argv[0]
146 return
147
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000148 if not files:
149 error('no input files')
150
Anders Carlssond125bb12008-01-29 07:21:34 +0000151 if action == 'preprocess' or save_temps:
152 for i, file in enumerate(files):
153 if not language:
154 language = inferlanguage(extension(file))
155 if save_temps and action != 'preprocess':
156 # Need a temporary output file
157 if language == 'c':
158 poutput = changeextension(file, "i");
159 elif language == 'objective-c':
160 poutput = changeextension(file, "mi");
161 else:
162 poutput = changeextension(file, "tmp." + extension(file))
163 files[i] = poutput
164 else:
165 poutput = output
166 if poutput:
167 args = ['-x', language, '-o', poutput, file] + compile_opts
168 else:
169 args = ['-x', language, file] + compile_opts
170 preprocess(args)
171 # Discard the explicit language after used once
172 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000173
Anders Carlssond125bb12008-01-29 07:21:34 +0000174 if action == 'compile' or save_temps:
175 for i, file in enumerate(files):
176 if not language:
177 language = inferlanguage(extension(file))
178 if save_temps and action != "compile":
179 # Need a temporary output file
180 coutput = changeextension(file, "o");
181 files[i] = coutput
182 elif not output:
183 coutput = changeextension(file, "o")
184 else:
185 coutput = output
186 args = ['-x', language, '-o', coutput, file] + compile_opts
187 compile(args)
188 language = ''
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000189
190 if action == 'link':
191 for i, file in enumerate(files):
Anders Carlssonc720d9b2008-01-31 23:48:19 +0000192 ext = extension(file)
193 if ext != "o" and ext != "a":
Anders Carlssond125bb12008-01-29 07:21:34 +0000194 out = changeextension(file, "o")
195 args = ['-o', out, file] + compile_opts
Seo Sanghyeon2bfa5332008-01-10 01:43:47 +0000196 compile(args)
197 files[i] = out
198 if not output:
199 output = 'a.out'
200 args = ['-o', output] + link_opts + files
201 link(args)
202
203if __name__ == '__main__':
204 main(sys.argv[1:])