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