1# based on playground/evil in the waf svn tree 2 3import os, datetime, fnmatch 4from waflib import Scripting, Utils, Options, Logs, Errors 5from waflib import ConfigSet, Context 6from samba_utils import LOCAL_CACHE, os_path_relpath 7 8def run_task(t, k): 9 '''run a single build task''' 10 ret = t.run() 11 if ret: 12 raise Errors.WafError("Failed to build %s: %u" % (k, ret)) 13 14 15def run_named_build_task(cmd): 16 '''run a named build task, matching the cmd name using fnmatch 17 wildcards against inputs and outputs of all build tasks''' 18 bld = fake_build_environment(info=False) 19 found = False 20 cwd_node = bld.root.find_dir(os.getcwd()) 21 top_node = bld.root.find_dir(bld.srcnode.abspath()) 22 23 cmd = os.path.normpath(cmd) 24 25 # cope with builds of bin/*/* 26 if os.path.islink(cmd): 27 cmd = os_path_relpath(os.readlink(cmd), os.getcwd()) 28 29 if cmd[0:12] == "bin/default/": 30 cmd = cmd[12:] 31 32 for g in bld.task_manager.groups: 33 for attr in ['outputs', 'inputs']: 34 for t in g.tasks: 35 s = getattr(t, attr, []) 36 for k in s: 37 relpath1 = k.relpath_gen(cwd_node) 38 relpath2 = k.relpath_gen(top_node) 39 if (fnmatch.fnmatch(relpath1, cmd) or 40 fnmatch.fnmatch(relpath2, cmd)): 41 t.position = [0,0] 42 print(t.display()) 43 run_task(t, k) 44 found = True 45 46 47 if not found: 48 raise Errors.WafError("Unable to find build target matching %s" % cmd) 49 50 51def rewrite_compile_targets(): 52 '''cope with the bin/ form of compile target''' 53 if not Options.options.compile_targets: 54 return 55 56 bld = fake_build_environment(info=False) 57 targets = LOCAL_CACHE(bld, 'TARGET_TYPE') 58 tlist = [] 59 60 for t in Options.options.compile_targets.split(','): 61 if not os.path.islink(t): 62 tlist.append(t) 63 continue 64 link = os.readlink(t) 65 list = link.split('/') 66 for name in [list[-1], '/'.join(list[-2:])]: 67 if name in targets: 68 tlist.append(name) 69 continue 70 Options.options.compile_targets = ",".join(tlist) 71 72 73 74def wildcard_main(missing_cmd_fn): 75 '''this replaces main from Scripting, allowing us to override the 76 behaviour for unknown commands 77 78 If a unknown command is found, then missing_cmd_fn() is called with 79 the name of the requested command 80 ''' 81 Scripting.commands = Options.arg_line[:] 82 83 # rewrite the compile targets to cope with the bin/xx form 84 rewrite_compile_targets() 85 86 while Scripting.commands: 87 x = Scripting.commands.pop(0) 88 89 ini = datetime.datetime.now() 90 if x == 'configure': 91 fun = Scripting.configure 92 elif x == 'build': 93 fun = Scripting.build 94 else: 95 fun = getattr(Utils.g_module, x, None) 96 97 # this is the new addition on top of main from Scripting.py 98 if not fun: 99 missing_cmd_fn(x) 100 break 101 102 ctx = getattr(Utils.g_module, x + '_context', Utils.Context)() 103 104 if x in ['init', 'shutdown', 'dist', 'distclean', 'distcheck']: 105 try: 106 fun(ctx) 107 except TypeError: 108 fun() 109 else: 110 fun(ctx) 111 112 ela = '' 113 if not Options.options.progress_bar: 114 ela = ' (%s)' % Utils.get_elapsed_time(ini) 115 116 if x != 'init' and x != 'shutdown': 117 Logs.info('%r finished successfully%s' % (x, ela)) 118 119 if not Scripting.commands and x != 'shutdown': 120 Scripting.commands.append('shutdown') 121 122 123 124 125def fake_build_environment(info=True, flush=False): 126 """create all the tasks for the project, but do not run the build 127 return the build context in use""" 128 bld = getattr(Context.g_module, 'build_context', Utils.Context)() 129 bld = Scripting.check_configured(bld) 130 131 Options.commands['install'] = False 132 Options.commands['uninstall'] = False 133 134 bld.is_install = 0 # False 135 136 try: 137 proj = ConfigSet.ConfigSet(Options.lockfile) 138 except IOError: 139 raise Errors.WafError("Project not configured (run 'waf configure' first)") 140 141 bld.load_envs() 142 143 if info: 144 Logs.info("Waf: Entering directory `%s'" % bld.bldnode.abspath()) 145 bld.add_subdirs([os.path.split(Context.g_module.root_path)[0]]) 146 147 bld.pre_build() 148 if flush: 149 bld.flush() 150 return bld 151 152