waf/build_system_kit/nostate/ebdlib.py

132 lines
3.4 KiB
Python

#! /usr/bin/env python
import os, sys, imp, time
from waflib import Context, Options, Configure, Utils, Logs, TaskGen, Task, Build, ConfigSet
import waflib.Tools.c
"""
Create a modified waf file in which tasks use timestamps only
see README.txt
"""
# we hard-code a configuration for c but it could be left in the script file too
def configure(conf):
conf.load('gcc')
def recurse_rep(x, y):
f = getattr(Context.g_module, x.cmd or x.fun, Utils.nada)
return f(x)
def start(cwd, version, wafdir):
# this is the entry point of our small build system
Logs.init_log()
Context.waf_dir = wafdir
Context.out_dir = Context.top_dir = Context.run_dir = cwd
Context.g_module = Context.load_module(cwd + os.sep + 'wscript')
Context.g_module.configure = configure
Context.g_module.root_path = cwd
Context.Context.recurse = recurse_rep
Context.g_module.top = Context.g_module.out = '.' # no build directory
# just parse the options and execute a build
Options.OptionsContext().execute()
conf = Context.create_context('configure')
conf.options = Options.options
conf.execute()
bld = Context.create_context('build')
bld.env = conf.env
bld.options = Options.options
bld.environ = os.environ
bld.execute()
# change the build context so it does not need to write any file
class StatelessBuild(Build.BuildContext):
def load_envs(self):
self.env = ConfigSet.ConfigSet()
def store(self):
pass
def restore(self):
self.init_dirs()
def execute_build(self):
# we override this method to hide the messages "leaving directory" (just because)
self.recurse([self.run_dir])
self.pre_build()
self.timer = Utils.Timer()
if Options.options.progress_bar:
sys.stderr.write(Logs.colors.cursor_off)
try:
self.compile()
finally:
if Options.options.progress_bar:
sys.stderr.write(Logs.colors.cursor_on)
print('')
self.post_build()
class SilentConf(Configure.ConfigurationContext):
# silent configuration
def __init__(self, **kw):
# disable the configuration messages from Context.start_msg/end_msg
self.in_msg = 1
super(SilentConf, self).__init__(**kw)
def execute(self):
# copy-paste from the original method, but without the cache file creation
self.init_dirs()
path = os.path.join(self.bldnode.abspath(), 'config.log')
self.logger = Logs.make_logger(path, 'cfg')
app = getattr(Context.g_module, 'APPNAME', '')
if app:
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(Configure.conf_template % vars())
super(Configure.ConfigurationContext, self).execute()
# change the superclass of existing tasks to force timestamps (the build has no state)
def status(self):
for t in self.run_after:
if not t.hasrun:
return Task.ASK_LATER
implicit_deps = []
try:
implicit_deps, _ = self.scan()
except:
pass
# we can add one more node, for example:
implicit_deps.append(self.generator.path.make_node('wscript'))
for x in self.inputs + self.dep_nodes + implicit_deps:
for y in self.outputs:
try:
if os.stat(x.abspath()).st_mtime > os.stat(y.abspath()).st_mtime:
return Task.RUN_ME
except:
return Task.RUN_ME
return Task.SKIP_ME
Task.Task.runnable_status = status
# the post build execution does not need to deal with signatures or anything else
Task.Task.post_run = Utils.nada