annotate contrib/header-tools/reduce-headers @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents
children 1830386684a0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 #! /usr/bin/python2
kono
parents:
diff changeset
2 import os.path
kono
parents:
diff changeset
3 import sys
kono
parents:
diff changeset
4 import shlex
kono
parents:
diff changeset
5 import re
kono
parents:
diff changeset
6 import tempfile
kono
parents:
diff changeset
7 import copy
kono
parents:
diff changeset
8
kono
parents:
diff changeset
9 from headerutils import *
kono
parents:
diff changeset
10
kono
parents:
diff changeset
11 requires = { }
kono
parents:
diff changeset
12 provides = { }
kono
parents:
diff changeset
13
kono
parents:
diff changeset
14 no_remove = [ "system.h", "coretypes.h", "config.h" , "bconfig.h", "backend.h" ]
kono
parents:
diff changeset
15
kono
parents:
diff changeset
16 # These targets are the ones which provide "coverage". Typically, if any
kono
parents:
diff changeset
17 # target is going to fail compilation, it's one of these. This was determined
kono
parents:
diff changeset
18 # during the initial runs of reduce-headers... On a full set of target builds,
kono
parents:
diff changeset
19 # every failure which occured was triggered by one of these.
kono
parents:
diff changeset
20 # This list is used during target-list construction simply to put any of these
kono
parents:
diff changeset
21 # *first* in the candidate list, increasing the probability that a failure is
kono
parents:
diff changeset
22 # found quickly.
kono
parents:
diff changeset
23 target_priority = [
kono
parents:
diff changeset
24 "aarch64-linux-gnu",
kono
parents:
diff changeset
25 "arm-netbsdelf",
kono
parents:
diff changeset
26 "c6x-elf",
kono
parents:
diff changeset
27 "epiphany-elf",
kono
parents:
diff changeset
28 "hppa2.0-hpux10.1",
kono
parents:
diff changeset
29 "i686-mingw32crt",
kono
parents:
diff changeset
30 "i686-pc-msdosdjgpp",
kono
parents:
diff changeset
31 "mipsel-elf",
kono
parents:
diff changeset
32 "powerpc-eabisimaltivec",
kono
parents:
diff changeset
33 "rs6000-ibm-aix5.1.0",
kono
parents:
diff changeset
34 "sh-superh-elf",
kono
parents:
diff changeset
35 "sparc64-elf",
kono
parents:
diff changeset
36 "spu-elf"
kono
parents:
diff changeset
37 ]
kono
parents:
diff changeset
38
kono
parents:
diff changeset
39
kono
parents:
diff changeset
40 target_dir = ""
kono
parents:
diff changeset
41 build_dir = ""
kono
parents:
diff changeset
42 ignore_list = list()
kono
parents:
diff changeset
43 target_builds = list()
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 target_dict = { }
kono
parents:
diff changeset
46 header_dict = { }
kono
parents:
diff changeset
47 search_path = [ ".", "../include", "../libcpp/include" ]
kono
parents:
diff changeset
48
kono
parents:
diff changeset
49 remove_count = { }
kono
parents:
diff changeset
50
kono
parents:
diff changeset
51
kono
parents:
diff changeset
52 # Given a header name, normalize it. ie. cp/cp-tree.h could be in gcc, while
kono
parents:
diff changeset
53 # the same header could be referenced from within the cp subdirectory as
kono
parents:
diff changeset
54 # just cp-tree.h
kono
parents:
diff changeset
55 # for now, just assume basenames are unique
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 def normalize_header (header):
kono
parents:
diff changeset
58 return os.path.basename (header)
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60
kono
parents:
diff changeset
61 # Adds a header file and its sub-includes to the global dictionary if they
kono
parents:
diff changeset
62 # aren't already there. Specify s_path since different build directories may
kono
parents:
diff changeset
63 # append themselves on demand to the global list.
kono
parents:
diff changeset
64 # return entry for the specified header, knowing all sub entries are completed
kono
parents:
diff changeset
65
kono
parents:
diff changeset
66 def get_header_info (header, s_path):
kono
parents:
diff changeset
67 global header_dict
kono
parents:
diff changeset
68 global empty_iinfo
kono
parents:
diff changeset
69 process_list = list ()
kono
parents:
diff changeset
70 location = ""
kono
parents:
diff changeset
71 bname = ""
kono
parents:
diff changeset
72 bname_iinfo = empty_iinfo
kono
parents:
diff changeset
73 for path in s_path:
kono
parents:
diff changeset
74 if os.path.exists (path + "/" + header):
kono
parents:
diff changeset
75 location = path + "/" + header
kono
parents:
diff changeset
76 break
kono
parents:
diff changeset
77
kono
parents:
diff changeset
78 if location:
kono
parents:
diff changeset
79 bname = normalize_header (location)
kono
parents:
diff changeset
80 if header_dict.get (bname):
kono
parents:
diff changeset
81 bname_iinfo = header_dict[bname]
kono
parents:
diff changeset
82 loc2 = ii_path (bname_iinfo)+ "/" + bname
kono
parents:
diff changeset
83 if loc2[:2] == "./":
kono
parents:
diff changeset
84 loc2 = loc2[2:]
kono
parents:
diff changeset
85 if location[:2] == "./":
kono
parents:
diff changeset
86 location = location[2:]
kono
parents:
diff changeset
87 if loc2 != location:
kono
parents:
diff changeset
88 # Don't use the cache if it isnt the right one.
kono
parents:
diff changeset
89 bname_iinfo = process_ii_macro (location)
kono
parents:
diff changeset
90 return bname_iinfo
kono
parents:
diff changeset
91
kono
parents:
diff changeset
92 bname_iinfo = process_ii_macro (location)
kono
parents:
diff changeset
93 header_dict[bname] = bname_iinfo
kono
parents:
diff changeset
94 # now decend into the include tree
kono
parents:
diff changeset
95 for i in ii_include_list (bname_iinfo):
kono
parents:
diff changeset
96 get_header_info (i, s_path)
kono
parents:
diff changeset
97 else:
kono
parents:
diff changeset
98 # if the file isnt in the source directories, look in the build and target
kono
parents:
diff changeset
99 # directories. If it is here, then aggregate all the versions.
kono
parents:
diff changeset
100 location = build_dir + "/gcc/" + header
kono
parents:
diff changeset
101 build_inc = target_inc = False
kono
parents:
diff changeset
102 if os.path.exists (location):
kono
parents:
diff changeset
103 build_inc = True
kono
parents:
diff changeset
104 for x in target_dict:
kono
parents:
diff changeset
105 location = target_dict[x] + "/gcc/" + header
kono
parents:
diff changeset
106 if os.path.exists (location):
kono
parents:
diff changeset
107 target_inc = True
kono
parents:
diff changeset
108 break
kono
parents:
diff changeset
109
kono
parents:
diff changeset
110 if (build_inc or target_inc):
kono
parents:
diff changeset
111 bname = normalize_header(header)
kono
parents:
diff changeset
112 defines = set()
kono
parents:
diff changeset
113 consumes = set()
kono
parents:
diff changeset
114 incl = set()
kono
parents:
diff changeset
115 if build_inc:
kono
parents:
diff changeset
116 iinfo = process_ii_macro (build_dir + "/gcc/" + header)
kono
parents:
diff changeset
117 defines = set (ii_macro_define (iinfo))
kono
parents:
diff changeset
118 consumes = set (ii_macro_consume (iinfo))
kono
parents:
diff changeset
119 incl = set (ii_include_list (iinfo))
kono
parents:
diff changeset
120
kono
parents:
diff changeset
121 if (target_inc):
kono
parents:
diff changeset
122 for x in target_dict:
kono
parents:
diff changeset
123 location = target_dict[x] + "/gcc/" + header
kono
parents:
diff changeset
124 if os.path.exists (location):
kono
parents:
diff changeset
125 iinfo = process_ii_macro (location)
kono
parents:
diff changeset
126 defines.update (ii_macro_define (iinfo))
kono
parents:
diff changeset
127 consumes.update (ii_macro_consume (iinfo))
kono
parents:
diff changeset
128 incl.update (ii_include_list (iinfo))
kono
parents:
diff changeset
129
kono
parents:
diff changeset
130 bname_iinfo = (header, "build", list(incl), list(), list(consumes), list(defines), list(), list())
kono
parents:
diff changeset
131
kono
parents:
diff changeset
132 header_dict[bname] = bname_iinfo
kono
parents:
diff changeset
133 for i in incl:
kono
parents:
diff changeset
134 get_header_info (i, s_path)
kono
parents:
diff changeset
135
kono
parents:
diff changeset
136 return bname_iinfo
kono
parents:
diff changeset
137
kono
parents:
diff changeset
138
kono
parents:
diff changeset
139 # return a list of all headers brought in by this header
kono
parents:
diff changeset
140 def all_headers (fname):
kono
parents:
diff changeset
141 global header_dict
kono
parents:
diff changeset
142 headers_stack = list()
kono
parents:
diff changeset
143 headers_list = list()
kono
parents:
diff changeset
144 if header_dict.get (fname) == None:
kono
parents:
diff changeset
145 return list ()
kono
parents:
diff changeset
146 for y in ii_include_list (header_dict[fname]):
kono
parents:
diff changeset
147 headers_stack.append (y)
kono
parents:
diff changeset
148
kono
parents:
diff changeset
149 while headers_stack:
kono
parents:
diff changeset
150 h = headers_stack.pop ()
kono
parents:
diff changeset
151 hn = normalize_header (h)
kono
parents:
diff changeset
152 if hn not in headers_list:
kono
parents:
diff changeset
153 headers_list.append (hn)
kono
parents:
diff changeset
154 if header_dict.get(hn):
kono
parents:
diff changeset
155 for y in ii_include_list (header_dict[hn]):
kono
parents:
diff changeset
156 if normalize_header (y) not in headers_list:
kono
parents:
diff changeset
157 headers_stack.append (y)
kono
parents:
diff changeset
158
kono
parents:
diff changeset
159 return headers_list
kono
parents:
diff changeset
160
kono
parents:
diff changeset
161
kono
parents:
diff changeset
162
kono
parents:
diff changeset
163
kono
parents:
diff changeset
164 # Search bld_dir for all target tuples, confirm that they have a build path with
kono
parents:
diff changeset
165 # bld_dir/target-tuple/gcc, and build a dictionary of build paths indexed by
kono
parents:
diff changeset
166 # target tuple..
kono
parents:
diff changeset
167
kono
parents:
diff changeset
168 def build_target_dict (bld_dir, just_these):
kono
parents:
diff changeset
169 global target_dict
kono
parents:
diff changeset
170 target_doct = { }
kono
parents:
diff changeset
171 error = False
kono
parents:
diff changeset
172 if os.path.exists (bld_dir):
kono
parents:
diff changeset
173 if just_these:
kono
parents:
diff changeset
174 ls = just_these
kono
parents:
diff changeset
175 else:
kono
parents:
diff changeset
176 ls = os.listdir(bld_dir)
kono
parents:
diff changeset
177 for t in ls:
kono
parents:
diff changeset
178 if t.find("-") != -1:
kono
parents:
diff changeset
179 target = t.strip()
kono
parents:
diff changeset
180 tpath = bld_dir + "/" + target
kono
parents:
diff changeset
181 if not os.path.exists (tpath + "/gcc"):
kono
parents:
diff changeset
182 print "Error: gcc build directory for target " + t + " Does not exist: " + tpath + "/gcc"
kono
parents:
diff changeset
183 error = True
kono
parents:
diff changeset
184 else:
kono
parents:
diff changeset
185 target_dict[target] = tpath
kono
parents:
diff changeset
186
kono
parents:
diff changeset
187 if error:
kono
parents:
diff changeset
188 target_dict = { }
kono
parents:
diff changeset
189
kono
parents:
diff changeset
190 def get_obj_name (src_file):
kono
parents:
diff changeset
191 if src_file[-2:] == ".c":
kono
parents:
diff changeset
192 return src_file.replace (".c", ".o")
kono
parents:
diff changeset
193 elif src_file[-3:] == ".cc":
kono
parents:
diff changeset
194 return src_file.replace (".cc", ".o")
kono
parents:
diff changeset
195 return ""
kono
parents:
diff changeset
196
kono
parents:
diff changeset
197 def target_obj_exists (target, obj_name):
kono
parents:
diff changeset
198 global target_dict
kono
parents:
diff changeset
199 # look in a subdir if src has a subdir, then check gcc base directory.
kono
parents:
diff changeset
200 if target_dict.get(target):
kono
parents:
diff changeset
201 obj = target_dict[target] + "/gcc/" + obj_name
kono
parents:
diff changeset
202 if not os.path.exists (obj):
kono
parents:
diff changeset
203 obj = target_dict[target] + "/gcc/" + os.path.basename(obj_name)
kono
parents:
diff changeset
204 if os.path.exists (obj):
kono
parents:
diff changeset
205 return True
kono
parents:
diff changeset
206 return False
kono
parents:
diff changeset
207
kono
parents:
diff changeset
208 # Given a src file, return a list of targets which may build this file.
kono
parents:
diff changeset
209 def find_targets (src_file):
kono
parents:
diff changeset
210 global target_dict
kono
parents:
diff changeset
211 targ_list = list()
kono
parents:
diff changeset
212 obj_name = get_obj_name (src_file)
kono
parents:
diff changeset
213 if not obj_name:
kono
parents:
diff changeset
214 print "Error: " + src_file + " - Cannot determine object name."
kono
parents:
diff changeset
215 return list()
kono
parents:
diff changeset
216
kono
parents:
diff changeset
217 # Put the high priority targets which tend to trigger failures first
kono
parents:
diff changeset
218 for target in target_priority:
kono
parents:
diff changeset
219 if target_obj_exists (target, obj_name):
kono
parents:
diff changeset
220 targ_list.append ((target, target_dict[target]))
kono
parents:
diff changeset
221
kono
parents:
diff changeset
222 for target in target_dict:
kono
parents:
diff changeset
223 if target not in target_priority and target_obj_exists (target, obj_name):
kono
parents:
diff changeset
224 targ_list.append ((target, target_dict[target]))
kono
parents:
diff changeset
225
kono
parents:
diff changeset
226 return targ_list
kono
parents:
diff changeset
227
kono
parents:
diff changeset
228
kono
parents:
diff changeset
229 def try_to_remove (src_file, h_list, verbose):
kono
parents:
diff changeset
230 global target_dict
kono
parents:
diff changeset
231 global header_dict
kono
parents:
diff changeset
232 global build_dir
kono
parents:
diff changeset
233
kono
parents:
diff changeset
234 # build from scratch each time
kono
parents:
diff changeset
235 header_dict = { }
kono
parents:
diff changeset
236 summary = ""
kono
parents:
diff changeset
237 rmcount = 0
kono
parents:
diff changeset
238
kono
parents:
diff changeset
239 because = { }
kono
parents:
diff changeset
240 src_info = process_ii_macro_src (src_file)
kono
parents:
diff changeset
241 src_data = ii_src (src_info)
kono
parents:
diff changeset
242 if src_data:
kono
parents:
diff changeset
243 inclist = ii_include_list_non_cond (src_info)
kono
parents:
diff changeset
244 # work is done if there are no includes to check
kono
parents:
diff changeset
245 if not inclist:
kono
parents:
diff changeset
246 return src_file + ": No include files to attempt to remove"
kono
parents:
diff changeset
247
kono
parents:
diff changeset
248 # work on the include list in reverse.
kono
parents:
diff changeset
249 inclist.reverse()
kono
parents:
diff changeset
250
kono
parents:
diff changeset
251 # Get the target list
kono
parents:
diff changeset
252 targ_list = list()
kono
parents:
diff changeset
253 targ_list = find_targets (src_file)
kono
parents:
diff changeset
254
kono
parents:
diff changeset
255 spath = search_path
kono
parents:
diff changeset
256 if os.path.dirname (src_file):
kono
parents:
diff changeset
257 spath.append (os.path.dirname (src_file))
kono
parents:
diff changeset
258
kono
parents:
diff changeset
259 hostbuild = True
kono
parents:
diff changeset
260 if src_file.find("config/") != -1:
kono
parents:
diff changeset
261 # config files dont usually build on the host
kono
parents:
diff changeset
262 hostbuild = False
kono
parents:
diff changeset
263 obn = get_obj_name (os.path.basename (src_file))
kono
parents:
diff changeset
264 if obn and os.path.exists (build_dir + "/gcc/" + obn):
kono
parents:
diff changeset
265 hostbuild = True
kono
parents:
diff changeset
266 if not target_dict:
kono
parents:
diff changeset
267 summary = src_file + ": Target builds are required for config files. None found."
kono
parents:
diff changeset
268 print summary
kono
parents:
diff changeset
269 return summary
kono
parents:
diff changeset
270 if not targ_list:
kono
parents:
diff changeset
271 summary =src_file + ": Cannot find any targets which build this file."
kono
parents:
diff changeset
272 print summary
kono
parents:
diff changeset
273 return summary
kono
parents:
diff changeset
274
kono
parents:
diff changeset
275 if hostbuild:
kono
parents:
diff changeset
276 # confirm it actually builds before we do anything
kono
parents:
diff changeset
277 print "Confirming source file builds"
kono
parents:
diff changeset
278 res = get_make_output (build_dir + "/gcc", "all")
kono
parents:
diff changeset
279 if res[0] != 0:
kono
parents:
diff changeset
280 message = "Error: " + src_file + " does not build currently."
kono
parents:
diff changeset
281 summary = src_file + " does not build on host."
kono
parents:
diff changeset
282 print message
kono
parents:
diff changeset
283 print res[1]
kono
parents:
diff changeset
284 if verbose:
kono
parents:
diff changeset
285 verbose.write (message + "\n")
kono
parents:
diff changeset
286 verbose.write (res[1]+ "\n")
kono
parents:
diff changeset
287 return summary
kono
parents:
diff changeset
288
kono
parents:
diff changeset
289 src_requires = set (ii_macro_consume (src_info))
kono
parents:
diff changeset
290 for macro in src_requires:
kono
parents:
diff changeset
291 because[macro] = src_file
kono
parents:
diff changeset
292 header_seen = list ()
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 os.rename (src_file, src_file + ".bak")
kono
parents:
diff changeset
295 src_orig = copy.deepcopy (src_data)
kono
parents:
diff changeset
296 src_tmp = copy.deepcopy (src_data)
kono
parents:
diff changeset
297
kono
parents:
diff changeset
298 try:
kono
parents:
diff changeset
299 # process the includes from bottom to top. This is because we know that
kono
parents:
diff changeset
300 # later includes have are known to be needed, so any dependency from this
kono
parents:
diff changeset
301 # header is a true dependency
kono
parents:
diff changeset
302 for inc_file in inclist:
kono
parents:
diff changeset
303 inc_file_norm = normalize_header (inc_file)
kono
parents:
diff changeset
304
kono
parents:
diff changeset
305 if inc_file in no_remove:
kono
parents:
diff changeset
306 continue
kono
parents:
diff changeset
307 if len (h_list) != 0 and inc_file_norm not in h_list:
kono
parents:
diff changeset
308 continue
kono
parents:
diff changeset
309 if inc_file_norm[0:3] == "gt-":
kono
parents:
diff changeset
310 continue
kono
parents:
diff changeset
311 if inc_file_norm[0:6] == "gtype-":
kono
parents:
diff changeset
312 continue
kono
parents:
diff changeset
313 if inc_file_norm.replace(".h",".c") == os.path.basename(src_file):
kono
parents:
diff changeset
314 continue
kono
parents:
diff changeset
315
kono
parents:
diff changeset
316 lookfor = ii_src_line(src_info)[inc_file]
kono
parents:
diff changeset
317 src_tmp.remove (lookfor)
kono
parents:
diff changeset
318 message = "Trying " + src_file + " without " + inc_file
kono
parents:
diff changeset
319 print message
kono
parents:
diff changeset
320 if verbose:
kono
parents:
diff changeset
321 verbose.write (message + "\n")
kono
parents:
diff changeset
322 out = open(src_file, "w")
kono
parents:
diff changeset
323 for line in src_tmp:
kono
parents:
diff changeset
324 out.write (line)
kono
parents:
diff changeset
325 out.close()
kono
parents:
diff changeset
326
kono
parents:
diff changeset
327 keep = False
kono
parents:
diff changeset
328 if hostbuild:
kono
parents:
diff changeset
329 res = get_make_output (build_dir + "/gcc", "all")
kono
parents:
diff changeset
330 else:
kono
parents:
diff changeset
331 res = (0, "")
kono
parents:
diff changeset
332
kono
parents:
diff changeset
333 rc = res[0]
kono
parents:
diff changeset
334 message = "Passed Host build"
kono
parents:
diff changeset
335 if (rc != 0):
kono
parents:
diff changeset
336 # host build failed
kono
parents:
diff changeset
337 message = "Compilation failed:\n";
kono
parents:
diff changeset
338 keep = True
kono
parents:
diff changeset
339 else:
kono
parents:
diff changeset
340 if targ_list:
kono
parents:
diff changeset
341 objfile = get_obj_name (src_file)
kono
parents:
diff changeset
342 t1 = targ_list[0]
kono
parents:
diff changeset
343 if objfile and os.path.exists(t1[1] +"/gcc/"+objfile):
kono
parents:
diff changeset
344 res = get_make_output_parallel (targ_list, objfile, 0)
kono
parents:
diff changeset
345 else:
kono
parents:
diff changeset
346 res = get_make_output_parallel (targ_list, "all-gcc", 0)
kono
parents:
diff changeset
347 rc = res[0]
kono
parents:
diff changeset
348 if rc != 0:
kono
parents:
diff changeset
349 message = "Compilation failed on TARGET : " + res[2]
kono
parents:
diff changeset
350 keep = True
kono
parents:
diff changeset
351 else:
kono
parents:
diff changeset
352 message = "Passed host and target builds"
kono
parents:
diff changeset
353
kono
parents:
diff changeset
354 if keep:
kono
parents:
diff changeset
355 print message + "\n"
kono
parents:
diff changeset
356
kono
parents:
diff changeset
357 if (rc != 0):
kono
parents:
diff changeset
358 if verbose:
kono
parents:
diff changeset
359 verbose.write (message + "\n");
kono
parents:
diff changeset
360 verbose.write (res[1])
kono
parents:
diff changeset
361 verbose.write ("\n");
kono
parents:
diff changeset
362 if os.path.exists (inc_file):
kono
parents:
diff changeset
363 ilog = open(inc_file+".log","a")
kono
parents:
diff changeset
364 ilog.write (message + " for " + src_file + ":\n\n");
kono
parents:
diff changeset
365 ilog.write ("============================================\n");
kono
parents:
diff changeset
366 ilog.write (res[1])
kono
parents:
diff changeset
367 ilog.write ("\n");
kono
parents:
diff changeset
368 ilog.close()
kono
parents:
diff changeset
369 if os.path.exists (src_file):
kono
parents:
diff changeset
370 ilog = open(src_file+".log","a")
kono
parents:
diff changeset
371 ilog.write (message + " for " +inc_file + ":\n\n");
kono
parents:
diff changeset
372 ilog.write ("============================================\n");
kono
parents:
diff changeset
373 ilog.write (res[1])
kono
parents:
diff changeset
374 ilog.write ("\n");
kono
parents:
diff changeset
375 ilog.close()
kono
parents:
diff changeset
376
kono
parents:
diff changeset
377 # Given a sequence where :
kono
parents:
diff changeset
378 # #include "tm.h"
kono
parents:
diff changeset
379 # #include "target.h" // includes tm.h
kono
parents:
diff changeset
380
kono
parents:
diff changeset
381 # target.h was required, and when attempting to remove tm.h we'd see that
kono
parents:
diff changeset
382 # all the macro defintions are "required" since they all look like:
kono
parents:
diff changeset
383 # #ifndef HAVE_blah
kono
parents:
diff changeset
384 # #define HAVE_blah
kono
parents:
diff changeset
385 # endif
kono
parents:
diff changeset
386
kono
parents:
diff changeset
387 # when target.h was found to be required, tm.h will be tagged as included.
kono
parents:
diff changeset
388 # so when we get this far, we know we dont have to check the macros for
kono
parents:
diff changeset
389 # tm.h since we know it is already been included.
kono
parents:
diff changeset
390
kono
parents:
diff changeset
391 if inc_file_norm not in header_seen:
kono
parents:
diff changeset
392 iinfo = get_header_info (inc_file, spath)
kono
parents:
diff changeset
393 newlist = all_headers (inc_file_norm)
kono
parents:
diff changeset
394 if ii_path(iinfo) == "build" and not target_dict:
kono
parents:
diff changeset
395 keep = True
kono
parents:
diff changeset
396 text = message + " : Will not remove a build file without some targets."
kono
parents:
diff changeset
397 print text
kono
parents:
diff changeset
398 ilog = open(src_file+".log","a")
kono
parents:
diff changeset
399 ilog.write (text +"\n")
kono
parents:
diff changeset
400 ilog.write ("============================================\n");
kono
parents:
diff changeset
401 ilog.close()
kono
parents:
diff changeset
402 ilog = open("reduce-headers-kept.log","a")
kono
parents:
diff changeset
403 ilog.write (src_file + " " + text +"\n")
kono
parents:
diff changeset
404 ilog.close()
kono
parents:
diff changeset
405 else:
kono
parents:
diff changeset
406 newlist = list()
kono
parents:
diff changeset
407 if not keep and inc_file_norm not in header_seen:
kono
parents:
diff changeset
408 # now look for any macro requirements.
kono
parents:
diff changeset
409 for h in newlist:
kono
parents:
diff changeset
410 if not h in header_seen:
kono
parents:
diff changeset
411 if header_dict.get(h):
kono
parents:
diff changeset
412 defined = ii_macro_define (header_dict[h])
kono
parents:
diff changeset
413 for dep in defined:
kono
parents:
diff changeset
414 if dep in src_requires and dep not in ignore_list:
kono
parents:
diff changeset
415 keep = True;
kono
parents:
diff changeset
416 text = message + ", but must keep " + inc_file + " because it provides " + dep
kono
parents:
diff changeset
417 if because.get(dep) != None:
kono
parents:
diff changeset
418 text = text + " Possibly required by " + because[dep]
kono
parents:
diff changeset
419 print text
kono
parents:
diff changeset
420 ilog = open(inc_file+".log","a")
kono
parents:
diff changeset
421 ilog.write (because[dep]+": Requires [dep] in "+src_file+"\n")
kono
parents:
diff changeset
422 ilog.write ("============================================\n");
kono
parents:
diff changeset
423 ilog.close()
kono
parents:
diff changeset
424 ilog = open(src_file+".log","a")
kono
parents:
diff changeset
425 ilog.write (text +"\n")
kono
parents:
diff changeset
426 ilog.write ("============================================\n");
kono
parents:
diff changeset
427 ilog.close()
kono
parents:
diff changeset
428 ilog = open("reduce-headers-kept.log","a")
kono
parents:
diff changeset
429 ilog.write (src_file + " " + text +"\n")
kono
parents:
diff changeset
430 ilog.close()
kono
parents:
diff changeset
431 if verbose:
kono
parents:
diff changeset
432 verbose.write (text + "\n")
kono
parents:
diff changeset
433
kono
parents:
diff changeset
434 if keep:
kono
parents:
diff changeset
435 # add all headers 'consumes' to src_requires list, and mark as seen
kono
parents:
diff changeset
436 for h in newlist:
kono
parents:
diff changeset
437 if not h in header_seen:
kono
parents:
diff changeset
438 header_seen.append (h)
kono
parents:
diff changeset
439 if header_dict.get(h):
kono
parents:
diff changeset
440 consume = ii_macro_consume (header_dict[h])
kono
parents:
diff changeset
441 for dep in consume:
kono
parents:
diff changeset
442 if dep not in src_requires:
kono
parents:
diff changeset
443 src_requires.add (dep)
kono
parents:
diff changeset
444 if because.get(dep) == None:
kono
parents:
diff changeset
445 because[dep] = inc_file
kono
parents:
diff changeset
446
kono
parents:
diff changeset
447 src_tmp = copy.deepcopy (src_data)
kono
parents:
diff changeset
448 else:
kono
parents:
diff changeset
449 print message + " --> removing " + inc_file + "\n"
kono
parents:
diff changeset
450 rmcount += 1
kono
parents:
diff changeset
451 if verbose:
kono
parents:
diff changeset
452 verbose.write (message + " --> removing " + inc_file + "\n")
kono
parents:
diff changeset
453 if remove_count.get(inc_file) == None:
kono
parents:
diff changeset
454 remove_count[inc_file] = 1
kono
parents:
diff changeset
455 else:
kono
parents:
diff changeset
456 remove_count[inc_file] += 1
kono
parents:
diff changeset
457 src_data = copy.deepcopy (src_tmp)
kono
parents:
diff changeset
458 except:
kono
parents:
diff changeset
459 print "Interuption: restoring original file"
kono
parents:
diff changeset
460 out = open(src_file, "w")
kono
parents:
diff changeset
461 for line in src_orig:
kono
parents:
diff changeset
462 out.write (line)
kono
parents:
diff changeset
463 out.close()
kono
parents:
diff changeset
464 raise
kono
parents:
diff changeset
465
kono
parents:
diff changeset
466 # copy current version, since it is the "right" one now.
kono
parents:
diff changeset
467 out = open(src_file, "w")
kono
parents:
diff changeset
468 for line in src_data:
kono
parents:
diff changeset
469 out.write (line)
kono
parents:
diff changeset
470 out.close()
kono
parents:
diff changeset
471
kono
parents:
diff changeset
472 # Try a final host bootstrap build to make sure everything is kosher.
kono
parents:
diff changeset
473 if hostbuild:
kono
parents:
diff changeset
474 res = get_make_output (build_dir, "all")
kono
parents:
diff changeset
475 rc = res[0]
kono
parents:
diff changeset
476 if (rc != 0):
kono
parents:
diff changeset
477 # host build failed! return to original version
kono
parents:
diff changeset
478 print "Error: " + src_file + " Failed to bootstrap at end!!! restoring."
kono
parents:
diff changeset
479 print " Bad version at " + src_file + ".bad"
kono
parents:
diff changeset
480 os.rename (src_file, src_file + ".bad")
kono
parents:
diff changeset
481 out = open(src_file, "w")
kono
parents:
diff changeset
482 for line in src_orig:
kono
parents:
diff changeset
483 out.write (line)
kono
parents:
diff changeset
484 out.close()
kono
parents:
diff changeset
485 return src_file + ": failed to build after reduction. Restored original"
kono
parents:
diff changeset
486
kono
parents:
diff changeset
487 if src_data == src_orig:
kono
parents:
diff changeset
488 summary = src_file + ": No change."
kono
parents:
diff changeset
489 else:
kono
parents:
diff changeset
490 summary = src_file + ": Reduction performed, "+str(rmcount)+" includes removed."
kono
parents:
diff changeset
491 print summary
kono
parents:
diff changeset
492 return summary
kono
parents:
diff changeset
493
kono
parents:
diff changeset
494 only_h = list ()
kono
parents:
diff changeset
495 ignore_cond = False
kono
parents:
diff changeset
496
kono
parents:
diff changeset
497 usage = False
kono
parents:
diff changeset
498 src = list()
kono
parents:
diff changeset
499 only_targs = list ()
kono
parents:
diff changeset
500 for x in sys.argv[1:]:
kono
parents:
diff changeset
501 if x[0:2] == "-b":
kono
parents:
diff changeset
502 build_dir = x[2:]
kono
parents:
diff changeset
503 elif x[0:2] == "-f":
kono
parents:
diff changeset
504 fn = normalize_header (x[2:])
kono
parents:
diff changeset
505 if fn not in only_h:
kono
parents:
diff changeset
506 only_h.append (fn)
kono
parents:
diff changeset
507 elif x[0:2] == "-h":
kono
parents:
diff changeset
508 usage = True
kono
parents:
diff changeset
509 elif x[0:2] == "-d":
kono
parents:
diff changeset
510 ignore_cond = True
kono
parents:
diff changeset
511 elif x[0:2] == "-D":
kono
parents:
diff changeset
512 ignore_list.append(x[2:])
kono
parents:
diff changeset
513 elif x[0:2] == "-T":
kono
parents:
diff changeset
514 only_targs.append(x[2:])
kono
parents:
diff changeset
515 elif x[0:2] == "-t":
kono
parents:
diff changeset
516 target_dir = x[2:]
kono
parents:
diff changeset
517 elif x[0] == "-":
kono
parents:
diff changeset
518 print "Error: Unrecognized option " + x
kono
parents:
diff changeset
519 usgae = True
kono
parents:
diff changeset
520 else:
kono
parents:
diff changeset
521 if not os.path.exists (x):
kono
parents:
diff changeset
522 print "Error: specified file " + x + " does not exist."
kono
parents:
diff changeset
523 usage = True
kono
parents:
diff changeset
524 else:
kono
parents:
diff changeset
525 src.append (x)
kono
parents:
diff changeset
526
kono
parents:
diff changeset
527 if target_dir:
kono
parents:
diff changeset
528 build_target_dict (target_dir, only_targs)
kono
parents:
diff changeset
529
kono
parents:
diff changeset
530 if build_dir == "" and target_dir == "":
kono
parents:
diff changeset
531 print "Error: Must specify a build directory, and/or a target directory."
kono
parents:
diff changeset
532 usage = True
kono
parents:
diff changeset
533
kono
parents:
diff changeset
534 if build_dir and not os.path.exists (build_dir):
kono
parents:
diff changeset
535 print "Error: specified build directory does not exist : " + build_dir
kono
parents:
diff changeset
536 usage = True
kono
parents:
diff changeset
537
kono
parents:
diff changeset
538 if target_dir and not os.path.exists (target_dir):
kono
parents:
diff changeset
539 print "Error: specified target directory does not exist : " + target_dir
kono
parents:
diff changeset
540 usage = True
kono
parents:
diff changeset
541
kono
parents:
diff changeset
542 if usage:
kono
parents:
diff changeset
543 print "Attempts to remove extraneous include files from source files."
kono
parents:
diff changeset
544 print " "
kono
parents:
diff changeset
545 print "Should be run from the main gcc source directory, and works on a target"
kono
parents:
diff changeset
546 print "directory, as we attempt to make the 'all' target."
kono
parents:
diff changeset
547 print " "
kono
parents:
diff changeset
548 print "By default, gcc-reorder-includes is run on each file before attempting"
kono
parents:
diff changeset
549 print "to remove includes. this removes duplicates and puts some headers in a"
kono
parents:
diff changeset
550 print "canonical ordering"
kono
parents:
diff changeset
551 print " "
kono
parents:
diff changeset
552 print "The build directory should be ready to compile via make. Time is saved"
kono
parents:
diff changeset
553 print "if the build is already complete, so that only changes need to be built."
kono
parents:
diff changeset
554 print " "
kono
parents:
diff changeset
555 print "Usage: [options] file1.c [file2.c] ... [filen.c]"
kono
parents:
diff changeset
556 print " -bdir : the root build directory to attempt buiding .o files."
kono
parents:
diff changeset
557 print " -tdir : the target build directory"
kono
parents:
diff changeset
558 print " -d : Ignore conditional macro dependencies."
kono
parents:
diff changeset
559 print " "
kono
parents:
diff changeset
560 print " -Dmacro : Ignore a specific macro for dependencies"
kono
parents:
diff changeset
561 print " -Ttarget : Only consider target in target directory."
kono
parents:
diff changeset
562 print " -fheader : Specifies a specific .h file to be considered."
kono
parents:
diff changeset
563 print " "
kono
parents:
diff changeset
564 print " -D, -T, and -f can be specified mulitple times and are aggregated."
kono
parents:
diff changeset
565 print " "
kono
parents:
diff changeset
566 print " The original file will be in filen.bak"
kono
parents:
diff changeset
567 print " "
kono
parents:
diff changeset
568 sys.exit (0)
kono
parents:
diff changeset
569
kono
parents:
diff changeset
570 if only_h:
kono
parents:
diff changeset
571 print "Attempting to remove only these files:"
kono
parents:
diff changeset
572 for x in only_h:
kono
parents:
diff changeset
573 print x
kono
parents:
diff changeset
574 print " "
kono
parents:
diff changeset
575
kono
parents:
diff changeset
576 logfile = open("reduce-headers.log","w")
kono
parents:
diff changeset
577
kono
parents:
diff changeset
578 for x in src:
kono
parents:
diff changeset
579 msg = try_to_remove (x, only_h, logfile)
kono
parents:
diff changeset
580 ilog = open("reduce-headers.sum","a")
kono
parents:
diff changeset
581 ilog.write (msg + "\n")
kono
parents:
diff changeset
582 ilog.close()
kono
parents:
diff changeset
583
kono
parents:
diff changeset
584 ilog = open("reduce-headers.sum","a")
kono
parents:
diff changeset
585 ilog.write ("===============================================================\n")
kono
parents:
diff changeset
586 for x in remove_count:
kono
parents:
diff changeset
587 msg = x + ": Removed " + str(remove_count[x]) + " times."
kono
parents:
diff changeset
588 print msg
kono
parents:
diff changeset
589 logfile.write (msg + "\n")
kono
parents:
diff changeset
590 ilog.write (msg + "\n")
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592
kono
parents:
diff changeset
593
kono
parents:
diff changeset
594
kono
parents:
diff changeset
595