1*36ac495dSmrg#! /usr/bin/python2 2*36ac495dSmrgimport os.path 3*36ac495dSmrgimport sys 4*36ac495dSmrgimport shlex 5*36ac495dSmrgimport re 6*36ac495dSmrgimport subprocess 7*36ac495dSmrgimport shutil 8*36ac495dSmrgimport pickle 9*36ac495dSmrg 10*36ac495dSmrgimport multiprocessing 11*36ac495dSmrg 12*36ac495dSmrgdef find_pound_include (line, use_outside, use_slash): 13*36ac495dSmrg inc = re.findall (ur"^\s*#\s*include\s*\"(.+?)\"", line) 14*36ac495dSmrg if len(inc) == 1: 15*36ac495dSmrg nm = inc[0] 16*36ac495dSmrg if use_outside or os.path.exists (nm): 17*36ac495dSmrg if use_slash or '/' not in nm: 18*36ac495dSmrg return nm 19*36ac495dSmrg return "" 20*36ac495dSmrg 21*36ac495dSmrgdef find_system_include (line): 22*36ac495dSmrg inc = re.findall (ur"^\s*#\s*include\s*<(.+?)>", line) 23*36ac495dSmrg if len(inc) == 1: 24*36ac495dSmrg return inc[0] 25*36ac495dSmrg return "" 26*36ac495dSmrg 27*36ac495dSmrgdef find_pound_define (line): 28*36ac495dSmrg inc = re.findall (ur"^\s*#\s*define ([A-Za-z0-9_]+)", line) 29*36ac495dSmrg if len(inc) != 0: 30*36ac495dSmrg if len(inc) > 1: 31*36ac495dSmrg print "What? more than 1 match in #define??" 32*36ac495dSmrg print inc 33*36ac495dSmrg sys.exit(5) 34*36ac495dSmrg return inc[0]; 35*36ac495dSmrg return "" 36*36ac495dSmrg 37*36ac495dSmrgdef is_pound_if (line): 38*36ac495dSmrg inc = re.findall ("^\s*#\s*if\s", line) 39*36ac495dSmrg if not inc: 40*36ac495dSmrg inc = re.findall ("^\s*#\s*if[n]?def\s", line) 41*36ac495dSmrg if inc: 42*36ac495dSmrg return True 43*36ac495dSmrg return False 44*36ac495dSmrg 45*36ac495dSmrgdef is_pound_endif (line): 46*36ac495dSmrg inc = re.findall ("^\s*#\s*endif", line) 47*36ac495dSmrg if inc: 48*36ac495dSmrg return True 49*36ac495dSmrg return False 50*36ac495dSmrg 51*36ac495dSmrgdef find_pound_if (line): 52*36ac495dSmrg inc = re.findall (ur"^\s*#\s*if\s+(.*)", line) 53*36ac495dSmrg if len(inc) == 0: 54*36ac495dSmrg inc = re.findall (ur"^\s*#\s*elif\s+(.*)", line) 55*36ac495dSmrg if len(inc) > 0: 56*36ac495dSmrg inc2 = re.findall (ur"defined\s*\((.+?)\)", inc[0]) 57*36ac495dSmrg inc3 = re.findall (ur"defined\s+([a-zA-Z0-9_]+)", inc[0]) 58*36ac495dSmrg for yy in inc3: 59*36ac495dSmrg inc2.append (yy) 60*36ac495dSmrg return inc2 61*36ac495dSmrg else: 62*36ac495dSmrg inc = re.findall (ur"^\s*#\s*ifdef\s(.*)", line) 63*36ac495dSmrg if len(inc) == 0: 64*36ac495dSmrg inc = re.findall (ur"^\s*#\s*ifndef\s(.*)", line) 65*36ac495dSmrg if len(inc) > 0: 66*36ac495dSmrg inc2 = re.findall ("[A-Za-z_][A-Za-z_0-9]*", inc[0]) 67*36ac495dSmrg return inc2 68*36ac495dSmrg if len(inc) == 0: 69*36ac495dSmrg return list () 70*36ac495dSmrg print "WTF. more than one line returned for find_pound_if" 71*36ac495dSmrg print inc 72*36ac495dSmrg sys.exit(5) 73*36ac495dSmrg 74*36ac495dSmrg 75*36ac495dSmrg# IINFO - this is a vector of include information. It consists of 7 elements. 76*36ac495dSmrg# [0] - base name of the file 77*36ac495dSmrg# [1] - path leading to this file. 78*36ac495dSmrg# [2] - orderd list of all headers directly included by this file. 79*36ac495dSmrg# [3] - Ordered list of any headers included within condionally compiled code. 80*36ac495dSmrg# headers files are expected to have all includes one level deep due to 81*36ac495dSmrg# the omnipresent guards at the top of the file. 82*36ac495dSmrg# [4] - List of all macros which are consumed (used) within this file. 83*36ac495dSmrg# [5] - list of all macros which may be defined in this file. 84*36ac495dSmrg# [6] - The source code for this file, if cached. 85*36ac495dSmrg# [7] - line number info for any headers in the source file. Indexed by base 86*36ac495dSmrg# name, returning the line the include is on. 87*36ac495dSmrg 88*36ac495dSmrgempty_iinfo = ("", "", list(), list(), list(), list(), list()) 89*36ac495dSmrg 90*36ac495dSmrg# This function will process a file and extract interesting information. 91*36ac495dSmrg# DO_MACROS indicates whether macros defined and used should be recorded. 92*36ac495dSmrg# KEEP_SRC indicates the source for the file should be cached. 93*36ac495dSmrgdef process_include_info (filen, do_macros, keep_src): 94*36ac495dSmrg header = False 95*36ac495dSmrg if not os.path.exists (filen): 96*36ac495dSmrg return empty_iinfo 97*36ac495dSmrg 98*36ac495dSmrg sfile = open (filen, "r"); 99*36ac495dSmrg data = sfile.readlines() 100*36ac495dSmrg sfile.close() 101*36ac495dSmrg 102*36ac495dSmrg # Ignore the initial #ifdef HEADER_H in header files 103*36ac495dSmrg if filen[-2:] == ".h": 104*36ac495dSmrg nest = -1 105*36ac495dSmrg header = True 106*36ac495dSmrg else: 107*36ac495dSmrg nest = 0 108*36ac495dSmrg 109*36ac495dSmrg macout = list () 110*36ac495dSmrg macin = list() 111*36ac495dSmrg incl = list() 112*36ac495dSmrg cond_incl = list() 113*36ac495dSmrg src_line = { } 114*36ac495dSmrg guard = "" 115*36ac495dSmrg 116*36ac495dSmrg for line in (data): 117*36ac495dSmrg if is_pound_if (line): 118*36ac495dSmrg nest += 1 119*36ac495dSmrg elif is_pound_endif (line): 120*36ac495dSmrg nest -= 1 121*36ac495dSmrg 122*36ac495dSmrg nm = find_pound_include (line, True, True) 123*36ac495dSmrg if nm != "" and nm not in incl and nm[-2:] == ".h": 124*36ac495dSmrg incl.append (nm) 125*36ac495dSmrg if nest > 0: 126*36ac495dSmrg cond_incl.append (nm) 127*36ac495dSmrg if keep_src: 128*36ac495dSmrg src_line[nm] = line 129*36ac495dSmrg continue 130*36ac495dSmrg 131*36ac495dSmrg if do_macros: 132*36ac495dSmrg d = find_pound_define (line) 133*36ac495dSmrg if d: 134*36ac495dSmrg if d not in macout: 135*36ac495dSmrg macout.append (d); 136*36ac495dSmrg continue 137*36ac495dSmrg 138*36ac495dSmrg d = find_pound_if (line) 139*36ac495dSmrg if d: 140*36ac495dSmrg # The first #if in a header file should be the guard 141*36ac495dSmrg if header and len (d) == 1 and guard == "": 142*36ac495dSmrg if d[0][-2:] == "_H": 143*36ac495dSmrg guard = d 144*36ac495dSmrg else: 145*36ac495dSmrg guard = "Guess there was no guard..." 146*36ac495dSmrg else: 147*36ac495dSmrg for mac in d: 148*36ac495dSmrg if mac != "defined" and mac not in macin: 149*36ac495dSmrg macin.append (mac); 150*36ac495dSmrg 151*36ac495dSmrg if not keep_src: 152*36ac495dSmrg data = list() 153*36ac495dSmrg 154*36ac495dSmrg return (os.path.basename (filen), os.path.dirname (filen), incl, cond_incl, 155*36ac495dSmrg macin, macout, data, src_line) 156*36ac495dSmrg 157*36ac495dSmrg# Extract header info, but no macros or source code. 158*36ac495dSmrgdef process_ii (filen): 159*36ac495dSmrg return process_include_info (filen, False, False) 160*36ac495dSmrg 161*36ac495dSmrg# Extract header information, and collect macro information. 162*36ac495dSmrgdef process_ii_macro (filen): 163*36ac495dSmrg return process_include_info (filen, True, False) 164*36ac495dSmrg 165*36ac495dSmrg# Extract header information, cache the source lines. 166*36ac495dSmrgdef process_ii_src (filen): 167*36ac495dSmrg return process_include_info (filen, False, True) 168*36ac495dSmrg 169*36ac495dSmrg# Extract header information, coolewc macro info and cache the source lines. 170*36ac495dSmrgdef process_ii_macro_src (filen): 171*36ac495dSmrg return process_include_info (filen, True, True) 172*36ac495dSmrg 173*36ac495dSmrg 174*36ac495dSmrgdef ii_base (iinfo): 175*36ac495dSmrg return iinfo[0] 176*36ac495dSmrg 177*36ac495dSmrgdef ii_path (iinfo): 178*36ac495dSmrg return iinfo[1] 179*36ac495dSmrg 180*36ac495dSmrgdef ii_include_list (iinfo): 181*36ac495dSmrg return iinfo[2] 182*36ac495dSmrg 183*36ac495dSmrgdef ii_include_list_cond (iinfo): 184*36ac495dSmrg return iinfo[3] 185*36ac495dSmrg 186*36ac495dSmrgdef ii_include_list_non_cond (iinfo): 187*36ac495dSmrg l = ii_include_list (iinfo) 188*36ac495dSmrg for n in ii_include_list_cond (iinfo): 189*36ac495dSmrg l.remove (n) 190*36ac495dSmrg return l 191*36ac495dSmrg 192*36ac495dSmrgdef ii_macro_consume (iinfo): 193*36ac495dSmrg return iinfo[4] 194*36ac495dSmrg 195*36ac495dSmrgdef ii_macro_define (iinfo): 196*36ac495dSmrg return iinfo[5] 197*36ac495dSmrg 198*36ac495dSmrgdef ii_src (iinfo): 199*36ac495dSmrg return iinfo[6] 200*36ac495dSmrg 201*36ac495dSmrgdef ii_src_line (iinfo): 202*36ac495dSmrg return iinfo[7] 203*36ac495dSmrg 204*36ac495dSmrgdef ii_read (fname): 205*36ac495dSmrg f = open (fname, 'rb') 206*36ac495dSmrg incl = pickle.load (f) 207*36ac495dSmrg consumes = pickle.load (f) 208*36ac495dSmrg defines = pickle.load (f) 209*36ac495dSmrg obj = (fname,fname,incl,list(), list(), consumes, defines, list(), list()) 210*36ac495dSmrg return obj 211*36ac495dSmrg 212*36ac495dSmrgdef ii_write (fname, obj): 213*36ac495dSmrg f = open (fname, 'wb') 214*36ac495dSmrg pickle.dump (obj[2], f) 215*36ac495dSmrg pickle.dump (obj[4], f) 216*36ac495dSmrg pickle.dump (obj[5], f) 217*36ac495dSmrg f.close () 218*36ac495dSmrg 219*36ac495dSmrg# execute a system command which returns file names 220*36ac495dSmrgdef execute_command (command): 221*36ac495dSmrg files = list() 222*36ac495dSmrg f = os.popen (command) 223*36ac495dSmrg for x in f: 224*36ac495dSmrg if x[0:2] == "./": 225*36ac495dSmrg fn = x.rstrip()[2:] 226*36ac495dSmrg else: 227*36ac495dSmrg fn = x.rstrip() 228*36ac495dSmrg files.append(fn) 229*36ac495dSmrg return files 230*36ac495dSmrg 231*36ac495dSmrg# Try to locate a build directory from PATH 232*36ac495dSmrgdef find_gcc_bld_dir (path): 233*36ac495dSmrg blddir = "" 234*36ac495dSmrg # Look for blddir/gcc/tm.h 235*36ac495dSmrg command = "find " + path + " -mindepth 2 -maxdepth 3 -name tm.h" 236*36ac495dSmrg files = execute_command (command) 237*36ac495dSmrg for y in files: 238*36ac495dSmrg p = os.path.dirname (y) 239*36ac495dSmrg if os.path.basename (p) == "gcc": 240*36ac495dSmrg blddir = p 241*36ac495dSmrg break 242*36ac495dSmrg # If not found, try looking a bit deeper 243*36ac495dSmrg # Dont look this deep initially because a lot of cross target builds may show 244*36ac495dSmrg # up in the list before a native build... but those are better than nothing. 245*36ac495dSmrg if not blddir: 246*36ac495dSmrg command = "find " + path + " -mindepth 3 -maxdepth 5 -name tm.h" 247*36ac495dSmrg files = execute_command (command) 248*36ac495dSmrg for y in files: 249*36ac495dSmrg p = os.path.dirname (y) 250*36ac495dSmrg if os.path.basename (p) == "gcc": 251*36ac495dSmrg blddir = p 252*36ac495dSmrg break 253*36ac495dSmrg 254*36ac495dSmrg return blddir 255*36ac495dSmrg 256*36ac495dSmrg 257*36ac495dSmrg# Find files matching pattern NAME, return in a list. 258*36ac495dSmrg# CURRENT is True if you want to include the current directory 259*36ac495dSmrg# DEEPER is True if you want to search 3 levels below the current directory 260*36ac495dSmrg# any files with testsuite diurectories are ignored 261*36ac495dSmrg 262*36ac495dSmrgdef find_gcc_files (name, current, deeper): 263*36ac495dSmrg files = list() 264*36ac495dSmrg command = "" 265*36ac495dSmrg if current: 266*36ac495dSmrg if not deeper: 267*36ac495dSmrg command = "find -maxdepth 1 -name " + name + " -not -path \"./testsuite/*\"" 268*36ac495dSmrg else: 269*36ac495dSmrg command = "find -maxdepth 4 -name " + name + " -not -path \"./testsuite/*\"" 270*36ac495dSmrg else: 271*36ac495dSmrg if deeper: 272*36ac495dSmrg command = "find -maxdepth 4 -mindepth 2 -name " + name + " -not -path \"./testsuite/*\"" 273*36ac495dSmrg 274*36ac495dSmrg if command != "": 275*36ac495dSmrg files = execute_command (command) 276*36ac495dSmrg 277*36ac495dSmrg return files 278*36ac495dSmrg 279*36ac495dSmrg# find the list of unique include names found in a file. 280*36ac495dSmrgdef find_unique_include_list_src (data): 281*36ac495dSmrg found = list () 282*36ac495dSmrg for line in data: 283*36ac495dSmrg d = find_pound_include (line, True, True) 284*36ac495dSmrg if d and d not in found and d[-2:] == ".h": 285*36ac495dSmrg found.append (d) 286*36ac495dSmrg return found 287*36ac495dSmrg 288*36ac495dSmrg# find the list of unique include names found in a file. 289*36ac495dSmrgdef find_unique_include_list (filen): 290*36ac495dSmrg data = open (filen).read().splitlines() 291*36ac495dSmrg return find_unique_include_list_src (data) 292*36ac495dSmrg 293*36ac495dSmrg 294*36ac495dSmrg# Create the macin, macout, and incl vectors for a file FILEN. 295*36ac495dSmrg# macin are the macros that are used in #if* conditional expressions 296*36ac495dSmrg# macout are the macros which are #defined 297*36ac495dSmrg# incl is the list of incluide files encountered 298*36ac495dSmrg# returned as a tuple of the filename followed by the triplet of lists 299*36ac495dSmrg# (filen, macin, macout, incl) 300*36ac495dSmrg 301*36ac495dSmrgdef create_macro_in_out (filen): 302*36ac495dSmrg sfile = open (filen, "r"); 303*36ac495dSmrg data = sfile.readlines() 304*36ac495dSmrg sfile.close() 305*36ac495dSmrg 306*36ac495dSmrg macout = list () 307*36ac495dSmrg macin = list() 308*36ac495dSmrg incl = list() 309*36ac495dSmrg 310*36ac495dSmrg for line in (data): 311*36ac495dSmrg d = find_pound_define (line) 312*36ac495dSmrg if d != "": 313*36ac495dSmrg if d not in macout: 314*36ac495dSmrg macout.append (d); 315*36ac495dSmrg continue 316*36ac495dSmrg 317*36ac495dSmrg d = find_pound_if (line) 318*36ac495dSmrg if len(d) != 0: 319*36ac495dSmrg for mac in d: 320*36ac495dSmrg if mac != "defined" and mac not in macin: 321*36ac495dSmrg macin.append (mac); 322*36ac495dSmrg continue 323*36ac495dSmrg 324*36ac495dSmrg nm = find_pound_include (line, True, True) 325*36ac495dSmrg if nm != "" and nm not in incl: 326*36ac495dSmrg incl.append (nm) 327*36ac495dSmrg 328*36ac495dSmrg return (filen, macin, macout, incl) 329*36ac495dSmrg 330*36ac495dSmrg# create the macro information for filen, and create .macin, .macout, and .incl 331*36ac495dSmrg# files. Return the created macro tuple. 332*36ac495dSmrgdef create_include_data_files (filen): 333*36ac495dSmrg 334*36ac495dSmrg macros = create_macro_in_out (filen) 335*36ac495dSmrg depends = macros[1] 336*36ac495dSmrg defines = macros[2] 337*36ac495dSmrg incls = macros[3] 338*36ac495dSmrg 339*36ac495dSmrg disp_message = filen 340*36ac495dSmrg if len (defines) > 0: 341*36ac495dSmrg disp_message = disp_message + " " + str(len (defines)) + " #defines" 342*36ac495dSmrg dfile = open (filen + ".macout", "w") 343*36ac495dSmrg for x in defines: 344*36ac495dSmrg dfile.write (x + "\n") 345*36ac495dSmrg dfile.close () 346*36ac495dSmrg 347*36ac495dSmrg if len (depends) > 0: 348*36ac495dSmrg disp_message = disp_message + " " + str(len (depends)) + " #if dependencies" 349*36ac495dSmrg dfile = open (filen + ".macin", "w") 350*36ac495dSmrg for x in depends: 351*36ac495dSmrg dfile.write (x + "\n") 352*36ac495dSmrg dfile.close () 353*36ac495dSmrg 354*36ac495dSmrg if len (incls) > 0: 355*36ac495dSmrg disp_message = disp_message + " " + str(len (incls)) + " #includes" 356*36ac495dSmrg dfile = open (filen + ".incl", "w") 357*36ac495dSmrg for x in incls: 358*36ac495dSmrg dfile.write (x + "\n") 359*36ac495dSmrg dfile.close () 360*36ac495dSmrg 361*36ac495dSmrg return macros 362*36ac495dSmrg 363*36ac495dSmrg 364*36ac495dSmrg 365*36ac495dSmrg# extract data for include file name_h and enter it into the dictionary. 366*36ac495dSmrg# this does not change once read in. use_requires is True if you want to 367*36ac495dSmrg# prime the values with already created .requires and .provides files. 368*36ac495dSmrgdef get_include_data (name_h, use_requires): 369*36ac495dSmrg macin = list() 370*36ac495dSmrg macout = list() 371*36ac495dSmrg incl = list () 372*36ac495dSmrg if use_requires and os.path.exists (name_h + ".requires"): 373*36ac495dSmrg macin = open (name_h + ".requires").read().splitlines() 374*36ac495dSmrg elif os.path.exists (name_h + ".macin"): 375*36ac495dSmrg macin = open (name_h + ".macin").read().splitlines() 376*36ac495dSmrg 377*36ac495dSmrg if use_requires and os.path.exists (name_h + ".provides"): 378*36ac495dSmrg macout = open (name_h + ".provides").read().splitlines() 379*36ac495dSmrg elif os.path.exists (name_h + ".macout"): 380*36ac495dSmrg macout = open (name_h + ".macout").read().splitlines() 381*36ac495dSmrg 382*36ac495dSmrg if os.path.exists (name_h + ".incl"): 383*36ac495dSmrg incl = open (name_h + ".incl").read().splitlines() 384*36ac495dSmrg 385*36ac495dSmrg if len(macin) == 0 and len(macout) == 0 and len(incl) == 0: 386*36ac495dSmrg return () 387*36ac495dSmrg data = ( name_h, macin, macout, incl ) 388*36ac495dSmrg return data 389*36ac495dSmrg 390*36ac495dSmrg# find FIND in src, and replace it with the list of headers in REPLACE. 391*36ac495dSmrg# Remove any duplicates of FIND in REPLACE, and if some of the REPLACE 392*36ac495dSmrg# headers occur earlier in the include chain, leave them. 393*36ac495dSmrg# Return the new SRC only if anything changed. 394*36ac495dSmrgdef find_replace_include (find, replace, src): 395*36ac495dSmrg res = list() 396*36ac495dSmrg seen = { } 397*36ac495dSmrg anything = False 398*36ac495dSmrg for line in src: 399*36ac495dSmrg inc = find_pound_include (line, True, True) 400*36ac495dSmrg if inc == find: 401*36ac495dSmrg for y in replace: 402*36ac495dSmrg if seen.get(y) == None: 403*36ac495dSmrg res.append("#include \""+y+"\"\n") 404*36ac495dSmrg seen[y] = True 405*36ac495dSmrg if y != find: 406*36ac495dSmrg anything = True 407*36ac495dSmrg# if find isnt in the replacement list, then we are deleting FIND, so changes. 408*36ac495dSmrg if find not in replace: 409*36ac495dSmrg anything = True 410*36ac495dSmrg else: 411*36ac495dSmrg if inc in replace: 412*36ac495dSmrg if seen.get(inc) == None: 413*36ac495dSmrg res.append (line) 414*36ac495dSmrg seen[inc] = True 415*36ac495dSmrg else: 416*36ac495dSmrg res.append (line) 417*36ac495dSmrg 418*36ac495dSmrg if (anything): 419*36ac495dSmrg return res 420*36ac495dSmrg else: 421*36ac495dSmrg return list() 422*36ac495dSmrg 423*36ac495dSmrg 424*36ac495dSmrg# pass in a require and provide dictionary to be read in. 425*36ac495dSmrgdef read_require_provides (require, provide): 426*36ac495dSmrg if not os.path.exists ("require-provide.master"): 427*36ac495dSmrg print "require-provide.master file is not available. please run data collection." 428*36ac495dSmrg sys.exit(1) 429*36ac495dSmrg incl_list = open("require-provide.master").read().splitlines() 430*36ac495dSmrg for f in incl_list: 431*36ac495dSmrg if os.path.exists (f+".requires"): 432*36ac495dSmrg require[os.path.basename (f)] = open (f + ".requires").read().splitlines() 433*36ac495dSmrg else: 434*36ac495dSmrg require[os.path.basename (f)] = list () 435*36ac495dSmrg if os.path.exists (f+".provides"): 436*36ac495dSmrg provide[os.path.basename (f)] = open (f + ".provides").read().splitlines() 437*36ac495dSmrg else: 438*36ac495dSmrg provide [os.path.basename (f)] = list () 439*36ac495dSmrg 440*36ac495dSmrg 441*36ac495dSmrgdef build_include_list (filen): 442*36ac495dSmrg include_files = list() 443*36ac495dSmrg sfile = open (filen, "r") 444*36ac495dSmrg data = sfile.readlines() 445*36ac495dSmrg sfile.close() 446*36ac495dSmrg for line in data: 447*36ac495dSmrg nm = find_pound_include (line, False, False) 448*36ac495dSmrg if nm != "" and nm[-2:] == ".h": 449*36ac495dSmrg if nm not in include_files: 450*36ac495dSmrg include_files.append(nm) 451*36ac495dSmrg return include_files 452*36ac495dSmrg 453*36ac495dSmrgdef build_reverse_include_list (filen): 454*36ac495dSmrg include_files = list() 455*36ac495dSmrg sfile = open (filen, "r") 456*36ac495dSmrg data = sfile.readlines() 457*36ac495dSmrg sfile.close() 458*36ac495dSmrg for line in reversed(data): 459*36ac495dSmrg nm = find_pound_include (line, False, False) 460*36ac495dSmrg if nm != "": 461*36ac495dSmrg if nm not in include_files: 462*36ac495dSmrg include_files.append(nm) 463*36ac495dSmrg return include_files 464*36ac495dSmrg 465*36ac495dSmrg# Get compilation return code, and compensate for a warning that we want to 466*36ac495dSmrg# consider an error when it comes to inlined templates. 467*36ac495dSmrgdef get_make_rc (rc, output): 468*36ac495dSmrg rc = rc % 1280 469*36ac495dSmrg if rc == 0: 470*36ac495dSmrg # This is not considered an error during compilation of an individual file, 471*36ac495dSmrg # but it will cause an error during link if it isn't defined. If this 472*36ac495dSmrg # warning is seen during compiling a file, make it a build error so we 473*36ac495dSmrg # don't remove the header. 474*36ac495dSmrg h = re.findall ("warning: inline function.*used but never defined", output) 475*36ac495dSmrg if len(h) != 0: 476*36ac495dSmrg rc = 1 477*36ac495dSmrg return rc; 478*36ac495dSmrg 479*36ac495dSmrgdef get_make_output (build_dir, make_opt): 480*36ac495dSmrg devnull = open('/dev/null', 'w') 481*36ac495dSmrg at_a_time = multiprocessing.cpu_count() * 2 482*36ac495dSmrg make = "make -j"+str(at_a_time)+ " " 483*36ac495dSmrg if build_dir != "": 484*36ac495dSmrg command = "cd " + build_dir +"; " + make + make_opt 485*36ac495dSmrg else: 486*36ac495dSmrg command = make + make_opt 487*36ac495dSmrg process = subprocess.Popen(command, stdout=devnull, stderr=subprocess.PIPE, shell=True) 488*36ac495dSmrg output = process.communicate(); 489*36ac495dSmrg rc = get_make_rc (process.returncode, output[1]) 490*36ac495dSmrg return (rc , output[1]) 491*36ac495dSmrg 492*36ac495dSmrgdef spawn_makes (command_list): 493*36ac495dSmrg devnull = open('/dev/null', 'w') 494*36ac495dSmrg rc = (0,"", "") 495*36ac495dSmrg proc_res = list() 496*36ac495dSmrg text = " Trying target builds : " 497*36ac495dSmrg for command_pair in command_list: 498*36ac495dSmrg tname = command_pair[0] 499*36ac495dSmrg command = command_pair[1] 500*36ac495dSmrg text += tname + ", " 501*36ac495dSmrg c = subprocess.Popen(command, bufsize=-1, stdout=devnull, stderr=subprocess.PIPE, shell=True) 502*36ac495dSmrg proc_res.append ((c, tname)) 503*36ac495dSmrg 504*36ac495dSmrg print text[:-2] 505*36ac495dSmrg 506*36ac495dSmrg for p in proc_res: 507*36ac495dSmrg output = p[0].communicate() 508*36ac495dSmrg ret = (get_make_rc (p[0].returncode, output[1]), output[1], p[1]) 509*36ac495dSmrg if (ret[0] != 0): 510*36ac495dSmrg # Just record the first one. 511*36ac495dSmrg if rc[0] == 0: 512*36ac495dSmrg rc = ret; 513*36ac495dSmrg return rc 514*36ac495dSmrg 515*36ac495dSmrgdef get_make_output_parallel (targ_list, make_opt, at_a_time): 516*36ac495dSmrg command = list() 517*36ac495dSmrg targname = list() 518*36ac495dSmrg if at_a_time == 0: 519*36ac495dSmrg at_a_time = multiprocessing.cpu_count() * 2 520*36ac495dSmrg proc_res = [0] * at_a_time 521*36ac495dSmrg for x in targ_list: 522*36ac495dSmrg if make_opt[-2:] == ".o": 523*36ac495dSmrg s = "cd " + x[1] + "/gcc/; make " + make_opt 524*36ac495dSmrg else: 525*36ac495dSmrg s = "cd " + x[1] +"; make " + make_opt 526*36ac495dSmrg command.append ((x[0],s)) 527*36ac495dSmrg 528*36ac495dSmrg num = len(command) 529*36ac495dSmrg rc = (0,"", "") 530*36ac495dSmrg loops = num // at_a_time 531*36ac495dSmrg 532*36ac495dSmrg if (loops > 0): 533*36ac495dSmrg for idx in range (loops): 534*36ac495dSmrg ret = spawn_makes (command[idx*at_a_time:(idx+1)*at_a_time]) 535*36ac495dSmrg if ret[0] != 0: 536*36ac495dSmrg rc = ret 537*36ac495dSmrg break 538*36ac495dSmrg 539*36ac495dSmrg if (rc[0] == 0): 540*36ac495dSmrg leftover = num % at_a_time 541*36ac495dSmrg if (leftover > 0): 542*36ac495dSmrg ret = spawn_makes (command[-leftover:]) 543*36ac495dSmrg if ret[0] != 0: 544*36ac495dSmrg rc = ret 545*36ac495dSmrg 546*36ac495dSmrg return rc 547*36ac495dSmrg 548*36ac495dSmrg 549*36ac495dSmrgdef readwholefile (src_file): 550*36ac495dSmrg sfile = open (src_file, "r") 551*36ac495dSmrg src_data = sfile.readlines() 552*36ac495dSmrg sfile.close() 553*36ac495dSmrg return src_data 554*36ac495dSmrg 555