mirror of
https://github.com/cookiengineer/audacity
synced 2025-10-19 09:01:15 +02:00
Update local LV2 libraries to latest versions
lilv-0.24.6 lv2-1.16.0 serd-0.30.2 sord-0.16.4 sratom-0.6.4 suil-0.10.6
This commit is contained in:
@@ -1,317 +1,649 @@
|
||||
#! /usr/bin/env python
|
||||
#!/usr/bin/env python
|
||||
# encoding: utf-8
|
||||
# WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
|
||||
# Thomas Nagy, 2005-2018 (ita)
|
||||
|
||||
import os,shlex,sys,time
|
||||
from waflib import ConfigSet,Utils,Options,Logs,Context,Build,Errors
|
||||
try:
|
||||
from urllib import request
|
||||
except ImportError:
|
||||
from urllib import urlopen
|
||||
else:
|
||||
urlopen=request.urlopen
|
||||
BREAK='break'
|
||||
CONTINUE='continue'
|
||||
WAF_CONFIG_LOG='config.log'
|
||||
autoconfig=False
|
||||
conf_template='''# project %(app)s configured on %(now)s by
|
||||
"""
|
||||
Configuration system
|
||||
|
||||
A :py:class:`waflib.Configure.ConfigurationContext` instance is created when ``waf configure`` is called, it is used to:
|
||||
|
||||
* create data dictionaries (ConfigSet instances)
|
||||
* store the list of modules to import
|
||||
* hold configuration routines such as ``find_program``, etc
|
||||
"""
|
||||
|
||||
import os, re, shlex, shutil, sys, time, traceback
|
||||
from waflib import ConfigSet, Utils, Options, Logs, Context, Build, Errors
|
||||
|
||||
WAF_CONFIG_LOG = 'config.log'
|
||||
"""Name of the configuration log file"""
|
||||
|
||||
autoconfig = False
|
||||
"""Execute the configuration automatically"""
|
||||
|
||||
conf_template = '''# project %(app)s configured on %(now)s by
|
||||
# waf %(wafver)s (abi %(abi)s, python %(pyver)x on %(systype)s)
|
||||
# using %(args)s
|
||||
#'''
|
||||
def download_check(node):
|
||||
pass
|
||||
def download_tool(tool,force=False,ctx=None):
|
||||
for x in Utils.to_list(Context.remote_repo):
|
||||
for sub in Utils.to_list(Context.remote_locs):
|
||||
url='/'.join((x,sub,tool+'.py'))
|
||||
try:
|
||||
web=urlopen(url)
|
||||
try:
|
||||
if web.getcode()!=200:
|
||||
continue
|
||||
except AttributeError:
|
||||
pass
|
||||
except Exception:
|
||||
continue
|
||||
else:
|
||||
tmp=ctx.root.make_node(os.sep.join((Context.waf_dir,'waflib','extras',tool+'.py')))
|
||||
tmp.write(web.read(),'wb')
|
||||
Logs.warn('Downloaded %s from %s'%(tool,url))
|
||||
download_check(tmp)
|
||||
try:
|
||||
module=Context.load_tool(tool)
|
||||
except Exception:
|
||||
Logs.warn('The tool %s from %s is unusable'%(tool,url))
|
||||
try:
|
||||
tmp.delete()
|
||||
except Exception:
|
||||
pass
|
||||
continue
|
||||
return module
|
||||
raise Errors.WafError('Could not load the Waf tool')
|
||||
|
||||
class ConfigurationContext(Context.Context):
|
||||
'''configures the project'''
|
||||
cmd='configure'
|
||||
error_handlers=[]
|
||||
def __init__(self,**kw):
|
||||
super(ConfigurationContext,self).__init__(**kw)
|
||||
self.environ=dict(os.environ)
|
||||
self.all_envs={}
|
||||
self.top_dir=None
|
||||
self.out_dir=None
|
||||
self.tools=[]
|
||||
self.hash=0
|
||||
self.files=[]
|
||||
self.tool_cache=[]
|
||||
|
||||
cmd = 'configure'
|
||||
|
||||
error_handlers = []
|
||||
"""
|
||||
Additional functions to handle configuration errors
|
||||
"""
|
||||
|
||||
def __init__(self, **kw):
|
||||
super(ConfigurationContext, self).__init__(**kw)
|
||||
self.environ = dict(os.environ)
|
||||
self.all_envs = {}
|
||||
|
||||
self.top_dir = None
|
||||
self.out_dir = None
|
||||
|
||||
self.tools = [] # tools loaded in the configuration, and that will be loaded when building
|
||||
|
||||
self.hash = 0
|
||||
self.files = []
|
||||
|
||||
self.tool_cache = []
|
||||
|
||||
self.setenv('')
|
||||
def setenv(self,name,env=None):
|
||||
|
||||
def setenv(self, name, env=None):
|
||||
"""
|
||||
Set a new config set for conf.env. If a config set of that name already exists,
|
||||
recall it without modification.
|
||||
|
||||
The name is the filename prefix to save to ``c4che/NAME_cache.py``, and it
|
||||
is also used as *variants* by the build commands.
|
||||
Though related to variants, whatever kind of data may be stored in the config set::
|
||||
|
||||
def configure(cfg):
|
||||
cfg.env.ONE = 1
|
||||
cfg.setenv('foo')
|
||||
cfg.env.ONE = 2
|
||||
|
||||
def build(bld):
|
||||
2 == bld.env_of_name('foo').ONE
|
||||
|
||||
:param name: name of the configuration set
|
||||
:type name: string
|
||||
:param env: ConfigSet to copy, or an empty ConfigSet is created
|
||||
:type env: :py:class:`waflib.ConfigSet.ConfigSet`
|
||||
"""
|
||||
if name not in self.all_envs or env:
|
||||
if not env:
|
||||
env=ConfigSet.ConfigSet()
|
||||
env = ConfigSet.ConfigSet()
|
||||
self.prepare_env(env)
|
||||
else:
|
||||
env=env.derive()
|
||||
self.all_envs[name]=env
|
||||
self.variant=name
|
||||
env = env.derive()
|
||||
self.all_envs[name] = env
|
||||
self.variant = name
|
||||
|
||||
def get_env(self):
|
||||
"""Getter for the env property"""
|
||||
return self.all_envs[self.variant]
|
||||
def set_env(self,val):
|
||||
self.all_envs[self.variant]=val
|
||||
env=property(get_env,set_env)
|
||||
def set_env(self, val):
|
||||
"""Setter for the env property"""
|
||||
self.all_envs[self.variant] = val
|
||||
|
||||
env = property(get_env, set_env)
|
||||
|
||||
def init_dirs(self):
|
||||
top=self.top_dir
|
||||
"""
|
||||
Initialize the project directory and the build directory
|
||||
"""
|
||||
|
||||
top = self.top_dir
|
||||
if not top:
|
||||
top=Options.options.top
|
||||
top = Options.options.top
|
||||
if not top:
|
||||
top=getattr(Context.g_module,Context.TOP,None)
|
||||
top = getattr(Context.g_module, Context.TOP, None)
|
||||
if not top:
|
||||
top=self.path.abspath()
|
||||
top=os.path.abspath(top)
|
||||
self.srcnode=(os.path.isabs(top)and self.root or self.path).find_dir(top)
|
||||
top = self.path.abspath()
|
||||
top = os.path.abspath(top)
|
||||
|
||||
self.srcnode = (os.path.isabs(top) and self.root or self.path).find_dir(top)
|
||||
assert(self.srcnode)
|
||||
out=self.out_dir
|
||||
|
||||
out = self.out_dir
|
||||
if not out:
|
||||
out=Options.options.out
|
||||
out = Options.options.out
|
||||
if not out:
|
||||
out=getattr(Context.g_module,Context.OUT,None)
|
||||
out = getattr(Context.g_module, Context.OUT, None)
|
||||
if not out:
|
||||
out=Options.lockfile.replace('.lock-waf_%s_'%sys.platform,'').replace('.lock-waf','')
|
||||
self.bldnode=(os.path.isabs(out)and self.root or self.path).make_node(out)
|
||||
out = Options.lockfile.replace('.lock-waf_%s_' % sys.platform, '').replace('.lock-waf', '')
|
||||
|
||||
# someone can be messing with symlinks
|
||||
out = os.path.realpath(out)
|
||||
|
||||
self.bldnode = (os.path.isabs(out) and self.root or self.path).make_node(out)
|
||||
self.bldnode.mkdir()
|
||||
|
||||
if not os.path.isdir(self.bldnode.abspath()):
|
||||
conf.fatal('Could not create the build directory %s'%self.bldnode.abspath())
|
||||
self.fatal('Could not create the build directory %s' % self.bldnode.abspath())
|
||||
|
||||
def execute(self):
|
||||
"""
|
||||
See :py:func:`waflib.Context.Context.execute`
|
||||
"""
|
||||
self.init_dirs()
|
||||
self.cachedir=self.bldnode.make_node(Build.CACHE_DIR)
|
||||
|
||||
self.cachedir = self.bldnode.make_node(Build.CACHE_DIR)
|
||||
self.cachedir.mkdir()
|
||||
path=os.path.join(self.bldnode.abspath(),WAF_CONFIG_LOG)
|
||||
self.logger=Logs.make_logger(path,'cfg')
|
||||
app=getattr(Context.g_module,'APPNAME','')
|
||||
|
||||
path = os.path.join(self.bldnode.abspath(), WAF_CONFIG_LOG)
|
||||
self.logger = Logs.make_logger(path, 'cfg')
|
||||
|
||||
app = getattr(Context.g_module, 'APPNAME', '')
|
||||
if app:
|
||||
ver=getattr(Context.g_module,'VERSION','')
|
||||
ver = getattr(Context.g_module, 'VERSION', '')
|
||||
if ver:
|
||||
app="%s (%s)"%(app,ver)
|
||||
now=time.ctime()
|
||||
pyver=sys.hexversion
|
||||
systype=sys.platform
|
||||
args=" ".join(sys.argv)
|
||||
wafver=Context.WAFVERSION
|
||||
abi=Context.ABI
|
||||
self.to_log(conf_template%vars())
|
||||
self.msg('Setting top to',self.srcnode.abspath())
|
||||
self.msg('Setting out to',self.bldnode.abspath())
|
||||
if id(self.srcnode)==id(self.bldnode):
|
||||
Logs.warn('Setting top == out (remember to use "update_outputs")')
|
||||
elif id(self.path)!=id(self.srcnode):
|
||||
app = "%s (%s)" % (app, ver)
|
||||
|
||||
params = {'now': time.ctime(), 'pyver': sys.hexversion, 'systype': sys.platform, 'args': " ".join(sys.argv), 'wafver': Context.WAFVERSION, 'abi': Context.ABI, 'app': app}
|
||||
self.to_log(conf_template % params)
|
||||
self.msg('Setting top to', self.srcnode.abspath())
|
||||
self.msg('Setting out to', self.bldnode.abspath())
|
||||
|
||||
if id(self.srcnode) == id(self.bldnode):
|
||||
Logs.warn('Setting top == out')
|
||||
elif id(self.path) != id(self.srcnode):
|
||||
if self.srcnode.is_child_of(self.path):
|
||||
Logs.warn('Are you certain that you do not want to set top="." ?')
|
||||
super(ConfigurationContext,self).execute()
|
||||
|
||||
super(ConfigurationContext, self).execute()
|
||||
|
||||
self.store()
|
||||
Context.top_dir=self.srcnode.abspath()
|
||||
Context.out_dir=self.bldnode.abspath()
|
||||
env=ConfigSet.ConfigSet()
|
||||
env['argv']=sys.argv
|
||||
env['options']=Options.options.__dict__
|
||||
env.run_dir=Context.run_dir
|
||||
env.top_dir=Context.top_dir
|
||||
env.out_dir=Context.out_dir
|
||||
env['hash']=self.hash
|
||||
env['files']=self.files
|
||||
env['environ']=dict(self.environ)
|
||||
if not self.env.NO_LOCK_IN_RUN:
|
||||
env.store(Context.run_dir+os.sep+Options.lockfile)
|
||||
if not self.env.NO_LOCK_IN_TOP:
|
||||
env.store(Context.top_dir+os.sep+Options.lockfile)
|
||||
if not self.env.NO_LOCK_IN_OUT:
|
||||
env.store(Context.out_dir+os.sep+Options.lockfile)
|
||||
def prepare_env(self,env):
|
||||
|
||||
Context.top_dir = self.srcnode.abspath()
|
||||
Context.out_dir = self.bldnode.abspath()
|
||||
|
||||
# this will write a configure lock so that subsequent builds will
|
||||
# consider the current path as the root directory (see prepare_impl).
|
||||
# to remove: use 'waf distclean'
|
||||
env = ConfigSet.ConfigSet()
|
||||
env.argv = sys.argv
|
||||
env.options = Options.options.__dict__
|
||||
env.config_cmd = self.cmd
|
||||
|
||||
env.run_dir = Context.run_dir
|
||||
env.top_dir = Context.top_dir
|
||||
env.out_dir = Context.out_dir
|
||||
|
||||
# conf.hash & conf.files hold wscript files paths and hash
|
||||
# (used only by Configure.autoconfig)
|
||||
env.hash = self.hash
|
||||
env.files = self.files
|
||||
env.environ = dict(self.environ)
|
||||
env.launch_dir = Context.launch_dir
|
||||
|
||||
if not (self.env.NO_LOCK_IN_RUN or env.environ.get('NO_LOCK_IN_RUN') or getattr(Options.options, 'no_lock_in_run')):
|
||||
env.store(os.path.join(Context.run_dir, Options.lockfile))
|
||||
if not (self.env.NO_LOCK_IN_TOP or env.environ.get('NO_LOCK_IN_TOP') or getattr(Options.options, 'no_lock_in_top')):
|
||||
env.store(os.path.join(Context.top_dir, Options.lockfile))
|
||||
if not (self.env.NO_LOCK_IN_OUT or env.environ.get('NO_LOCK_IN_OUT') or getattr(Options.options, 'no_lock_in_out')):
|
||||
env.store(os.path.join(Context.out_dir, Options.lockfile))
|
||||
|
||||
def prepare_env(self, env):
|
||||
"""
|
||||
Insert *PREFIX*, *BINDIR* and *LIBDIR* values into ``env``
|
||||
|
||||
:type env: :py:class:`waflib.ConfigSet.ConfigSet`
|
||||
:param env: a ConfigSet, usually ``conf.env``
|
||||
"""
|
||||
if not env.PREFIX:
|
||||
if Options.options.prefix or Utils.is_win32:
|
||||
env.PREFIX=os.path.abspath(os.path.expanduser(Options.options.prefix))
|
||||
env.PREFIX = Options.options.prefix
|
||||
else:
|
||||
env.PREFIX=''
|
||||
env.PREFIX = '/'
|
||||
if not env.BINDIR:
|
||||
env.BINDIR=Utils.subst_vars('${PREFIX}/bin',env)
|
||||
if Options.options.bindir:
|
||||
env.BINDIR = Options.options.bindir
|
||||
else:
|
||||
env.BINDIR = Utils.subst_vars('${PREFIX}/bin', env)
|
||||
if not env.LIBDIR:
|
||||
env.LIBDIR=Utils.subst_vars('${PREFIX}/lib',env)
|
||||
if Options.options.libdir:
|
||||
env.LIBDIR = Options.options.libdir
|
||||
else:
|
||||
env.LIBDIR = Utils.subst_vars('${PREFIX}/lib%s' % Utils.lib64(), env)
|
||||
|
||||
def store(self):
|
||||
n=self.cachedir.make_node('build.config.py')
|
||||
n.write('version = 0x%x\ntools = %r\n'%(Context.HEXVERSION,self.tools))
|
||||
"""Save the config results into the cache file"""
|
||||
n = self.cachedir.make_node('build.config.py')
|
||||
n.write('version = 0x%x\ntools = %r\n' % (Context.HEXVERSION, self.tools))
|
||||
|
||||
if not self.all_envs:
|
||||
self.fatal('nothing to store in the configuration context!')
|
||||
|
||||
for key in self.all_envs:
|
||||
tmpenv=self.all_envs[key]
|
||||
tmpenv.store(os.path.join(self.cachedir.abspath(),key+Build.CACHE_SUFFIX))
|
||||
def load(self,input,tooldir=None,funs=None,download=True):
|
||||
tools=Utils.to_list(input)
|
||||
if tooldir:tooldir=Utils.to_list(tooldir)
|
||||
tmpenv = self.all_envs[key]
|
||||
tmpenv.store(os.path.join(self.cachedir.abspath(), key + Build.CACHE_SUFFIX))
|
||||
|
||||
def load(self, tool_list, tooldir=None, funs=None, with_sys_path=True, cache=False):
|
||||
"""
|
||||
Load Waf tools, which will be imported whenever a build is started.
|
||||
|
||||
:param tool_list: waf tools to import
|
||||
:type tool_list: list of string
|
||||
:param tooldir: paths for the imports
|
||||
:type tooldir: list of string
|
||||
:param funs: functions to execute from the waf tools
|
||||
:type funs: list of string
|
||||
:param cache: whether to prevent the tool from running twice
|
||||
:type cache: bool
|
||||
"""
|
||||
|
||||
tools = Utils.to_list(tool_list)
|
||||
if tooldir:
|
||||
tooldir = Utils.to_list(tooldir)
|
||||
for tool in tools:
|
||||
mag=(tool,id(self.env),funs)
|
||||
if mag in self.tool_cache:
|
||||
self.to_log('(tool %s is already loaded, skipping)'%tool)
|
||||
continue
|
||||
self.tool_cache.append(mag)
|
||||
module=None
|
||||
# avoid loading the same tool more than once with the same functions
|
||||
# used by composite projects
|
||||
|
||||
if cache:
|
||||
mag = (tool, id(self.env), tooldir, funs)
|
||||
if mag in self.tool_cache:
|
||||
self.to_log('(tool %s is already loaded, skipping)' % tool)
|
||||
continue
|
||||
self.tool_cache.append(mag)
|
||||
|
||||
module = None
|
||||
try:
|
||||
module=Context.load_tool(tool,tooldir)
|
||||
except ImportError ,e:
|
||||
if Options.options.download:
|
||||
module=download_tool(tool,ctx=self)
|
||||
if not module:
|
||||
self.fatal('Could not load the Waf tool %r or download a suitable replacement from the repository (sys.path %r)\n%s'%(tool,sys.path,e))
|
||||
else:
|
||||
self.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s'%(tool,sys.path,e))
|
||||
except Exception ,e:
|
||||
self.to_log('imp %r (%r & %r)'%(tool,tooldir,funs))
|
||||
self.to_log(Utils.ex_stack())
|
||||
module = Context.load_tool(tool, tooldir, ctx=self, with_sys_path=with_sys_path)
|
||||
except ImportError as e:
|
||||
self.fatal('Could not load the Waf tool %r from %r\n%s' % (tool, getattr(e, 'waf_sys_path', sys.path), e))
|
||||
except Exception as e:
|
||||
self.to_log('imp %r (%r & %r)' % (tool, tooldir, funs))
|
||||
self.to_log(traceback.format_exc())
|
||||
raise
|
||||
|
||||
if funs is not None:
|
||||
self.eval_rules(funs)
|
||||
else:
|
||||
func=getattr(module,'configure',None)
|
||||
func = getattr(module, 'configure', None)
|
||||
if func:
|
||||
if type(func)is type(Utils.readf):func(self)
|
||||
else:self.eval_rules(func)
|
||||
self.tools.append({'tool':tool,'tooldir':tooldir,'funs':funs})
|
||||
def post_recurse(self,node):
|
||||
super(ConfigurationContext,self).post_recurse(node)
|
||||
self.hash=Utils.h_list((self.hash,node.read('rb')))
|
||||
if type(func) is type(Utils.readf):
|
||||
func(self)
|
||||
else:
|
||||
self.eval_rules(func)
|
||||
|
||||
self.tools.append({'tool':tool, 'tooldir':tooldir, 'funs':funs})
|
||||
|
||||
def post_recurse(self, node):
|
||||
"""
|
||||
Records the path and a hash of the scripts visited, see :py:meth:`waflib.Context.Context.post_recurse`
|
||||
|
||||
:param node: script
|
||||
:type node: :py:class:`waflib.Node.Node`
|
||||
"""
|
||||
super(ConfigurationContext, self).post_recurse(node)
|
||||
self.hash = Utils.h_list((self.hash, node.read('rb')))
|
||||
self.files.append(node.abspath())
|
||||
def eval_rules(self,rules):
|
||||
self.rules=Utils.to_list(rules)
|
||||
|
||||
def eval_rules(self, rules):
|
||||
"""
|
||||
Execute configuration tests provided as list of functions to run
|
||||
|
||||
:param rules: list of configuration method names
|
||||
:type rules: list of string
|
||||
"""
|
||||
self.rules = Utils.to_list(rules)
|
||||
for x in self.rules:
|
||||
f=getattr(self,x)
|
||||
if not f:self.fatal("No such method '%s'."%x)
|
||||
try:
|
||||
f()
|
||||
except Exception ,e:
|
||||
ret=self.err_handler(x,e)
|
||||
if ret==BREAK:
|
||||
break
|
||||
elif ret==CONTINUE:
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
def err_handler(self,fun,error):
|
||||
pass
|
||||
f = getattr(self, x)
|
||||
if not f:
|
||||
self.fatal('No such configuration function %r' % x)
|
||||
f()
|
||||
|
||||
def conf(f):
|
||||
def fun(*k,**kw):
|
||||
mandatory=True
|
||||
if'mandatory'in kw:
|
||||
mandatory=kw['mandatory']
|
||||
del kw['mandatory']
|
||||
"""
|
||||
Decorator: attach new configuration functions to :py:class:`waflib.Build.BuildContext` and
|
||||
:py:class:`waflib.Configure.ConfigurationContext`. The methods bound will accept a parameter
|
||||
named 'mandatory' to disable the configuration errors::
|
||||
|
||||
def configure(conf):
|
||||
conf.find_program('abc', mandatory=False)
|
||||
|
||||
:param f: method to bind
|
||||
:type f: function
|
||||
"""
|
||||
def fun(*k, **kw):
|
||||
mandatory = kw.pop('mandatory', True)
|
||||
try:
|
||||
return f(*k,**kw)
|
||||
return f(*k, **kw)
|
||||
except Errors.ConfigurationError:
|
||||
if mandatory:
|
||||
raise
|
||||
setattr(ConfigurationContext,f.__name__,fun)
|
||||
setattr(Build.BuildContext,f.__name__,fun)
|
||||
|
||||
fun.__name__ = f.__name__
|
||||
setattr(ConfigurationContext, f.__name__, fun)
|
||||
setattr(Build.BuildContext, f.__name__, fun)
|
||||
return f
|
||||
|
||||
@conf
|
||||
def add_os_flags(self,var,dest=None):
|
||||
try:self.env.append_value(dest or var,shlex.split(self.environ[var]))
|
||||
except KeyError:pass
|
||||
def add_os_flags(self, var, dest=None, dup=False):
|
||||
"""
|
||||
Import operating system environment values into ``conf.env`` dict::
|
||||
|
||||
def configure(conf):
|
||||
conf.add_os_flags('CFLAGS')
|
||||
|
||||
:param var: variable to use
|
||||
:type var: string
|
||||
:param dest: destination variable, by default the same as var
|
||||
:type dest: string
|
||||
:param dup: add the same set of flags again
|
||||
:type dup: bool
|
||||
"""
|
||||
try:
|
||||
flags = shlex.split(self.environ[var])
|
||||
except KeyError:
|
||||
return
|
||||
if dup or ''.join(flags) not in ''.join(Utils.to_list(self.env[dest or var])):
|
||||
self.env.append_value(dest or var, flags)
|
||||
|
||||
@conf
|
||||
def cmd_to_list(self,cmd):
|
||||
if isinstance(cmd,str)and cmd.find(' '):
|
||||
try:
|
||||
os.stat(cmd)
|
||||
except OSError:
|
||||
def cmd_to_list(self, cmd):
|
||||
"""
|
||||
Detect if a command is written in pseudo shell like ``ccache g++`` and return a list.
|
||||
|
||||
:param cmd: command
|
||||
:type cmd: a string or a list of string
|
||||
"""
|
||||
if isinstance(cmd, str):
|
||||
if os.path.isfile(cmd):
|
||||
# do not take any risk
|
||||
return [cmd]
|
||||
if os.sep == '/':
|
||||
return shlex.split(cmd)
|
||||
else:
|
||||
return[cmd]
|
||||
try:
|
||||
return shlex.split(cmd, posix=False)
|
||||
except TypeError:
|
||||
# Python 2.5 on windows?
|
||||
return shlex.split(cmd)
|
||||
return cmd
|
||||
|
||||
@conf
|
||||
def check_waf_version(self,mini='1.6.99',maxi='1.8.0'):
|
||||
self.start_msg('Checking for waf version in %s-%s'%(str(mini),str(maxi)))
|
||||
ver=Context.HEXVERSION
|
||||
if Utils.num2ver(mini)>ver:
|
||||
self.fatal('waf version should be at least %r (%r found)'%(Utils.num2ver(mini),ver))
|
||||
if Utils.num2ver(maxi)<ver:
|
||||
self.fatal('waf version should be at most %r (%r found)'%(Utils.num2ver(maxi),ver))
|
||||
self.end_msg('ok')
|
||||
def check_waf_version(self, mini='1.9.99', maxi='2.1.0', **kw):
|
||||
"""
|
||||
Raise a Configuration error if the Waf version does not strictly match the given bounds::
|
||||
|
||||
conf.check_waf_version(mini='1.9.99', maxi='2.1.0')
|
||||
|
||||
:type mini: number, tuple or string
|
||||
:param mini: Minimum required version
|
||||
:type maxi: number, tuple or string
|
||||
:param maxi: Maximum allowed version
|
||||
"""
|
||||
self.start_msg('Checking for waf version in %s-%s' % (str(mini), str(maxi)), **kw)
|
||||
ver = Context.HEXVERSION
|
||||
if Utils.num2ver(mini) > ver:
|
||||
self.fatal('waf version should be at least %r (%r found)' % (Utils.num2ver(mini), ver))
|
||||
if Utils.num2ver(maxi) < ver:
|
||||
self.fatal('waf version should be at most %r (%r found)' % (Utils.num2ver(maxi), ver))
|
||||
self.end_msg('ok', **kw)
|
||||
|
||||
@conf
|
||||
def find_file(self,filename,path_list=[]):
|
||||
def find_file(self, filename, path_list=[]):
|
||||
"""
|
||||
Find a file in a list of paths
|
||||
|
||||
:param filename: name of the file to search for
|
||||
:param path_list: list of directories to search
|
||||
:return: the first matching filename; else a configuration exception is raised
|
||||
"""
|
||||
for n in Utils.to_list(filename):
|
||||
for d in Utils.to_list(path_list):
|
||||
p=os.path.join(d,n)
|
||||
p = os.path.expanduser(os.path.join(d, n))
|
||||
if os.path.exists(p):
|
||||
return p
|
||||
self.fatal('Could not find %r'%filename)
|
||||
self.fatal('Could not find %r' % filename)
|
||||
|
||||
@conf
|
||||
def find_program(self,filename,**kw):
|
||||
exts=kw.get('exts',Utils.is_win32 and'.exe,.com,.bat,.cmd'or',.sh,.pl,.py')
|
||||
environ=kw.get('environ',os.environ)
|
||||
ret=''
|
||||
filename=Utils.to_list(filename)
|
||||
var=kw.get('var','')
|
||||
def find_program(self, filename, **kw):
|
||||
"""
|
||||
Search for a program on the operating system
|
||||
|
||||
When var is used, you may set os.environ[var] to help find a specific program version, for example::
|
||||
|
||||
$ CC='ccache gcc' waf configure
|
||||
|
||||
:param path_list: paths to use for searching
|
||||
:type param_list: list of string
|
||||
:param var: store the result to conf.env[var] where var defaults to filename.upper() if not provided; the result is stored as a list of strings
|
||||
:type var: string
|
||||
:param value: obtain the program from the value passed exclusively
|
||||
:type value: list or string (list is preferred)
|
||||
:param exts: list of extensions for the binary (do not add an extension for portability)
|
||||
:type exts: list of string
|
||||
:param msg: name to display in the log, by default filename is used
|
||||
:type msg: string
|
||||
:param interpreter: interpreter for the program
|
||||
:type interpreter: ConfigSet variable key
|
||||
:raises: :py:class:`waflib.Errors.ConfigurationError`
|
||||
"""
|
||||
|
||||
exts = kw.get('exts', Utils.is_win32 and '.exe,.com,.bat,.cmd' or ',.sh,.pl,.py')
|
||||
|
||||
environ = kw.get('environ', getattr(self, 'environ', os.environ))
|
||||
|
||||
ret = ''
|
||||
|
||||
filename = Utils.to_list(filename)
|
||||
msg = kw.get('msg', ', '.join(filename))
|
||||
|
||||
var = kw.get('var', '')
|
||||
if not var:
|
||||
var=filename[0].upper()
|
||||
if self.env[var]:
|
||||
ret=self.env[var]
|
||||
elif var in environ:
|
||||
ret=environ[var]
|
||||
path_list=kw.get('path_list','')
|
||||
if not ret:
|
||||
if path_list:
|
||||
path_list=Utils.to_list(path_list)
|
||||
var = re.sub(r'[-.]', '_', filename[0].upper())
|
||||
|
||||
path_list = kw.get('path_list', '')
|
||||
if path_list:
|
||||
path_list = Utils.to_list(path_list)
|
||||
else:
|
||||
path_list = environ.get('PATH', '').split(os.pathsep)
|
||||
|
||||
if kw.get('value'):
|
||||
# user-provided in command-line options and passed to find_program
|
||||
ret = self.cmd_to_list(kw['value'])
|
||||
elif environ.get(var):
|
||||
# user-provided in the os environment
|
||||
ret = self.cmd_to_list(environ[var])
|
||||
elif self.env[var]:
|
||||
# a default option in the wscript file
|
||||
ret = self.cmd_to_list(self.env[var])
|
||||
else:
|
||||
if not ret:
|
||||
ret = self.find_binary(filename, exts.split(','), path_list)
|
||||
if not ret and Utils.winreg:
|
||||
ret = Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER, filename)
|
||||
if not ret and Utils.winreg:
|
||||
ret = Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE, filename)
|
||||
ret = self.cmd_to_list(ret)
|
||||
|
||||
if ret:
|
||||
if len(ret) == 1:
|
||||
retmsg = ret[0]
|
||||
else:
|
||||
path_list=environ.get('PATH','').split(os.pathsep)
|
||||
if not isinstance(filename,list):
|
||||
filename=[filename]
|
||||
for a in exts.split(','):
|
||||
if ret:
|
||||
break
|
||||
for b in filename:
|
||||
if ret:
|
||||
break
|
||||
for c in path_list:
|
||||
if ret:
|
||||
break
|
||||
x=os.path.expanduser(os.path.join(c,b+a))
|
||||
if os.path.isfile(x):
|
||||
ret=x
|
||||
if not ret and Utils.winreg:
|
||||
ret=Utils.get_registry_app_path(Utils.winreg.HKEY_CURRENT_USER,filename)
|
||||
if not ret and Utils.winreg:
|
||||
ret=Utils.get_registry_app_path(Utils.winreg.HKEY_LOCAL_MACHINE,filename)
|
||||
self.msg('Checking for program '+','.join(filename),ret or False)
|
||||
self.to_log('find program=%r paths=%r var=%r -> %r'%(filename,path_list,var,ret))
|
||||
retmsg = ret
|
||||
else:
|
||||
retmsg = False
|
||||
|
||||
self.msg('Checking for program %r' % msg, retmsg, **kw)
|
||||
if not kw.get('quiet'):
|
||||
self.to_log('find program=%r paths=%r var=%r -> %r' % (filename, path_list, var, ret))
|
||||
|
||||
if not ret:
|
||||
self.fatal(kw.get('errmsg','')or'Could not find the program %s'%','.join(filename))
|
||||
if var:
|
||||
self.env[var]=ret
|
||||
self.fatal(kw.get('errmsg', '') or 'Could not find the program %r' % filename)
|
||||
|
||||
interpreter = kw.get('interpreter')
|
||||
if interpreter is None:
|
||||
if not Utils.check_exe(ret[0], env=environ):
|
||||
self.fatal('Program %r is not executable' % ret)
|
||||
self.env[var] = ret
|
||||
else:
|
||||
self.env[var] = self.env[interpreter] + ret
|
||||
|
||||
return ret
|
||||
|
||||
@conf
|
||||
def find_perl_program(self,filename,path_list=[],var=None,environ=None,exts=''):
|
||||
def find_binary(self, filenames, exts, paths):
|
||||
for f in filenames:
|
||||
for ext in exts:
|
||||
exe_name = f + ext
|
||||
if os.path.isabs(exe_name):
|
||||
if os.path.isfile(exe_name):
|
||||
return exe_name
|
||||
else:
|
||||
for path in paths:
|
||||
x = os.path.expanduser(os.path.join(path, exe_name))
|
||||
if os.path.isfile(x):
|
||||
return x
|
||||
return None
|
||||
|
||||
@conf
|
||||
def run_build(self, *k, **kw):
|
||||
"""
|
||||
Create a temporary build context to execute a build. A reference to that build
|
||||
context is kept on self.test_bld for debugging purposes, and you should not rely
|
||||
on it too much (read the note on the cache below).
|
||||
The parameters given in the arguments to this function are passed as arguments for
|
||||
a single task generator created in the build. Only three parameters are obligatory:
|
||||
|
||||
:param features: features to pass to a task generator created in the build
|
||||
:type features: list of string
|
||||
:param compile_filename: file to create for the compilation (default: *test.c*)
|
||||
:type compile_filename: string
|
||||
:param code: code to write in the filename to compile
|
||||
:type code: string
|
||||
|
||||
Though this function returns *0* by default, the build may set an attribute named *retval* on the
|
||||
build context object to return a particular value. See :py:func:`waflib.Tools.c_config.test_exec_fun` for example.
|
||||
|
||||
This function also features a cache which can be enabled by the following option::
|
||||
|
||||
def options(opt):
|
||||
opt.add_option('--confcache', dest='confcache', default=0,
|
||||
action='count', help='Use a configuration cache')
|
||||
|
||||
And execute the configuration with the following command-line::
|
||||
|
||||
$ waf configure --confcache
|
||||
|
||||
"""
|
||||
buf = []
|
||||
for key in sorted(kw.keys()):
|
||||
v = kw[key]
|
||||
if hasattr(v, '__call__'):
|
||||
buf.append(Utils.h_fun(v))
|
||||
else:
|
||||
buf.append(str(v))
|
||||
h = Utils.h_list(buf)
|
||||
dir = self.bldnode.abspath() + os.sep + (not Utils.is_win32 and '.' or '') + 'conf_check_' + Utils.to_hex(h)
|
||||
|
||||
cachemode = kw.get('confcache', getattr(Options.options, 'confcache', None))
|
||||
|
||||
if not cachemode and os.path.exists(dir):
|
||||
shutil.rmtree(dir)
|
||||
|
||||
try:
|
||||
app=self.find_program(filename,path_list=path_list,var=var,environ=environ,exts=exts)
|
||||
except Exception:
|
||||
self.find_program('perl',var='PERL')
|
||||
app=self.find_file(filename,os.environ['PATH'].split(os.pathsep))
|
||||
if not app:
|
||||
os.makedirs(dir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
try:
|
||||
os.stat(dir)
|
||||
except OSError:
|
||||
self.fatal('cannot use the configuration test folder %r' % dir)
|
||||
|
||||
if cachemode == 1:
|
||||
try:
|
||||
proj = ConfigSet.ConfigSet(os.path.join(dir, 'cache_run_build'))
|
||||
except EnvironmentError:
|
||||
pass
|
||||
else:
|
||||
ret = proj['cache_run_build']
|
||||
if isinstance(ret, str) and ret.startswith('Test does not build'):
|
||||
self.fatal(ret)
|
||||
return ret
|
||||
|
||||
bdir = os.path.join(dir, 'testbuild')
|
||||
|
||||
if not os.path.exists(bdir):
|
||||
os.makedirs(bdir)
|
||||
|
||||
cls_name = kw.get('run_build_cls') or getattr(self, 'run_build_cls', 'build')
|
||||
self.test_bld = bld = Context.create_context(cls_name, top_dir=dir, out_dir=bdir)
|
||||
bld.init_dirs()
|
||||
bld.progress_bar = 0
|
||||
bld.targets = '*'
|
||||
|
||||
bld.logger = self.logger
|
||||
bld.all_envs.update(self.all_envs) # not really necessary
|
||||
bld.env = kw['env']
|
||||
|
||||
bld.kw = kw
|
||||
bld.conf = self
|
||||
kw['build_fun'](bld)
|
||||
ret = -1
|
||||
try:
|
||||
try:
|
||||
bld.compile()
|
||||
except Errors.WafError:
|
||||
ret = 'Test does not build: %s' % traceback.format_exc()
|
||||
self.fatal(ret)
|
||||
else:
|
||||
ret = getattr(bld, 'retval', 0)
|
||||
finally:
|
||||
if cachemode:
|
||||
# cache the results each time
|
||||
proj = ConfigSet.ConfigSet()
|
||||
proj['cache_run_build'] = ret
|
||||
proj.store(os.path.join(dir, 'cache_run_build'))
|
||||
else:
|
||||
shutil.rmtree(dir)
|
||||
return ret
|
||||
|
||||
@conf
|
||||
def ret_msg(self, msg, args):
|
||||
if isinstance(msg, str):
|
||||
return msg
|
||||
return msg(args)
|
||||
|
||||
@conf
|
||||
def test(self, *k, **kw):
|
||||
|
||||
if not 'env' in kw:
|
||||
kw['env'] = self.env.derive()
|
||||
|
||||
# validate_c for example
|
||||
if kw.get('validate'):
|
||||
kw['validate'](kw)
|
||||
|
||||
self.start_msg(kw['msg'], **kw)
|
||||
ret = None
|
||||
try:
|
||||
ret = self.run_build(*k, **kw)
|
||||
except self.errors.ConfigurationError:
|
||||
self.end_msg(kw['errmsg'], 'YELLOW', **kw)
|
||||
if Logs.verbose > 1:
|
||||
raise
|
||||
if var:
|
||||
self.env[var]=Utils.to_list(self.env['PERL'])+[app]
|
||||
self.msg('Checking for %r'%filename,app)
|
||||
else:
|
||||
self.fatal('The configuration failed')
|
||||
else:
|
||||
kw['success'] = ret
|
||||
|
||||
if kw.get('post_check'):
|
||||
ret = kw['post_check'](kw)
|
||||
|
||||
if ret:
|
||||
self.end_msg(kw['errmsg'], 'YELLOW', **kw)
|
||||
self.fatal('The configuration failed %r' % ret)
|
||||
else:
|
||||
self.end_msg(self.ret_msg(kw['okmsg'], kw), **kw)
|
||||
return ret
|
||||
|
||||
|
Reference in New Issue
Block a user