meta2deps.py revision 246149
1246149Ssjg#!/usr/bin/env python 2246149Ssjg 3246149Ssjg""" 4246149SsjgThis script parses each "meta" file and extracts the 5246149Ssjginformation needed to deduce build and src dependencies. 6246149Ssjg 7246149SsjgIt works much the same as the original shell script, but is 8246149Ssjg*much* more efficient. 9246149Ssjg 10246149SsjgThe parsing work is handled by the class MetaFile. 11246149SsjgWe only pay attention to a subset of the information in the 12246149Ssjg"meta" files. Specifically: 13246149Ssjg 14246149Ssjg'CWD' to initialize our notion. 15246149Ssjg 16246149Ssjg'C' to track chdir(2) on a per process basis 17246149Ssjg 18246149Ssjg'R' files read are what we really care about. 19246149Ssjg directories read, provide a clue to resolving 20246149Ssjg subsequent relative paths. That is if we cannot find 21246149Ssjg them relative to 'cwd', we check relative to the last 22246149Ssjg dir read. 23246149Ssjg 24246149Ssjg'W' files opened for write or read-write, 25246149Ssjg for filemon V3 and earlier. 26246149Ssjg 27246149Ssjg'E' files executed. 28246149Ssjg 29246149Ssjg'L' files linked 30246149Ssjg 31246149Ssjg'V' the filemon version, this record is used as a clue 32246149Ssjg that we have reached the interesting bit. 33246149Ssjg 34246149Ssjg""" 35246149Ssjg 36246149Ssjg""" 37246149SsjgRCSid: 38246149Ssjg $Id: meta2deps.py,v 1.7 2012/11/06 05:44:03 sjg Exp $ 39246149Ssjg 40246149Ssjg Copyright (c) 2011, Juniper Networks, Inc. 41246149Ssjg 42246149Ssjg Redistribution and use in source and binary forms, with or without 43246149Ssjg modification, are permitted provided that the following conditions 44246149Ssjg are met: 45246149Ssjg 1. Redistributions of source code must retain the above copyright 46246149Ssjg notice, this list of conditions and the following disclaimer. 47246149Ssjg 2. Redistributions in binary form must reproduce the above copyright 48246149Ssjg notice, this list of conditions and the following disclaimer in the 49246149Ssjg documentation and/or other materials provided with the distribution. 50246149Ssjg 51246149Ssjg THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 52246149Ssjg "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 53246149Ssjg LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 54246149Ssjg A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 55246149Ssjg OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 56246149Ssjg SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 57246149Ssjg LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58246149Ssjg DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59246149Ssjg THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60246149Ssjg (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 61246149Ssjg OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62246149Ssjg 63246149Ssjg""" 64246149Ssjg 65246149Ssjgimport os, re, sys 66246149Ssjg 67246149Ssjgdef getv(dict, key, d=None): 68246149Ssjg """Lookup key in dict and return value or the supplied default.""" 69246149Ssjg if key in dict: 70246149Ssjg return dict[key] 71246149Ssjg return d 72246149Ssjg 73246149Ssjgdef resolve(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr): 74246149Ssjg """ 75246149Ssjg Return an absolute path, resolving via cwd or last_dir if needed. 76246149Ssjg """ 77246149Ssjg if path.endswith('/.'): 78246149Ssjg path = path[0:-2] 79246149Ssjg if path[0] == '/': 80246149Ssjg return path 81246149Ssjg if path == '.': 82246149Ssjg return cwd 83246149Ssjg if path.startswith('./'): 84246149Ssjg return cwd + path[1:] 85246149Ssjg if last_dir == cwd: 86246149Ssjg last_dir = None 87246149Ssjg for d in [last_dir, cwd]: 88246149Ssjg if not d: 89246149Ssjg continue 90246149Ssjg p = '/'.join([d,path]) 91246149Ssjg if debug > 2: 92246149Ssjg print >> debug_out, "looking for:", p, 93246149Ssjg if not os.path.exists(p): 94246149Ssjg if debug > 2: 95246149Ssjg print >> debug_out, "nope" 96246149Ssjg p = None 97246149Ssjg continue 98246149Ssjg if debug > 2: 99246149Ssjg print >> debug_out, "found:", p 100246149Ssjg return p 101246149Ssjg return None 102246149Ssjg 103246149Ssjgdef abspath(path, cwd, last_dir=None, debug=0, debug_out=sys.stderr): 104246149Ssjg """ 105246149Ssjg Return an absolute path, resolving via cwd or last_dir if needed. 106246149Ssjg this gets called a lot, so we try to avoid calling realpath 107246149Ssjg until we know we have something. 108246149Ssjg """ 109246149Ssjg path = resolve(path, cwd, last_dir, debug, debug_out) 110246149Ssjg if path and (path.find('./') > 0 or 111246149Ssjg path.endswith('/..') or 112246149Ssjg os.path.islink(path)): 113246149Ssjg return os.path.realpath(path) 114246149Ssjg return path 115246149Ssjg 116246149Ssjgdef sort_unique(list, cmp=None, key=None, reverse=False): 117246149Ssjg list.sort(cmp, key, reverse) 118246149Ssjg nl = [] 119246149Ssjg le = None 120246149Ssjg for e in list: 121246149Ssjg if e == le: 122246149Ssjg continue 123246149Ssjg nl.append(e) 124246149Ssjg return nl 125246149Ssjg 126246149Ssjgclass MetaFile: 127246149Ssjg """class to parse meta files generated by bmake.""" 128246149Ssjg 129246149Ssjg conf = None 130246149Ssjg dirdep_re = None 131246149Ssjg host_target = None 132246149Ssjg srctops = [] 133246149Ssjg objroots = [] 134246149Ssjg 135246149Ssjg seen = {} 136246149Ssjg obj_deps = [] 137246149Ssjg src_deps = [] 138246149Ssjg file_deps = [] 139246149Ssjg 140246149Ssjg def __init__(self, name, conf={}): 141246149Ssjg """if name is set we will parse it now. 142246149Ssjg conf can have the follwing keys: 143246149Ssjg 144246149Ssjg SRCTOPS list of tops of the src tree(s). 145246149Ssjg 146246149Ssjg CURDIR the src directory 'bmake' was run from. 147246149Ssjg 148246149Ssjg RELDIR the relative path from SRCTOP to CURDIR 149246149Ssjg 150246149Ssjg MACHINE the machine we built for. 151246149Ssjg set to 'none' if we are not cross-building. 152246149Ssjg 153246149Ssjg HOST_TARGET 154246149Ssjg when we build for the psuedo machine 'host' 155246149Ssjg the object tree uses HOST_TARGET rather than MACHINE. 156246149Ssjg 157246149Ssjg OBJROOTS a list of the common prefix for all obj dirs it might 158246149Ssjg end in '/' or '-'. 159246149Ssjg 160246149Ssjg DPDEPS names an optional file to which per file dependencies 161246149Ssjg will be appended. 162246149Ssjg For example if 'some/path/foo.h' is read from SRCTOP 163246149Ssjg then 'DPDEPS_some/path/foo.h +=' "RELDIR" is output. 164246149Ssjg This can allow 'bmake' to learn all the dirs within 165246149Ssjg the tree that depend on 'foo.h' 166246149Ssjg 167246149Ssjg debug desired debug level 168246149Ssjg 169246149Ssjg debug_out open file to send debug output to (sys.stderr) 170246149Ssjg 171246149Ssjg """ 172246149Ssjg 173246149Ssjg self.name = name 174246149Ssjg self.debug = getv(conf, 'debug', 0) 175246149Ssjg self.debug_out = getv(conf, 'debug_out', sys.stderr) 176246149Ssjg 177246149Ssjg if not self.conf: 178246149Ssjg # some of the steps below we want to do only once 179246149Ssjg self.conf = conf 180246149Ssjg self.host_target = getv(conf, 'HOST_TARGET') 181246149Ssjg for srctop in getv(conf, 'SRCTOPS', []): 182246149Ssjg if srctop[-1] != '/': 183246149Ssjg srctop += '/' 184246149Ssjg if not srctop in self.srctops: 185246149Ssjg self.srctops.append(srctop) 186246149Ssjg _srctop = os.path.realpath(srctop) 187246149Ssjg if _srctop[-1] != '/': 188246149Ssjg _srctop += '/' 189246149Ssjg if not _srctop in self.srctops: 190246149Ssjg self.srctops.append(_srctop) 191246149Ssjg 192246149Ssjg for objroot in getv(conf, 'OBJROOTS', []): 193246149Ssjg if not objroot in self.objroots: 194246149Ssjg self.objroots.append(objroot) 195246149Ssjg _objroot = os.path.realpath(objroot) 196246149Ssjg if objroot[-1] == '/': 197246149Ssjg _objroot += '/' 198246149Ssjg if not _objroot in self.objroots: 199246149Ssjg self.objroots.append(_objroot) 200246149Ssjg 201246149Ssjg if self.debug: 202246149Ssjg print >> self.debug_out, "host_target=", self.host_target 203246149Ssjg print >> self.debug_out, "srctops=", self.srctops 204246149Ssjg print >> self.debug_out, "objroots=", self.objroots 205246149Ssjg 206246149Ssjg self.dirdep_re = re.compile(r'([^/]+)/(.+)') 207246149Ssjg 208246149Ssjg self.curdir = getv(conf, 'CURDIR') 209246149Ssjg self.machine = getv(conf, 'MACHINE', '') 210246149Ssjg self.reldir = getv(conf, 'RELDIR') 211246149Ssjg self.dpdeps = getv(conf, 'DPDEPS') 212246149Ssjg if self.dpdeps and not self.reldir: 213246149Ssjg if self.debug: 214246149Ssjg print >> self.debug_out, "need reldir:", 215246149Ssjg if self.curdir: 216246149Ssjg srctop = self.find_top(self.curdir, self.srctops) 217246149Ssjg if srctop: 218246149Ssjg self.reldir = self.curdir.replace(srctop,'') 219246149Ssjg if self.debug: 220246149Ssjg print >> self.debug_out, self.reldir 221246149Ssjg if not self.reldir: 222246149Ssjg self.dpdeps = None # we cannot do it? 223246149Ssjg 224246149Ssjg if name: 225246149Ssjg self.parse() 226246149Ssjg 227246149Ssjg def reset(self): 228246149Ssjg """reset state if we are being passed meta files from multiple directories.""" 229246149Ssjg self.seen = {} 230246149Ssjg self.obj_deps = [] 231246149Ssjg self.src_deps = [] 232246149Ssjg self.file_deps = [] 233246149Ssjg 234246149Ssjg def dirdeps(self, sep='\n'): 235246149Ssjg """return DIRDEPS""" 236246149Ssjg return sep.strip() + sep.join(self.obj_deps) 237246149Ssjg 238246149Ssjg def src_dirdeps(self, sep='\n'): 239246149Ssjg """return SRC_DIRDEPS""" 240246149Ssjg return sep.strip() + sep.join(self.src_deps) 241246149Ssjg 242246149Ssjg def file_depends(self, out=None): 243246149Ssjg """Append DPDEPS_${file} += ${RELDIR} 244246149Ssjg for each file we saw, to the output file.""" 245246149Ssjg if not self.reldir: 246246149Ssjg return None 247246149Ssjg for f in sort_unique(self.file_deps): 248246149Ssjg print >> out, 'DPDEPS_%s += %s' % (f, self.reldir) 249246149Ssjg 250246149Ssjg def seenit(self, dir): 251246149Ssjg """rememer that we have seen dir.""" 252246149Ssjg self.seen[dir] = 1 253246149Ssjg 254246149Ssjg def add(self, list, data, clue=''): 255246149Ssjg """add data to list if it isn't already there.""" 256246149Ssjg if data not in list: 257246149Ssjg list.append(data) 258246149Ssjg if self.debug: 259246149Ssjg print >> self.debug_out, "%s: %sAdd: %s" % (self.name, clue, data) 260246149Ssjg 261246149Ssjg def find_top(self, path, list): 262246149Ssjg """the logical tree may be split accross multiple trees""" 263246149Ssjg for top in list: 264246149Ssjg if path.startswith(top): 265246149Ssjg if self.debug > 2: 266246149Ssjg print >> self.debug_out, "found in", top 267246149Ssjg return top 268246149Ssjg return None 269246149Ssjg 270246149Ssjg def find_obj(self, objroot, dir, path, input): 271246149Ssjg """return path within objroot, taking care of .dirdep files""" 272246149Ssjg ddep = None 273246149Ssjg for ddepf in [path + '.dirdep', dir + '/.dirdep']: 274246149Ssjg if not ddep and os.path.exists(ddepf): 275246149Ssjg ddep = open(ddepf, 'rb').readline().strip('# \n') 276246149Ssjg if self.debug > 1: 277246149Ssjg print >> self.debug_out, "found %s: %s\n" % (ddepf, ddep) 278246149Ssjg if ddep.endswith(self.machine): 279246149Ssjg ddep = ddep[0:-(1+len(self.machine))] 280246149Ssjg 281246149Ssjg if not ddep: 282246149Ssjg # no .dirdeps, so remember that we've seen the raw input 283246149Ssjg self.seenit(input) 284246149Ssjg self.seenit(dir) 285246149Ssjg if self.machine == 'none': 286246149Ssjg if dir.startswith(objroot): 287246149Ssjg return dir.replace(objroot,'') 288246149Ssjg return None 289246149Ssjg m = self.dirdep_re.match(dir.replace(objroot,'')) 290246149Ssjg if m: 291246149Ssjg ddep = m.group(2) 292246149Ssjg dmachine = m.group(1) 293246149Ssjg if dmachine != self.machine: 294246149Ssjg if not (self.machine == 'host' and 295246149Ssjg dmachine == self.host_target): 296246149Ssjg if self.debug > 2: 297246149Ssjg print >> self.debug_out, "adding .%s to %s" % (dmachine, ddep) 298246149Ssjg ddep += '.' + dmachine 299246149Ssjg 300246149Ssjg return ddep 301246149Ssjg 302246149Ssjg def parse(self, name=None, file=None): 303246149Ssjg """A meta file looks like: 304246149Ssjg 305246149Ssjg # Meta data file "path" 306246149Ssjg CMD "command-line" 307246149Ssjg CWD "cwd" 308246149Ssjg TARGET "target" 309246149Ssjg -- command output -- 310246149Ssjg -- filemon acquired metadata -- 311246149Ssjg # buildmon version 3 312246149Ssjg V 3 313246149Ssjg C "pid" "cwd" 314246149Ssjg E "pid" "path" 315246149Ssjg F "pid" "child" 316246149Ssjg R "pid" "path" 317246149Ssjg W "pid" "path" 318246149Ssjg X "pid" "status" 319246149Ssjg D "pid" "path" 320246149Ssjg L "pid" "src" "target" 321246149Ssjg M "pid" "old" "new" 322246149Ssjg S "pid" "path" 323246149Ssjg # Bye bye 324246149Ssjg 325246149Ssjg We go to some effort to avoid processing a dependency more than once. 326246149Ssjg Of the above record types only C,E,F,L,R,V and W are of interest. 327246149Ssjg """ 328246149Ssjg 329246149Ssjg version = 0 # unknown 330246149Ssjg if name: 331246149Ssjg self.name = name; 332246149Ssjg if file: 333246149Ssjg f = file 334246149Ssjg cwd = last_dir = self.cwd 335246149Ssjg else: 336246149Ssjg f = open(self.name, 'rb') 337246149Ssjg skip = True 338246149Ssjg pid_cwd = {} 339246149Ssjg pid_last_dir = {} 340246149Ssjg last_pid = 0 341246149Ssjg 342246149Ssjg if self.curdir: 343246149Ssjg self.seenit(self.curdir) # we ignore this 344246149Ssjg 345246149Ssjg interesting = 'CEFLRV' 346246149Ssjg for line in f: 347246149Ssjg # ignore anything we don't care about 348246149Ssjg if not line[0] in interesting: 349246149Ssjg continue 350246149Ssjg if self.debug > 2: 351246149Ssjg print >> self.debug_out, "input:", line, 352246149Ssjg w = line.split() 353246149Ssjg 354246149Ssjg if skip: 355246149Ssjg if w[0] == 'V': 356246149Ssjg skip = False 357246149Ssjg version = int(w[1]) 358246149Ssjg """ 359246149Ssjg if version < 4: 360246149Ssjg # we cannot ignore 'W' records 361246149Ssjg # as they may be 'rw' 362246149Ssjg interesting += 'W' 363246149Ssjg """ 364246149Ssjg elif w[0] == 'CWD': 365246149Ssjg self.cwd = cwd = last_dir = w[1] 366246149Ssjg self.seenit(cwd) # ignore this 367246149Ssjg if self.debug: 368246149Ssjg print >> self.debug_out, "%s: CWD=%s" % (self.name, cwd) 369246149Ssjg continue 370246149Ssjg 371246149Ssjg pid = int(w[1]) 372246149Ssjg if pid != last_pid: 373246149Ssjg if last_pid: 374246149Ssjg pid_cwd[last_pid] = cwd 375246149Ssjg pid_last_dir[last_pid] = last_dir 376246149Ssjg cwd = getv(pid_cwd, pid, self.cwd) 377246149Ssjg last_dir = getv(pid_last_dir, pid, self.cwd) 378246149Ssjg last_pid = pid 379246149Ssjg 380246149Ssjg # process operations 381246149Ssjg if w[0] == 'F': 382246149Ssjg npid = int(w[2]) 383246149Ssjg pid_cwd[npid] = cwd 384246149Ssjg pid_last_dir[npid] = cwd 385246149Ssjg last_pid = npid 386246149Ssjg continue 387246149Ssjg elif w[0] == 'C': 388246149Ssjg cwd = abspath(w[2], cwd, None, self.debug, self.debug_out) 389246149Ssjg if cwd.endswith('/.'): 390246149Ssjg cwd = cwd[0:-2] 391246149Ssjg last_dir = cwd 392246149Ssjg if self.debug > 1: 393246149Ssjg print >> self.debug_out, "cwd=", cwd 394246149Ssjg continue 395246149Ssjg 396246149Ssjg if w[2] in self.seen: 397246149Ssjg if self.debug > 2: 398246149Ssjg print >> self.debug_out, "seen:", w[2] 399246149Ssjg continue 400246149Ssjg # file operations 401246149Ssjg if w[0] in 'ML': 402246149Ssjg path = w[2].strip("'") 403246149Ssjg else: 404246149Ssjg path = w[2] 405246149Ssjg # we are never interested in .dirdep files as dependencies 406246149Ssjg if path.endswith('.dirdep'): 407246149Ssjg continue 408246149Ssjg # we don't want to resolve the last component if it is 409246149Ssjg # a symlink 410246149Ssjg path = resolve(path, cwd, last_dir, self.debug, self.debug_out) 411246149Ssjg if not path: 412246149Ssjg continue 413246149Ssjg dir,base = os.path.split(path) 414246149Ssjg if dir in self.seen: 415246149Ssjg if self.debug > 2: 416246149Ssjg print >> self.debug_out, "seen:", dir 417246149Ssjg continue 418246149Ssjg # we can have a path in an objdir which is a link 419246149Ssjg # to the src dir, we may need to add dependencies for each 420246149Ssjg rdir = dir 421246149Ssjg dir = abspath(dir, cwd, last_dir, self.debug, self.debug_out) 422246149Ssjg if rdir == dir or rdir.find('./') > 0: 423246149Ssjg rdir = None 424246149Ssjg # now put path back together 425246149Ssjg path = '/'.join([dir,base]) 426246149Ssjg if self.debug > 1: 427246149Ssjg print >> self.debug_out, "raw=%s rdir=%s dir=%s path=%s" % (w[2], rdir, dir, path) 428246149Ssjg if w[0] in 'SRWL': 429246149Ssjg if w[0] == 'W' and path.endswith('.dirdep'): 430246149Ssjg continue 431246149Ssjg if path in [last_dir, cwd, self.cwd, self.curdir]: 432246149Ssjg if self.debug > 1: 433246149Ssjg print >> self.debug_out, "skipping:", path 434246149Ssjg continue 435246149Ssjg if os.path.isdir(path): 436246149Ssjg if w[0] in 'RW': 437246149Ssjg last_dir = path; 438246149Ssjg if self.debug > 1: 439246149Ssjg print >> self.debug_out, "ldir=", last_dir 440246149Ssjg continue 441246149Ssjg 442246149Ssjg if w[0] in 'REWML': 443246149Ssjg # finally, we get down to it 444246149Ssjg if dir == self.cwd or dir == self.curdir: 445246149Ssjg continue 446246149Ssjg srctop = self.find_top(path, self.srctops) 447246149Ssjg if srctop: 448246149Ssjg if self.dpdeps: 449246149Ssjg self.add(self.file_deps, path.replace(srctop,''), 'file') 450246149Ssjg self.add(self.src_deps, dir.replace(srctop,''), 'src') 451246149Ssjg self.seenit(w[2]) 452246149Ssjg self.seenit(dir) 453246149Ssjg if rdir and not rdir.startswith(srctop): 454246149Ssjg dir = rdir # for below 455246149Ssjg rdir = None 456246149Ssjg else: 457246149Ssjg continue 458246149Ssjg 459246149Ssjg objroot = None 460246149Ssjg for dir in [dir,rdir]: 461246149Ssjg if not dir: 462246149Ssjg continue 463246149Ssjg objroot = self.find_top(dir, self.objroots) 464246149Ssjg if objroot: 465246149Ssjg break 466246149Ssjg if objroot: 467246149Ssjg ddep = self.find_obj(objroot, dir, path, w[2]) 468246149Ssjg if ddep: 469246149Ssjg self.add(self.obj_deps, ddep, 'obj') 470246149Ssjg else: 471246149Ssjg # don't waste time looking again 472246149Ssjg self.seenit(w[2]) 473246149Ssjg self.seenit(dir) 474246149Ssjg if not file: 475246149Ssjg f.close() 476246149Ssjg 477246149Ssjg 478246149Ssjgdef main(argv, klass=MetaFile, xopts='', xoptf=None): 479246149Ssjg """Simple driver for class MetaFile. 480246149Ssjg 481246149Ssjg Usage: 482246149Ssjg script [options] [key=value ...] "meta" ... 483246149Ssjg 484246149Ssjg Options and key=value pairs contribute to the 485246149Ssjg dictionary passed to MetaFile. 486246149Ssjg 487246149Ssjg -S "SRCTOP" 488246149Ssjg add "SRCTOP" to the "SRCTOPS" list. 489246149Ssjg 490246149Ssjg -C "CURDIR" 491246149Ssjg 492246149Ssjg -O "OBJROOT" 493246149Ssjg add "OBJROOT" to the "OBJROOTS" list. 494246149Ssjg 495246149Ssjg -m "MACHINE" 496246149Ssjg 497246149Ssjg -H "HOST_TARGET" 498246149Ssjg 499246149Ssjg -D "DPDEPS" 500246149Ssjg 501246149Ssjg -d bumps debug level 502246149Ssjg 503246149Ssjg """ 504246149Ssjg import getopt 505246149Ssjg 506246149Ssjg # import Psyco if we can 507246149Ssjg # it can speed things up quite a bit 508246149Ssjg have_psyco = 0 509246149Ssjg try: 510246149Ssjg import psyco 511246149Ssjg psyco.full() 512246149Ssjg have_psyco = 1 513246149Ssjg except: 514246149Ssjg pass 515246149Ssjg 516246149Ssjg conf = { 517246149Ssjg 'SRCTOPS': [], 518246149Ssjg 'OBJROOTS': [], 519246149Ssjg } 520246149Ssjg 521246149Ssjg try: 522246149Ssjg machine = os.environ['MACHINE'] 523246149Ssjg if machine: 524246149Ssjg conf['MACHINE'] = machine 525246149Ssjg srctop = os.environ['SB_SRC'] 526246149Ssjg if srctop: 527246149Ssjg conf['SRCTOPS'].append(srctop) 528246149Ssjg objroot = os.environ['SB_OBJROOT'] 529246149Ssjg if objroot: 530246149Ssjg conf['OBJROOTS'].append(objroot) 531246149Ssjg except: 532246149Ssjg pass 533246149Ssjg 534246149Ssjg debug = 0 535246149Ssjg output = True 536246149Ssjg 537246149Ssjg opts, args = getopt.getopt(argv[1:], 'dS:C:O:R:m:D:H:q' + xopts) 538246149Ssjg for o, a in opts: 539246149Ssjg if o == '-d': 540246149Ssjg debug += 1 541246149Ssjg elif o == '-q': 542246149Ssjg output = False 543246149Ssjg elif o == '-H': 544246149Ssjg conf['HOST_TARGET'] = a 545246149Ssjg elif o == '-S': 546246149Ssjg if a not in conf['SRCTOPS']: 547246149Ssjg conf['SRCTOPS'].append(a) 548246149Ssjg elif o == '-C': 549246149Ssjg conf['CURDIR'] = a 550246149Ssjg elif o == '-O': 551246149Ssjg if a not in conf['OBJROOTS']: 552246149Ssjg conf['OBJROOTS'].append(a) 553246149Ssjg elif o == '-R': 554246149Ssjg conf['RELDIR'] = a 555246149Ssjg elif o == '-D': 556246149Ssjg conf['DPDEPS'] = a 557246149Ssjg elif o == '-m': 558246149Ssjg conf['MACHINE'] = a 559246149Ssjg elif xoptf: 560246149Ssjg xoptf(o, a, conf) 561246149Ssjg 562246149Ssjg conf['debug'] = debug 563246149Ssjg 564246149Ssjg # get any var=val assignments 565246149Ssjg eaten = [] 566246149Ssjg for a in args: 567246149Ssjg if a.find('=') > 0: 568246149Ssjg k,v = a.split('=') 569246149Ssjg if k in ['SRCTOP','OBJROOT','SRCTOPS','OBJROOTS']: 570246149Ssjg if k == 'SRCTOP': 571246149Ssjg k = 'SRCTOPS' 572246149Ssjg elif k == 'OBJROOT': 573246149Ssjg k = 'OBJROOTS' 574246149Ssjg if v not in conf[k]: 575246149Ssjg conf[k].append(v) 576246149Ssjg else: 577246149Ssjg conf[k] = v 578246149Ssjg eaten.append(a) 579246149Ssjg continue 580246149Ssjg break 581246149Ssjg 582246149Ssjg for a in eaten: 583246149Ssjg args.remove(a) 584246149Ssjg 585246149Ssjg debug_out = getv(conf, 'debug_out', sys.stderr) 586246149Ssjg 587246149Ssjg if debug: 588246149Ssjg print >> debug_out, "config:" 589246149Ssjg print >> debug_out, "psyco=", have_psyco 590246149Ssjg for k,v in conf.items(): 591246149Ssjg print >> debug_out, "%s=%s" % (k,v) 592246149Ssjg 593246149Ssjg for a in args: 594246149Ssjg m = klass(a, conf) 595246149Ssjg 596246149Ssjg if output: 597246149Ssjg print m.dirdeps() 598246149Ssjg 599246149Ssjg print m.src_dirdeps('\nsrc:') 600246149Ssjg 601246149Ssjg dpdeps = getv(conf, 'DPDEPS') 602246149Ssjg if dpdeps: 603246149Ssjg m.file_depends(open(dpdeps, 'wb')) 604246149Ssjg 605246149Ssjg return m 606246149Ssjg 607246149Ssjgif __name__ == '__main__': 608246149Ssjg try: 609246149Ssjg main(sys.argv) 610246149Ssjg except: 611246149Ssjg # yes, this goes to stdout 612246149Ssjg print "ERROR: ", sys.exc_info()[1] 613246149Ssjg raise 614246149Ssjg 615