mirror of https://gitlab.com/ita1024/waf
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.1 KiB
Python
145 lines
4.1 KiB
Python
#! /usr/bin/env python
|
|
# encoding: utf-8
|
|
# Thomas Nagy, 2010 (ita)
|
|
|
|
VERSION='0.0.1'
|
|
APPNAME='cpp_gen'
|
|
|
|
top = '.'
|
|
out = 'build'
|
|
|
|
def options(opt):
|
|
opt.load('compiler_cxx')
|
|
|
|
def configure(conf):
|
|
conf.load('compiler_cxx')
|
|
conf.check(header_name='stdio.h', features='cxx cxxprogram', mandatory=False)
|
|
|
|
def build(bld):
|
|
bld.program(source='main.cpp a.cpp', target='app')
|
|
|
|
#--------
|
|
|
|
import os
|
|
from waflib import Task, TaskGen, Utils
|
|
from waflib.Tools import cxx
|
|
|
|
@TaskGen.extension('.cpp')
|
|
def more_tasks_at_once(self, node):
|
|
task1 = self.create_task('prog1', node, [])
|
|
task2 = self.create_compiled_task('cxx', node)
|
|
|
|
def cmpnodes(a, b):
|
|
return cmp(a.abspath(), b.abspath())
|
|
|
|
class prog1(Task.Task):
|
|
before = ['cxxprogram', 'cxxshlib', 'cxxstlib']
|
|
|
|
def uid(self):
|
|
"""
|
|
the unique id of this task should only depend on the file inputs
|
|
"""
|
|
m = Utils.md5()
|
|
up = m.update
|
|
up(self.__class__.__name__.encode())
|
|
for x in self.inputs:
|
|
up(x.abspath().encode())
|
|
return m.digest()
|
|
|
|
def runnable_status(self):
|
|
"""
|
|
since it is called after the build has started,
|
|
any task added must be passed through 'more_tasks'
|
|
"""
|
|
for x in self.run_after:
|
|
if not x.hasrun:
|
|
return Task.ASK_LATER
|
|
|
|
# so this is a bit special, the goal here is to set the output nodes
|
|
# and to create the c++ tasks before the normal processing is done
|
|
sig = self.signature()
|
|
for x in self.generator.bld.raw_deps.get(sig, []):
|
|
self.outputs.append(self.generator.bld.srcnode.find_node(x))
|
|
|
|
if not self.outputs:
|
|
self.read_outputs_from_cache()
|
|
|
|
if self.outputs:
|
|
self.create_cxx_task()
|
|
|
|
ret = Task.Task.runnable_status(self)
|
|
return ret
|
|
|
|
def create_cxx_task(self):
|
|
"""
|
|
create a task dynamically during the build
|
|
notice the use of 'more_tasks'
|
|
"""
|
|
tsk = cxx.cxx_hook(self.generator, self.outputs[0])
|
|
tsk.set_run_after(self) # the build has started, so the order must be set manually
|
|
self.more_tasks = [tsk] # add tasks dynamically during the build
|
|
self.generator.link_task.inputs.append(tsk.outputs[0]) # add another input for the link task
|
|
try:
|
|
self.generator.link_task.inputs.sort(cmp=cmpnodes) # eliminate the random order (more tasks like this)
|
|
except:
|
|
self.generator.link_task.inputs.sort(key=lambda x: x.abspath()) # python3
|
|
self.generator.link_task.set_run_after(tsk) # do not forget to set the build order there too
|
|
|
|
def run(self):
|
|
"""
|
|
actual execution
|
|
this code should not be executed if the files are retrieved from the cache
|
|
"""
|
|
if self.inputs[0].name == 'a.cpp':
|
|
# simulate the creation of an interface file
|
|
out = self.inputs[0].parent.get_bld().make_node('a.ser.cpp')
|
|
out.write('\n\n')
|
|
|
|
# read the file system
|
|
# remember that nodes cannot be created concurrently
|
|
# so you might to crate a lock if several tasks want the same nodes
|
|
inp = self.inputs[0]
|
|
node = inp.parent.get_bld().find_node(inp.name.replace('.cpp', '.ser.cpp'))
|
|
if node:
|
|
self.outputs = [node]
|
|
h_node = inp.parent.find_node(inp.name.replace('.cpp', '.ser.h'))
|
|
if h_node:
|
|
self.outputs.append(h_node)
|
|
|
|
# if there are outputs, create a new c++ task
|
|
if self.outputs:
|
|
self.create_cxx_task()
|
|
|
|
# access the scanner data
|
|
self.generator.bld.raw_deps[self.signature()] = [x.path_from(self.generator.bld.srcnode) for x in self.outputs]
|
|
|
|
def read_outputs_from_cache(self):
|
|
"""
|
|
set the outputs from the results found in the cache
|
|
we assume that the files are created in the same folder as the inputs
|
|
if it is not like this, the nodes should be restored by another system, for example
|
|
by storing them in a separate file during run()
|
|
"""
|
|
env = self.env
|
|
sig = self.signature()
|
|
ssig = Utils.to_hex(sig)
|
|
|
|
# first try to access the cache folder for the task
|
|
dname = os.path.join(self.generator.bld.cache_global, ssig)
|
|
try:
|
|
t1 = os.stat(dname).st_mtime
|
|
except OSError:
|
|
return None
|
|
|
|
try:
|
|
lst = os.listdir(dname)
|
|
except:
|
|
return
|
|
|
|
for x in lst:
|
|
self.outputs.append(self.inputs[0].parent.find_or_declare(x))
|
|
|
|
# not a fresh build and the cache is removed -> remember the files in the scanner data
|
|
self.generator.bld.raw_deps[self.signature()] = [x.path_from(self.generator.bld.srcnode) for x in self.outputs]
|
|
|