ebdlib.py (3483B)
1 #! /usr/bin/env python 2 3 import os, sys, imp, time 4 from waflib import Context, Options, Configure, Utils, Logs, TaskGen, Task, Build, ConfigSet 5 import waflib.Tools.c 6 7 """ 8 Create a modified waf file in which tasks use timestamps only 9 see README.txt 10 """ 11 12 # we hard-code a configuration for c but it could be left in the script file too 13 def configure(conf): 14 conf.load('gcc') 15 16 def recurse_rep(x, y): 17 f = getattr(Context.g_module, x.cmd or x.fun, Utils.nada) 18 return f(x) 19 20 def start(cwd, version, wafdir): 21 # this is the entry point of our small build system 22 23 Logs.init_log() 24 Context.waf_dir = wafdir 25 Context.out_dir = Context.top_dir = Context.run_dir = cwd 26 Context.g_module = Context.load_module(cwd + os.sep + 'wscript') 27 Context.g_module.configure = configure 28 Context.g_module.root_path = cwd 29 Context.Context.recurse = recurse_rep 30 31 Context.g_module.top = Context.g_module.out = '.' # no build directory 32 33 # just parse the options and execute a build 34 Options.OptionsContext().execute() 35 36 conf = Context.create_context('configure') 37 conf.options = Options.options 38 conf.execute() 39 40 bld = Context.create_context('build') 41 bld.env = conf.env 42 bld.options = Options.options 43 bld.environ = os.environ 44 bld.execute() 45 46 # change the build context so it does not need to write any file 47 class StatelessBuild(Build.BuildContext): 48 def load_envs(self): 49 self.env = ConfigSet.ConfigSet() 50 def store(self): 51 pass 52 def restore(self): 53 self.init_dirs() 54 def execute_build(self): 55 # we override this method to hide the messages "leaving directory" (just because) 56 self.recurse([self.run_dir]) 57 self.pre_build() 58 59 self.timer = Utils.Timer() 60 61 if Options.options.progress_bar: 62 sys.stderr.write(Logs.colors.cursor_off) 63 try: 64 self.compile() 65 finally: 66 if Options.options.progress_bar: 67 sys.stderr.write(Logs.colors.cursor_on) 68 print('') 69 self.post_build() 70 71 class SilentConf(Configure.ConfigurationContext): 72 # silent configuration 73 def __init__(self, **kw): 74 # disable the configuration messages from Context.start_msg/end_msg 75 self.in_msg = 1 76 super(SilentConf, self).__init__(**kw) 77 78 def execute(self): 79 80 # copy-paste from the original method, but without the cache file creation 81 self.init_dirs() 82 83 path = os.path.join(self.bldnode.abspath(), 'config.log') 84 self.logger = Logs.make_logger(path, 'cfg') 85 86 app = getattr(Context.g_module, 'APPNAME', '') 87 if app: 88 ver = getattr(Context.g_module, 'VERSION', '') 89 if ver: 90 app = "%s (%s)" % (app, ver) 91 92 now = time.ctime() 93 pyver = sys.hexversion 94 systype = sys.platform 95 args = " ".join(sys.argv) 96 wafver = Context.WAFVERSION 97 abi = Context.ABI 98 self.to_log(Configure.conf_template % vars()) 99 100 super(Configure.ConfigurationContext, self).execute() 101 102 103 # change the superclass of existing tasks to force timestamps (the build has no state) 104 def status(self): 105 for t in self.run_after: 106 if not t.hasrun: 107 return Task.ASK_LATER 108 109 implicit_deps = [] 110 try: 111 implicit_deps, _ = self.scan() 112 except: 113 pass 114 115 # we can add one more node, for example: 116 implicit_deps.append(self.generator.path.make_node('wscript')) 117 118 for x in self.inputs + self.dep_nodes + implicit_deps: 119 for y in self.outputs: 120 try: 121 if os.stat(x.abspath()).st_mtime > os.stat(y.abspath()).st_mtime: 122 return Task.RUN_ME 123 except: 124 return Task.RUN_ME 125 126 return Task.SKIP_ME 127 Task.Task.runnable_status = status 128 129 # the post build execution does not need to deal with signatures or anything else 130 Task.Task.post_run = Utils.nada 131