waf

FORK: waf with some random patches
git clone https://git.neptards.moe/neptards/waf.git
Log | Files | Refs | README

use_config.py (5657B)


      1 #!/usr/bin/env python
      2 # coding=utf-8
      3 # Mathieu Courtois - EDF R&D, 2013 - http://www.code-aster.org
      4 
      5 """
      6 When a project has a lot of options the 'waf configure' command line can be
      7 very long and it becomes a cause of error.
      8 This tool provides a convenient way to load a set of configuration parameters
      9 from a local file or from a remote url.
     10 
     11 The configuration parameters are stored in a Python file that is imported as
     12 an extra waf tool can be.
     13 
     14 Example:
     15 $ waf configure --use-config-dir=http://www.anywhere.org --use-config=myconf1 ...
     16 
     17 The file 'myconf1' will be downloaded from 'http://www.anywhere.org'
     18 (or 'http://www.anywhere.org/wafcfg').
     19 If the files are available locally, it could be:
     20 $ waf configure --use-config-dir=/somewhere/myconfigurations --use-config=myconf1 ...
     21 
     22 The configuration of 'myconf1.py' is automatically loaded by calling
     23 its 'configure' function. In this example, it defines environment variables and
     24 set options:
     25 
     26 def configure(self):
     27 	self.env['CC'] = 'gcc-4.8'
     28 	self.env.append_value('LIBPATH', [...])
     29 	self.options.perlbinary = '/usr/local/bin/perl'
     30 	self.options.pyc = False
     31 
     32 The corresponding command line should have been:
     33 $ CC=gcc-4.8 LIBPATH=... waf configure --nopyc --with-perl-binary=/usr/local/bin/perl
     34 
     35 
     36 This is an extra tool, not bundled with the default waf binary.
     37 To add the use_config tool to the waf file:
     38 $ ./waf-light --tools=use_config
     39 
     40 When using this tool, the wscript will look like:
     41 
     42 	def options(opt):
     43 		opt.load('use_config')
     44 
     45 	def configure(conf):
     46 		conf.load('use_config')
     47 """
     48 
     49 import sys
     50 import os.path as osp
     51 import os
     52 
     53 local_repo = ''
     54 """Local repository containing additional Waf tools (plugins)"""
     55 remote_repo = 'https://gitlab.com/ita1024/waf/raw/master/'
     56 """
     57 Remote directory containing downloadable waf tools. The missing tools can be downloaded by using::
     58 
     59 	$ waf configure --download
     60 """
     61 
     62 remote_locs = ['waflib/extras', 'waflib/Tools']
     63 """
     64 Remote directories for use with :py:const:`waflib.extras.use_config.remote_repo`
     65 """
     66 
     67 
     68 try:
     69 	from urllib import request
     70 except ImportError:
     71 	from urllib import urlopen
     72 else:
     73 	urlopen = request.urlopen
     74 
     75 
     76 from waflib import Errors, Context, Logs, Utils, Options, Configure
     77 
     78 try:
     79 	from urllib.parse import urlparse
     80 except ImportError:
     81 	from urlparse import urlparse
     82 
     83 
     84 
     85 
     86 DEFAULT_DIR = 'wafcfg'
     87 # add first the current wafcfg subdirectory
     88 sys.path.append(osp.abspath(DEFAULT_DIR))
     89 
     90 def options(self):
     91 	group = self.add_option_group('configure options')
     92 	group.add_option('--download', dest='download', default=False, action='store_true', help='try to download the tools if missing')
     93 
     94 	group.add_option('--use-config', action='store', default=None,
     95 					 metavar='CFG', dest='use_config',
     96 					 help='force the configuration parameters by importing '
     97 						  'CFG.py. Several modules may be provided (comma '
     98 						  'separated).')
     99 	group.add_option('--use-config-dir', action='store', default=DEFAULT_DIR,
    100 					 metavar='CFG_DIR', dest='use_config_dir',
    101 					 help='path or url where to find the configuration file')
    102 
    103 def download_check(node):
    104 	"""
    105 	Hook to check for the tools which are downloaded. Replace with your function if necessary.
    106 	"""
    107 	pass
    108 
    109 
    110 def download_tool(tool, force=False, ctx=None):
    111 	"""
    112 	Download a Waf tool from the remote repository defined in :py:const:`waflib.extras.use_config.remote_repo`::
    113 
    114 		$ waf configure --download
    115 	"""
    116 	for x in Utils.to_list(remote_repo):
    117 		for sub in Utils.to_list(remote_locs):
    118 			url = '/'.join((x, sub, tool + '.py'))
    119 			try:
    120 				web = urlopen(url)
    121 				try:
    122 					if web.getcode() != 200:
    123 						continue
    124 				except AttributeError:
    125 					pass
    126 			except Exception:
    127 				# on python3 urlopen throws an exception
    128 				# python 2.3 does not have getcode and throws an exception to fail
    129 				continue
    130 			else:
    131 				tmp = ctx.root.make_node(os.sep.join((Context.waf_dir, 'waflib', 'extras', tool + '.py')))
    132 				tmp.write(web.read(), 'wb')
    133 				Logs.warn('Downloaded %s from %s', tool, url)
    134 				download_check(tmp)
    135 				try:
    136 					module = Context.load_tool(tool)
    137 				except Exception:
    138 					Logs.warn('The tool %s from %s is unusable', tool, url)
    139 					try:
    140 						tmp.delete()
    141 					except Exception:
    142 						pass
    143 					continue
    144 				return module
    145 
    146 	raise Errors.WafError('Could not load the Waf tool')
    147 
    148 def load_tool(tool, tooldir=None, ctx=None, with_sys_path=True):
    149 	try:
    150 		module = Context.load_tool_default(tool, tooldir, ctx, with_sys_path)
    151 	except ImportError as e:
    152 		if not ctx or not hasattr(Options.options, 'download'):
    153 			Logs.error('Could not load %r during options phase (download unavailable at this point)' % tool)
    154 			raise
    155 		if Options.options.download:
    156 			module = download_tool(tool, ctx=ctx)
    157 			if not module:
    158 				ctx.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))
    159 		else:
    160 			ctx.fatal('Could not load the Waf tool %r from %r (try the --download option?):\n%s' % (tool, sys.path, e))
    161 	return module
    162 
    163 Context.load_tool_default = Context.load_tool
    164 Context.load_tool = load_tool
    165 Configure.download_tool = download_tool
    166 
    167 def configure(self):
    168 	opts = self.options
    169 	use_cfg = opts.use_config
    170 	if use_cfg is None:
    171 		return
    172 	url = urlparse(opts.use_config_dir)
    173 	kwargs = {}
    174 	if url.scheme:
    175 		kwargs['download'] = True
    176 		kwargs['remote_url'] = url.geturl()
    177 		# search first with the exact url, else try with +'/wafcfg'
    178 		kwargs['remote_locs'] = ['', DEFAULT_DIR]
    179 	tooldir = url.geturl() + ' ' + DEFAULT_DIR
    180 	for cfg in use_cfg.split(','):
    181 		Logs.pprint('NORMAL', "Searching configuration '%s'..." % cfg)
    182 		self.load(cfg, tooldir=tooldir, **kwargs)
    183 	self.start_msg('Checking for configuration')
    184 	self.end_msg(use_cfg)
    185