#! /usr/bin/env python # encoding: utf-8 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file import os,shlex,shutil,traceback,errno,sys,stat from waflib import Utils,Configure,Logs,Options,ConfigSet,Context,Errors,Build,Node build_dir_override=None no_climb_commands=['configure'] default_cmd="build" def waf_entry_point(current_directory,version,wafdir): Logs.init_log() if Context.WAFVERSION!=version: Logs.error('Waf script %r and library %r do not match (directory %r)'%(version,Context.WAFVERSION,wafdir)) sys.exit(1) if'--version'in sys.argv: Context.run_dir=current_directory ctx=Context.create_context('options') ctx.curdir=current_directory ctx.parse_args() sys.exit(0) Context.waf_dir=wafdir Context.launch_dir=current_directory no_climb=os.environ.get('NOCLIMB',None) if not no_climb: for k in no_climb_commands: if k in sys.argv: no_climb=True break cur=current_directory while cur: lst=os.listdir(cur) if Options.lockfile in lst: env=ConfigSet.ConfigSet() try: env.load(os.path.join(cur,Options.lockfile)) ino=os.stat(cur)[stat.ST_INO] except Exception: pass else: for x in[env.run_dir,env.top_dir,env.out_dir]: if Utils.is_win32: if cur==x: load=True break else: try: ino2=os.stat(x)[stat.ST_INO] except OSError: pass else: if ino==ino2: load=True break else: Logs.warn('invalid lock file in %s'%cur) load=False if load: Context.run_dir=env.run_dir Context.top_dir=env.top_dir Context.out_dir=env.out_dir break if not Context.run_dir: if Context.WSCRIPT_FILE in lst: Context.run_dir=cur next=os.path.dirname(cur) if next==cur: break cur=next if no_climb: break if not Context.run_dir: if'-h'in sys.argv or'--help'in sys.argv: Logs.warn('No wscript file found: the help message may be incomplete') Context.run_dir=current_directory ctx=Context.create_context('options') ctx.curdir=current_directory ctx.parse_args() sys.exit(0) Logs.error('Waf: Run from a directory containing a file named %r'%Context.WSCRIPT_FILE) sys.exit(1) try: os.chdir(Context.run_dir) except OSError: Logs.error('Waf: The folder %r is unreadable'%Context.run_dir) sys.exit(1) try: set_main_module(Context.run_dir+os.sep+Context.WSCRIPT_FILE) except Errors.WafError ,e: Logs.pprint('RED',e.verbose_msg) Logs.error(str(e)) sys.exit(1) except Exception ,e: Logs.error('Waf: The wscript in %r is unreadable'%Context.run_dir,e) traceback.print_exc(file=sys.stdout) sys.exit(2) try: run_commands() except Errors.WafError ,e: if Logs.verbose>1: Logs.pprint('RED',e.verbose_msg) Logs.error(e.msg) sys.exit(1) except SystemExit: raise except Exception ,e: traceback.print_exc(file=sys.stdout) sys.exit(2) except KeyboardInterrupt: Logs.pprint('RED','Interrupted') sys.exit(68) def set_main_module(file_path): Context.g_module=Context.load_module(file_path) Context.g_module.root_path=file_path def set_def(obj): name=obj.__name__ if not name in Context.g_module.__dict__: setattr(Context.g_module,name,obj) for k in[update,dist,distclean,distcheck,update]: set_def(k) if not'init'in Context.g_module.__dict__: Context.g_module.init=Utils.nada if not'shutdown'in Context.g_module.__dict__: Context.g_module.shutdown=Utils.nada if not'options'in Context.g_module.__dict__: Context.g_module.options=Utils.nada def parse_options(): Context.create_context('options').execute() if not Options.commands: Options.commands=[default_cmd] Options.commands=[x for x in Options.commands if x!='options'] Logs.verbose=Options.options.verbose Logs.init_log() if Options.options.zones: Logs.zones=Options.options.zones.split(',') if not Logs.verbose: Logs.verbose=1 elif Logs.verbose>0: Logs.zones=['runner'] if Logs.verbose>2: Logs.zones=['*'] def run_command(cmd_name): ctx=Context.create_context(cmd_name) ctx.log_timer=Utils.Timer() ctx.options=Options.options ctx.cmd=cmd_name ctx.execute() return ctx def run_commands(): parse_options() run_command('init') while Options.commands: cmd_name=Options.commands.pop(0) ctx=run_command(cmd_name) Logs.info('%r finished successfully (%s)'%(cmd_name,str(ctx.log_timer))) run_command('shutdown') def _can_distclean(name): for k in'.o .moc .exe'.split(): if name.endswith(k): return True return False def distclean_dir(dirname): for(root,dirs,files)in os.walk(dirname): for f in files: if _can_distclean(f): fname=root+os.sep+f try: os.remove(fname) except OSError: Logs.warn('Could not remove %r'%fname) for x in[Context.DBFILE,'config.log']: try: os.remove(x) except OSError: pass try: shutil.rmtree('c4che') except OSError: pass def distclean(ctx): '''removes the build directory''' lst=os.listdir('.') for f in lst: if f==Options.lockfile: try: proj=ConfigSet.ConfigSet(f) except IOError: Logs.warn('Could not read %r'%f) continue if proj['out_dir']!=proj['top_dir']: try: shutil.rmtree(proj['out_dir']) except IOError: pass except OSError ,e: if e.errno!=errno.ENOENT: Logs.warn('project %r cannot be removed'%proj[Context.OUT]) else: distclean_dir(proj['out_dir']) for k in(proj['out_dir'],proj['top_dir'],proj['run_dir']): try: os.remove(os.path.join(k,Options.lockfile)) except OSError ,e: if e.errno!=errno.ENOENT: Logs.warn('file %r cannot be removed'%f) if not Options.commands: for x in'.waf-1. waf-1. .waf3-1. waf3-1.'.split(): if f.startswith(x): shutil.rmtree(f,ignore_errors=True) class Dist(Context.Context): '''creates an archive containing the project source code''' cmd='dist' fun='dist' algo='tar.bz2' ext_algo={} def execute(self): self.recurse([os.path.dirname(Context.g_module.root_path)]) self.archive() def archive(self): import tarfile arch_name=self.get_arch_name() try: self.base_path except AttributeError: self.base_path=self.path node=self.base_path.make_node(arch_name) try: node.delete() except Exception: pass files=self.get_files() if self.algo.startswith('tar.'): tar=tarfile.open(arch_name,'w:'+self.algo.replace('tar.','')) for x in files: self.add_tar_file(x,tar) tar.close() elif self.algo=='zip': import zipfile zip=zipfile.ZipFile(arch_name,'w',compression=zipfile.ZIP_DEFLATED) for x in files: archive_name=self.get_base_name()+'/'+x.path_from(self.base_path) zip.write(x.abspath(),archive_name,zipfile.ZIP_DEFLATED) zip.close() else: self.fatal('Valid algo types are tar.bz2, tar.gz or zip') try: from hashlib import sha1 as sha except ImportError: from sha import sha try: digest=" (sha=%r)"%sha(node.read()).hexdigest() except Exception: digest='' Logs.info('New archive created: %s%s'%(self.arch_name,digest)) def get_tar_path(self,node): return node.abspath() def add_tar_file(self,x,tar): p=self.get_tar_path(x) tinfo=tar.gettarinfo(name=p,arcname=self.get_tar_prefix()+'/'+x.path_from(self.base_path)) tinfo.uid=0 tinfo.gid=0 tinfo.uname='root' tinfo.gname='root' fu=None try: fu=open(p,'rb') tar.addfile(tinfo,fileobj=fu) finally: if fu: fu.close() def get_tar_prefix(self): try: return self.tar_prefix except AttributeError: return self.get_base_name() def get_arch_name(self): try: self.arch_name except AttributeError: self.arch_name=self.get_base_name()+'.'+self.ext_algo.get(self.algo,self.algo) return self.arch_name def get_base_name(self): try: self.base_name except AttributeError: appname=getattr(Context.g_module,Context.APPNAME,'noname') version=getattr(Context.g_module,Context.VERSION,'1.0') self.base_name=appname+'-'+version return self.base_name def get_excl(self): try: return self.excl except AttributeError: self.excl=Node.exclude_regs+' **/waf-1.7.* **/.waf-1.7* **/waf3-1.7.* **/.waf3-1.7* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' nd=self.root.find_node(Context.out_dir) if nd: self.excl+=' '+nd.path_from(self.base_path) return self.excl def get_files(self): try: files=self.files except AttributeError: files=self.base_path.ant_glob('**/*',excl=self.get_excl()) return files def dist(ctx): '''makes a tarball for redistributing the sources''' pass class DistCheck(Dist): fun='distcheck' cmd='distcheck' def execute(self): self.recurse([os.path.dirname(Context.g_module.root_path)]) self.archive() self.check() def check(self): import tempfile,tarfile t=None try: t=tarfile.open(self.get_arch_name()) for x in t: t.extract(x) finally: if t: t.close() cfg=[] if Options.options.distcheck_args: cfg=shlex.split(Options.options.distcheck_args) else: cfg=[x for x in sys.argv if x.startswith('-')] instdir=tempfile.mkdtemp('.inst',self.get_base_name()) ret=Utils.subprocess.Popen([sys.executable,sys.argv[0],'configure','install','uninstall','--destdir='+instdir]+cfg,cwd=self.get_base_name()).wait() if ret: raise Errors.WafError('distcheck failed with code %i'%ret) if os.path.exists(instdir): raise Errors.WafError('distcheck succeeded, but files were left in %s'%instdir) shutil.rmtree(self.get_base_name()) def distcheck(ctx): '''checks if the project compiles (tarball from 'dist')''' pass def update(ctx): '''updates the plugins from the *waflib/extras* directory''' lst=Options.options.files.split(',') if not lst: lst=[x for x in Utils.listdir(Context.waf_dir+'/waflib/extras')if x.endswith('.py')] for x in lst: tool=x.replace('.py','') try: Configure.download_tool(tool,force=True,ctx=ctx) except Errors.WafError: Logs.error('Could not find the tool %s in the remote repository'%x) def autoconfigure(execute_method): def execute(self): if not Configure.autoconfig: return execute_method(self) env=ConfigSet.ConfigSet() do_config=False try: env.load(os.path.join(Context.top_dir,Options.lockfile)) except Exception: Logs.warn('Configuring the project') do_config=True else: if env.run_dir!=Context.run_dir: do_config=True else: h=0 for f in env['files']: h=Utils.h_list((h,Utils.readf(f,'rb'))) do_config=h!=env.hash if do_config: Options.commands.insert(0,self.cmd) Options.commands.insert(0,'configure') return return execute_method(self) return execute Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)