#! /usr/bin/env python # encoding: utf-8 """ Compile whole groups of C/C++ files at once. def build(bld): bld.load('compiler_cxx unity') """ import sys from waflib import Task, Options from waflib.Tools import c_preproc from waflib import TaskGen MAX_BATCH = 50 def options(opt): global MAX_BATCH opt.add_option('--batchsize', action='store', dest='batchsize', type='int', default=MAX_BATCH, help='batch size (0 for no batch)') class unity(Task.Task): color = 'BLUE' scan = c_preproc.scan def to_include(self, node): ret = node.path_from(self.outputs[0].parent) ret = ret.replace('\\', '\\\\').replace('"', '\\"') return ret def run(self): lst = ['#include "%s"\n' % self.to_include(node) for node in self.inputs] txt = ''.join(lst) self.outputs[0].write(txt) @TaskGen.taskgen_method def batch_size(self): return getattr(Options.options, 'batchsize', MAX_BATCH) def make_batch_fun(ext): # this generic code makes this quite unreadable, defining the function two times might have been better def make_batch(self, node): cnt = self.batch_size() if cnt <= 1: return self.create_compiled_task(ext, node) x = getattr(self, 'master_%s' % ext, None) if not x or len(x.inputs) >= cnt: x = self.create_task('unity') setattr(self, 'master_%s' % ext, x) cnt_cur = getattr(self, 'cnt_%s' % ext, 0) cxxnode = node.parent.find_or_declare('unity_%s_%d_%d.%s' % (self.idx, cnt_cur, cnt, ext)) x.outputs = [cxxnode] setattr(self, 'cnt_%s' % ext, cnt_cur + 1) self.create_compiled_task(ext, cxxnode) x.inputs.append(node) return make_batch def enable_support(cc, cxx): if cxx or not cc: TaskGen.extension('.cpp', '.cc', '.cxx', '.C', '.c++')(make_batch_fun('cxx')) if cc: TaskGen.extension('.c')(make_batch_fun('c')) else: TaskGen.task_gen.mappings['.c'] = TaskGen.task_gen.mappings['.cpp'] has_c = '.c' in TaskGen.task_gen.mappings or 'waflib.Tools.compiler_c' in sys.modules has_cpp = '.cpp' in TaskGen.task_gen.mappings or 'waflib.Tools.compiler_cxx' in sys.modules enable_support(has_c, has_cpp) # by default def build(bld): # it is best to do this enable_support(bld.env.CC_NAME, bld.env.CXX_NAME)