Last active
October 11, 2017 15:38
-
-
Save rpuntaie/2bddfb5d7b77db26415ee14371289971 to your computer and use it in GitHub Desktop.
variants for the waf-project build tool
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# encoding: utf-8 | |
# Roland Puntaier, 2017 | |
"""If there is a *variants* variable in the main wscript | |
- x_variant commandline arguments are created | |
for x in {configure, build, clean, install, uninstall} | |
- an x command line argument is expanded to all x_variant's | |
- the associated x function context contains :py:const:`variant` | |
Variant strings can use the `/` path separator to produce an according output tree. | |
####################### begin example wscript ################################## | |
from itertools import product as prod | |
from string import Template | |
import time | |
import os | |
import waf_variants | |
variants = ['/'.join(v) for v in prod('Tim Jan'.split(),'X Y'.split())] | |
def touch(x,txt=''): | |
with open(x,'w') as f: | |
f.write(txt) | |
def filltime(tsk): | |
ifn = tsk.inputs[0].abspath() | |
ofn = tsk.outputs[0].abspath() | |
with open(ifn,'r') as f: | |
s = f.read() | |
with open(ofn,'w') as f: | |
f.write(time.strftime(Template(s).substitute(tsk.env),time.localtime())) | |
asrc = 'tst.txt.tm' | |
atgt = os.path.splitext(asrc)[0] | |
def init(ini): | |
touch(asrc,'$name, it is %$timeformat.')#Template,then strftime | |
def configure(cfg): | |
v = cfg.variant | |
cfg.env.name,cfg.env.timeformat = v.split('/') | |
if 'Tim' in v: | |
cfg.env.name = 'Timi' | |
def build(bld): | |
v=bld.variant | |
bld(rule=lambda t:filltime(t),source=asrc,target=atgt) | |
def clean(cln): | |
pass | |
####################### end example wscript ################################## | |
waf configure | |
waf build | |
waf build_Y | |
waf build_Jan/Y | |
waf clean_X | |
waf clean_Tim | |
waf clean_Tim/X | |
... | |
""" | |
from waflib.Build import BuildContext, CleanContext, InstallContext, UninstallContext | |
from waflib.Configure import ConfigurationContext | |
from waflib import Context | |
from waflib import Options | |
class VariantContext(Context.Context): | |
"wscript global variants implicitly expanded to configure_x, build_x,..." | |
cmd = 'init' | |
fun = 'init' | |
def execute(self): | |
try: | |
Context.Context.execute(self) | |
vs = list(Context.g_module.variants) | |
cls = [cl for cl in Context.classes if issubclass(cl,BuildContext)] | |
for y in [ConfigurationContext]+cls: | |
c = y.__name__.replace('Context','').replace('ation','e').lower() | |
cvs = [] | |
for v in vs: | |
cv = self.add_variant(y,c,v) | |
cvs.append(cv) | |
cmds = [] | |
for k in Options.commands: | |
if k.startswith(c): | |
kk = k[len(c):].strip('_') | |
cmds.extend([acv for acv in cvs if kk in acv]) | |
else: | |
cmds.append(k) | |
Options.commands[:] = cmds | |
except AttributeError: | |
pass | |
def add_variant(self,y,c,v): | |
cv = c + '_' + v | |
class _variant_context(y): | |
cmd = cv | |
fun = c | |
variant = v | |
def __init__(s, **kw): | |
y.__init__(s, **kw) | |
if c[-1]=='e':#configure | |
s.setenv(v) | |
return cv |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
waf build_X will build Tim/X and Jan/X in the example