From a933244f48302ffd8d83a68c5a1a8f28baa820bf Mon Sep 17 00:00:00 2001 From: Thomas Nagy Date: Mon, 23 Feb 2015 10:44:57 +0100 Subject: [PATCH] Enable unity builds for C too --- waflib/Scripting.py | 2 +- waflib/extras/unity.py | 121 +++++++++++++++++++++++------------------ 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/waflib/Scripting.py b/waflib/Scripting.py index e48f1ff8..7cb5910f 100644 --- a/waflib/Scripting.py +++ b/waflib/Scripting.py @@ -144,7 +144,7 @@ def waf_entry_point(current_directory, version, wafdir): import cProfile, pstats cProfile.runctx("from waflib import Scripting; Scripting.run_commands()", {}, {}, 'profi.txt') p = pstats.Stats('profi.txt') - p.sort_stats('time').print_stats(25) # or 'cumulative' + p.sort_stats('time').print_stats(75) # or 'cumulative' """ try: run_commands() diff --git a/waflib/extras/unity.py b/waflib/extras/unity.py index 1938dcf1..d21e3519 100644 --- a/waflib/extras/unity.py +++ b/waflib/extras/unity.py @@ -1,53 +1,68 @@ -#! /usr/bin/env python -# encoding: utf-8 - -""" -Take a group of C++ files and compile them at once. - -def options(opt): - opt.load('compiler_cxx unity') -""" - -from waflib import Task, Options -from waflib.Tools import ccroot, cxx, c_preproc -from waflib.TaskGen import extension, taskgen_method - -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 run(self): - lst = ['#include "%s"\n' % node.abspath() for node in self.inputs] - txt = ''.join(lst) - self.outputs[0].write(txt) - -@taskgen_method -def batch_size(self): - return Options.options.batchsize - -@extension('.cpp', '.cc', '.cxx', '.C', '.c++') -def make_cxx_batch(self, node): - cnt = self.batch_size() - if cnt <= 1: - tsk = self.create_compiled_task('cxx', node) - return tsk - - try: - self.cnt_cxx - except AttributeError: - self.cnt_cxx = 0 - - x = getattr(self, 'master_cxx', None) - if not x or len(x.inputs) >= cnt: - x = self.master_cxx = self.create_task('unity') - cxxnode = node.parent.find_or_declare('union_%s_%d_%d.cxx' % (self.idx, self.cnt_cxx, cnt)) - self.master_cxx.outputs = [cxxnode] - self.cnt_cxx += 1 - self.create_compiled_task('cxx', cxxnode) - x.inputs.append(node) - +#! /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 run(self): + lst = ['#include "%s"\n' % node.abspath() 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: + make_cxx_batch = TaskGen.extension('.cpp', '.cc', '.cxx', '.C', '.c++')(make_batch_fun('cxx')) + if cc: + make_c_batch = 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) +