#! /usr/bin/env python # encoding: utf-8 # WARNING! Do not edit! https://waf.io/book/index.html#_obtaining_the_waf_file from __future__ import with_statement 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) Context.waf_dir=wafdir Context.run_dir=Context.launch_dir=current_directory start_dir=current_directory no_climb=os.environ.get('NOCLIMB') if len(sys.argv)>1: potential_wscript=os.path.join(current_directory,sys.argv[1]) if os.path.basename(potential_wscript)==Context.WSCRIPT_FILE and os.path.isfile(potential_wscript): path=os.path.normpath(os.path.dirname(potential_wscript)) start_dir=os.path.abspath(path) no_climb=True sys.argv.pop(1) ctx=Context.create_context('options') (options,commands,env)=ctx.parse_cmd_args(allow_unknown=True) if options.top: start_dir=Context.run_dir=Context.top_dir=options.top no_climb=True if options.out: Context.out_dir=options.out if not no_climb: for k in no_climb_commands: for y in commands: if y.startswith(k): no_climb=True break cur=start_dir while cur: try: lst=os.listdir(cur) except OSError: lst=[] Logs.error('Directory %r is unreadable!',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 EnvironmentError: pass else: for x in(env.run_dir,env.top_dir,env.out_dir): if not x: continue 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 wscript=os.path.normpath(os.path.join(Context.run_dir,Context.WSCRIPT_FILE)) if not os.path.exists(wscript): if options.whelp: Logs.warn('These are the generic options (no wscript/project found)') ctx.parser.print_help() sys.exit(0) Logs.error('Waf: Run from a folder containing a %r file (or try -h for the generic options)',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(wscript) 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) traceback.print_exc(file=sys.stdout) sys.exit(2) if options.profile: import cProfile,pstats cProfile.runctx('from waflib import Scripting; Scripting.run_commands()',{},{},'profi.txt') p=pstats.Stats('profi.txt') p.sort_stats('time').print_stats(75) else: try: try: run_commands() except: if options.pdb: import pdb type,value,tb=sys.exc_info() traceback.print_exc() pdb.post_mortem(tb) else: raise 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(dist,distclean,distcheck): 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(): ctx=Context.create_context('options') ctx.execute() if not Options.commands: Options.commands.append(default_cmd) if Options.options.whelp: ctx.parser.print_help() sys.exit(0) def run_command(cmd_name): ctx=Context.create_context(cmd_name) ctx.log_timer=Utils.Timer() ctx.options=Options.options ctx.cmd=cmd_name try: ctx.execute() finally: ctx.finalize() 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,ctx.log_timer) run_command('shutdown') def distclean_dir(dirname): for(root,dirs,files)in os.walk(dirname): for f in files: if f.endswith(('.o','.moc','.exe')): fname=os.path.join(root,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 build folders and data''' def remove_and_log(k,fun): try: fun(k) except EnvironmentError ,e: if e.errno!=errno.ENOENT: Logs.warn('Could not remove %r',k) if not Options.commands: for k in os.listdir('.'): for x in'.waf-2 waf-2 .waf3-2 waf3-2'.split(): if k.startswith(x): remove_and_log(k,shutil.rmtree) cur='.' if ctx.options.no_lock_in_top: cur=ctx.options.out try: lst=os.listdir(cur) except OSError: Logs.warn('Could not read %r',cur) return if Options.lockfile in lst: f=os.path.join(cur,Options.lockfile) try: env=ConfigSet.ConfigSet(f) except EnvironmentError: Logs.warn('Could not read %r',f) return if not env.out_dir or not env.top_dir: Logs.warn('Invalid lock file %r',f) return if env.out_dir==env.top_dir: distclean_dir(env.out_dir) else: remove_and_log(env.out_dir,shutil.rmtree) for k in(env.out_dir,env.top_dir,env.run_dir): p=os.path.join(k,Options.lockfile) remove_and_log(p,os.remove) 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 OSError: pass files=self.get_files() if self.algo.startswith('tar.'): tar=tarfile.open(node.abspath(),'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(node.abspath(),'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, tar.xz or zip') try: from hashlib import sha256 except ImportError: digest='' else: digest=' (sha256=%r)'%sha256(node.read(flags='rb')).hexdigest() 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' if os.path.isfile(p): with open(p,'rb')as f: tar.addfile(tinfo,fileobj=f) else: tar.addfile(tinfo) 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-2.* **/.waf-2.* **/waf3-2.* **/.waf3-2.* **/*~ **/*.rej **/*.orig **/*.pyc **/*.pyo **/*.bak **/*.swp **/.lock-w*' if Context.out_dir: 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 make_distcheck_cmd(self,tmpdir): cfg=[] if Options.options.distcheck_args: cfg=shlex.split(Options.options.distcheck_args) else: cfg=[x for x in sys.argv if x.startswith('-')] cmd=[sys.executable,sys.argv[0],'configure','build','install','uninstall','--destdir='+tmpdir]+cfg return cmd def check(self): import tempfile,tarfile with tarfile.open(self.get_arch_name())as t: for x in t: t.extract(x) instdir=tempfile.mkdtemp('.inst',self.get_base_name()) cmd=self.make_distcheck_cmd(instdir) ret=Utils.subprocess.Popen(cmd,cwd=self.get_base_name()).wait() if ret: raise Errors.WafError('distcheck failed with code %r'%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 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 EnvironmentError: 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: try: h=Utils.h_list((h,Utils.readf(f,'rb'))) except EnvironmentError: do_config=True break else: do_config=h!=env.hash if do_config: cmd=env.config_cmd or'configure' if Configure.autoconfig=='clobber': tmp=Options.options.__dict__ if env.options: Options.options.__dict__=env.options try: run_command(cmd) finally: Options.options.__dict__=tmp else: run_command(cmd) run_command(self.cmd) else: return execute_method(self) return execute Build.BuildContext.execute=autoconfigure(Build.BuildContext.execute)