summaryrefslogtreecommitdiff
path: root/waflib/Scripting.py
diff options
context:
space:
mode:
Diffstat (limited to 'waflib/Scripting.py')
-rw-r--r--waflib/Scripting.py403
1 files changed, 403 insertions, 0 deletions
diff --git a/waflib/Scripting.py b/waflib/Scripting.py
new file mode 100644
index 0000000..f7a3809
--- /dev/null
+++ b/waflib/Scripting.py
@@ -0,0 +1,403 @@
+#! /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
+ if not Context.run_dir:
+ 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(os.path.normpath(os.path.join(Context.run_dir,Context.WSCRIPT_FILE)))
+ except Errors.WafError as e:
+ Logs.pprint('RED',e.verbose_msg)
+ Logs.error(str(e))
+ sys.exit(1)
+ except Exception as 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 as e:
+ if Logs.verbose>1:
+ Logs.pprint('RED',e.verbose_msg)
+ Logs.error(e.msg)
+ sys.exit(1)
+ except SystemExit:
+ raise
+ except Exception as 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 as 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)