#! /usr/bin/env python## SCons - a Software Constructor## __COPYRIGHT__## Permission is hereby granted, free of charge, to any person obtaining# a copy of this software and associated documentation files (the# "Software"), to deal in the Software without restriction, including# without limitation the rights to use, copy, modify, merge, publish,# distribute, sublicense, and/or sell copies of the Software, and to# permit persons to whom the Software is furnished to do so, subject to# the following conditions:## The above copyright notice and this permission notice shall be included# in all copies or substantial portions of the Software.## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.#__revision__="__FILE__ __REVISION__ __DATE__ __DEVELOPER__"__version__="__VERSION__"__build__="__BUILD__"__buildsys__="__BUILDSYS__"__date__="__DATE__"__developer__="__DEVELOPER__"importosimportos.pathimportsysimporttime############################################################################### BEGIN STANDARD SCons SCRIPT HEADER## This is the cut-and-paste logic so that a self-contained script can# interoperate correctly with different SCons versions and installation# locations for the engine. If you modify anything in this section, you# should also change other scripts that use this same header.############################################################################### Strip the script directory from sys.path() so on case-insensitive# (WIN32) systems Python doesn't think that the "scons" script is the# "SCons" package. Replace it with our own library directories# (version-specific first, in case they installed by hand there,# followed by generic) so we pick up the right version of the build# engine modules if they're in either directory.script_dir=sys.path[0]ifscript_dirinsys.path:sys.path.remove(script_dir)libs=[]ifos.environ.has_key("SCONS_LIB_DIR"):libs.append(os.environ["SCONS_LIB_DIR"])local='scons-local-'+__version__ifscript_dir:local=os.path.join(script_dir,local)libs.append(os.path.abspath(local))scons_version='scons-%s'%__version__prefs=[]ifsys.platform=='win32':# sys.prefix is (likely) C:\Python*;# check only C:\Python*.prefs.append(sys.prefix)prefs.append(os.path.join(sys.prefix,'Lib','site-packages'))else:# On other (POSIX) platforms, things are more complicated due to# the variety of path names and library locations. Try to be smart# about it.ifscript_dir=='bin':# script_dir is `pwd`/bin;# check `pwd`/lib/scons*.prefs.append(os.getcwd())else:ifscript_dir=='.'orscript_dir=='':script_dir=os.getcwd()head,tail=os.path.split(script_dir)iftail=="bin":# script_dir is /foo/bin;# check /foo/lib/scons*.prefs.append(head)head,tail=os.path.split(sys.prefix)iftail=="usr":# sys.prefix is /foo/usr;# check /foo/usr/lib/scons* first,# then /foo/usr/local/lib/scons*.prefs.append(sys.prefix)prefs.append(os.path.join(sys.prefix,"local"))eliftail=="local":h,t=os.path.split(head)ift=="usr":# sys.prefix is /foo/usr/local;# check /foo/usr/local/lib/scons* first,# then /foo/usr/lib/scons*.prefs.append(sys.prefix)prefs.append(head)else:# sys.prefix is /foo/local;# check only /foo/local/lib/scons*.prefs.append(sys.prefix)else:# sys.prefix is /foo (ends in neither /usr or /local);# check only /foo/lib/scons*.prefs.append(sys.prefix)temp=map(lambdax:os.path.join(x,'lib'),prefs)temp.extend(map(lambdax:os.path.join(x,'lib','python'+sys.version[:3],'site-packages'),prefs))prefs=temp# Add the parent directory of the current python's library to the# preferences. On SuSE-91/AMD64, for example, this is /usr/lib64,# not /usr/lib.try:libpath=os.__file__exceptAttributeError:passelse:whilelibpath:libpath,tail=os.path.split(libpath)iftail[:6]=="python":breakiflibpath:# Python library is in /usr/libfoo/python*;# check /usr/libfoo/scons*.prefs.append(libpath)# Look first for 'scons-__version__' in all of our preference libs,# then for 'scons'.libs.extend(map(lambdax:os.path.join(x,scons_version),prefs))libs.extend(map(lambdax:os.path.join(x,'scons'),prefs))sys.path=libs+sys.path############################################################################### END STANDARD SCons SCRIPT HEADER##############################################################################importcPickleimportimpimportstringimportwhichdbimportSCons.SConsigndefmy_whichdb(filename):iffilename[-7:]==".dblite":return"SCons.dblite"try:f=open(filename+".dblite","rb")f.close()return"SCons.dblite"exceptIOError:passreturn_orig_whichdb(filename)_orig_whichdb=whichdb.whichdbwhichdb.whichdb=my_whichdbdefmy_import(mname):if'.'inmname:i=string.rfind(mname,'.')parent=my_import(mname[:i])fp,pathname,description=imp.find_module(mname[i+1:],parent.__path__)else:fp,pathname,description=imp.find_module(mname)returnimp.load_module(mname,fp,pathname,description)classFlagger:default_value=1def__setitem__(self,item,value):self.__dict__[item]=valueself.default_value=0def__getitem__(self,item):returnself.__dict__.get(item,self.default_value)Do_Call=NonePrint_Directories=[]Print_Entries=[]Print_Flags=Flagger()Verbose=0Readable=0defdefault_mapper(entry,name):try:val=eval("entry."+name)except:val=Nonereturnstr(val)defmap_action(entry,name):try:bact=entry.bactbactsig=entry.bactsigexceptAttributeError:returnNonereturn'%s [%s]'%(bactsig,bact)defmap_timestamp(entry,name):try:timestamp=entry.timestampexceptAttributeError:timestamp=NoneifReadableandtimestamp:return"'"+time.ctime(timestamp)+"'"else:returnstr(timestamp)defmap_bkids(entry,name):try:bkids=entry.bsources+entry.bdepends+entry.bimplicitbkidsigs=entry.bsourcesigs+entry.bdependsigs+entry.bimplicitsigsexceptAttributeError:returnNoneresult=[]foriinxrange(len(bkids)):result.append(nodeinfo_string(bkids[i],bkidsigs[i]," "))ifresult==[]:returnNonereturnstring.join(result,"\n ")map_field={'action':map_action,'timestamp':map_timestamp,'bkids':map_bkids,}map_name={'implicit':'bkids',}deffield(name,entry,verbose=Verbose):ifnotPrint_Flags[name]:returnNonefieldname=map_name.get(name,name)mapper=map_field.get(fieldname,default_mapper)val=mapper(entry,name)ifverbose:val=name+": "+valreturnvaldefnodeinfo_raw(name,ninfo,prefix=""):# This just formats the dictionary, which we would normally use str()# to do, except that we want the keys sorted for deterministic output.d=ninfo.__dict__try:keys=ninfo.field_list+['_version_id']exceptAttributeError:keys=d.keys()keys.sort()l=[]forkinkeys:l.append('%s: %s'%(repr(k),repr(d.get(k))))if'\n'inname:name=repr(name)returnname+': {'+string.join(l,', ')+'}'defnodeinfo_cooked(name,ninfo,prefix=""):try:field_list=ninfo.field_listexceptAttributeError:field_list=[]f=lambdax,ni=ninfo,v=Verbose:field(x,ni,v)if'\n'inname:name=repr(name)outlist=[name+':']+filter(None,map(f,field_list))ifVerbose:sep='\n '+prefixelse:sep=' 'returnstring.join(outlist,sep)nodeinfo_string=nodeinfo_cookeddefprintfield(name,entry,prefix=""):outlist=field("implicit",entry,0)ifoutlist:ifVerbose:print" implicit:"print" "+outlistoutact=field("action",entry,0)ifoutact:ifVerbose:print" action: "+outactelse:print" "+outactdefprintentries(entries,location):ifPrint_Entries:fornameinPrint_Entries:try:entry=entries[name]exceptKeyError:sys.stderr.write("sconsign: no entry `%s' in `%s'\n"%(name,location))else:try:ninfo=entry.ninfoexceptAttributeError:printname+":"else:printnodeinfo_string(name,entry.ninfo)printfield(name,entry.binfo)else:names=entries.keys()names.sort()fornameinnames:entry=entries[name]try:ninfo=entry.ninfoexceptAttributeError:printname+":"else:printnodeinfo_string(name,entry.ninfo)printfield(name,entry.binfo)classDo_SConsignDB:def__init__(self,dbm_name,dbm):self.dbm_name=dbm_nameself.dbm=dbmdef__call__(self,fname):# The *dbm modules stick their own file suffixes on the names# that are passed in. This is causes us to jump through some# hoops here to be able to allow the usertry:# Try opening the specified file name. Example:# SPECIFIED OPENED BY self.dbm.open()# --------- -------------------------# .sconsign => .sconsign.dblite# .sconsign.dblite => .sconsign.dblite.dblitedb=self.dbm.open(fname,"r")except(IOError,OSError),e:print_e=etry:# That didn't work, so try opening the base name,# so that if the actually passed in 'sconsign.dblite'# (for example), the dbm module will put the suffix back# on for us and open it anyway.db=self.dbm.open(os.path.splitext(fname)[0],"r")except(IOError,OSError):# That didn't work either. See if the file name# they specified just exists (independent of the dbm# suffix-mangling).try:open(fname,"r")except(IOError,OSError),e:# Nope, that file doesn't even exist, so report that# fact back.print_e=esys.stderr.write("sconsign: %s\n"%(print_e))returnexceptKeyboardInterrupt:raiseexceptcPickle.UnpicklingError:sys.stderr.write("sconsign: ignoring invalid `%s' file `%s'\n"%(self.dbm_name,fname))returnexceptException,e:sys.stderr.write("sconsign: ignoring invalid `%s' file `%s': %s\n"%(self.dbm_name,fname,e))returnifPrint_Directories:fordirinPrint_Directories:try:val=db[dir]exceptKeyError:sys.stderr.write("sconsign: no dir `%s' in `%s'\n"%(dir,args[0]))else:self.printentries(dir,val)else:keys=db.keys()keys.sort()fordirinkeys:self.printentries(dir,db[dir])defprintentries(self,dir,val):print'=== '+dir+':'printentries(cPickle.loads(val),dir)defDo_SConsignDir(name):try:fp=open(name,'rb')except(IOError,OSError),e:sys.stderr.write("sconsign: %s\n"%(e))returntry:sconsign=SCons.SConsign.Dir(fp)exceptKeyboardInterrupt:raiseexceptcPickle.UnpicklingError:sys.stderr.write("sconsign: ignoring invalid .sconsign file `%s'\n"%(name))returnexceptException,e:sys.stderr.write("sconsign: ignoring invalid .sconsign file `%s': %s\n"%(name,e))returnprintentries(sconsign.entries,args[0])##############################################################################importgetopthelpstr="""\Usage: sconsign [OPTIONS] FILE [...]Options: -a, --act, --action Print build action information. -c, --csig Print content signature information. -d DIR, --dir=DIR Print only info about DIR. -e ENTRY, --entry=ENTRY Print only info about ENTRY. -f FORMAT, --format=FORMAT FILE is in the specified FORMAT. -h, --help Print this message and exit. -i, --implicit Print implicit dependency information. -r, --readable Print timestamps in human-readable form. --raw Print raw Python object representations. -s, --size Print file sizes. -t, --timestamp Print timestamp information. -v, --verbose Verbose, describe each field."""opts,args=getopt.getopt(sys.argv[1:],"acd:e:f:hirstv",['act','action','csig','dir=','entry=','format=','help','implicit','raw','readable','size','timestamp','verbose'])foro,ainopts:ifoin('-a','--act','--action'):Print_Flags['action']=1elifoin('-c','--csig'):Print_Flags['csig']=1elifoin('-d','--dir'):Print_Directories.append(a)elifoin('-e','--entry'):Print_Entries.append(a)elifoin('-f','--format'):Module_Map={'dblite':'SCons.dblite','sconsign':None}dbm_name=Module_Map.get(a,a)ifdbm_name:try:dbm=my_import(dbm_name)except:sys.stderr.write("sconsign: illegal file format `%s'\n"%a)printhelpstrsys.exit(2)Do_Call=Do_SConsignDB(a,dbm)else:Do_Call=Do_SConsignDirelifoin('-h','--help'):printhelpstrsys.exit(0)elifoin('-i','--implicit'):Print_Flags['implicit']=1elifoin('--raw',):nodeinfo_string=nodeinfo_rawelifoin('-r','--readable'):Readable=1elifoin('-s','--size'):Print_Flags['size']=1elifoin('-t','--timestamp'):Print_Flags['timestamp']=1elifoin('-v','--verbose'):Verbose=1ifDo_Call:forainargs:Do_Call(a)else:forainargs:dbm_name=whichdb.whichdb(a)ifdbm_name:Map_Module={'SCons.dblite':'dblite'}dbm=my_import(dbm_name)Do_SConsignDB(Map_Module.get(dbm_name,dbm_name),dbm)(a)else:Do_SConsignDir(a)sys.exit(0)