diff --git a/waflib/extras/batched_cc.py b/waflib/extras/batched_cc.py index 015a89c9..ff146770 100644 --- a/waflib/extras/batched_cc.py +++ b/waflib/extras/batched_cc.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # encoding: utf-8 -# Thomas Nagy, 2006-2010 (ita) +# Thomas Nagy, 2006-2015 (ita) """ Build as batches. @@ -16,32 +16,37 @@ replace each cc/cpp Task by a TaskSlave. A new task called TaskMaster collects t signatures from each slave and finds out the command-line to run. Just import this module in the configuration (no other change required). -This is provided as an example, for performance unity builds are recommended (fewer tasks and fewer jobs to execute). +This is provided as an example, for performance unity builds are recommended (fewer tasks and +fewer jobs to execute). See waflib/extras/unity.py. """ -import os -from waflib import TaskGen, Task, Build, Logs -from waflib.TaskGen import extension, feature, before_method, after_method +from waflib import Task, Utils +from waflib.TaskGen import extension, feature, after_method +from waflib.Tools import c, cxx MAX_BATCH = 50 -c_str = '${CC} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} -c ${SRCLST}' -#c_str = '${CC} ${CCFLAGS} ${CPPFLAGS} ${_CCINCFLAGS} ${_CCDEFFLAGS} -c ${SRCLST}' +c_str = '${CC} ${CFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED}' c_fun, _ = Task.compile_fun_noshell(c_str) -cxx_str = '${CXX} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} -c ${SRCLST}' -#cxx_str = '${CXX} ${CXXFLAGS} ${CPPFLAGS} ${_CXXINCFLAGS} ${_CXXDEFFLAGS} -c ${SRCLST}' +cxx_str = '${CXX} ${CXXFLAGS} ${CPPFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} -c ${SRCLST} ${CXX_TGT_F_BATCHED}' cxx_fun, _ = Task.compile_fun_noshell(cxx_str) count = 70000 class batch_task(Task.Task): - color = 'RED' + color = 'PINK' after = ['c', 'cxx'] before = ['cprogram', 'cshlib', 'cstlib', 'cxxprogram', 'cxxshlib', 'cxxstlib'] + def uid(self): + m = Utils.md5() + m.update(Task.Task.uid(self)) + m.update(str(self.generator.idx).encode()) + return m.digest() + def __str__(self): - return '(batch compilation for %d slaves)\n' % len(self.slaves) + return 'Batch compilation for %d slaves' % len(self.slaves) def __init__(self, *k, **kw): Task.Task.__init__(self, *k, **kw) @@ -70,7 +75,6 @@ class batch_task(Task.Task): return Task.SKIP_ME def run(self): - outputs = [] self.outputs = [] srclst = [] @@ -81,7 +85,7 @@ class batch_task(Task.Task): srclst.append(t.inputs[0].abspath()) self.env.SRCLST = srclst - self.cwd = slaves[0].inputs[0].parent.get_bld().abspath() + self.cwd = slaves[0].outputs[0].parent.abspath() if self.slaves[0].__class__.__name__ == 'c': ret = c_fun(self) @@ -94,11 +98,23 @@ class batch_task(Task.Task): for t in slaves: t.old_post_run() -from waflib.Tools import c, cxx - -def hook(name): +def hook(cls_type): def n_hook(self, node): - task = self.create_task(name, node, node.change_ext('.o')) + + ext = '.obj' if self.env.CC_NAME == 'msvc' else '.o' + name = node.name + k = name.rfind('.') + if k >= 0: + basename = name[:k] + ext + else: + basename = name + ext + + outdir = node.parent.get_bld().make_node('%d' % self.idx) + outdir.mkdir() + out = outdir.find_or_declare(basename) + + task = self.create_task(cls_type, node, out) + try: self.compiled_tasks.append(task) except AttributeError: @@ -108,15 +124,20 @@ def hook(name): self.masters = {} self.allmasters = [] + def fix_path(tsk): + if self.env.CC_NAME == 'msvc': + tsk.env.append_unique('CXX_TGT_F_BATCHED', '/Fo%s' % outdir.abspath()) + if not node.parent in self.masters: m = self.masters[node.parent] = self.master = self.create_task('batch') + fix_path(m) self.allmasters.append(m) else: m = self.masters[node.parent] if len(m.slaves) > MAX_BATCH: m = self.masters[node.parent] = self.master = self.create_task('batch') + fix_path(m) self.allmasters.append(m) - m.add_slave(task) return task return n_hook @@ -131,19 +152,17 @@ def link_after_masters(self): for m in self.allmasters: self.link_task.set_run_after(m) -# Modify the c and cxx task classes - in theory it would be better to +# Modify the c and cxx task classes - in theory it would be best to # create subclasses and to re-map the c/c++ extensions -# for x in ('c', 'cxx'): t = Task.classes[x] def run(self): pass def post_run(self): - #self.executed=1 pass - setattr(t, 'oldrun', t.__dict__['run']) + setattr(t, 'oldrun', getattr(t, 'run', None)) setattr(t, 'run', run) setattr(t, 'old_post_run', t.post_run) setattr(t, 'post_run', post_run) diff --git a/waflib/extras/unity.py b/waflib/extras/unity.py index 5fc5b564..1938dcf1 100644 --- a/waflib/extras/unity.py +++ b/waflib/extras/unity.py @@ -8,12 +8,11 @@ def options(opt): opt.load('compiler_cxx unity') """ -import re -from waflib import Task, Options, Logs +from waflib import Task, Options from waflib.Tools import ccroot, cxx, c_preproc from waflib.TaskGen import extension, taskgen_method -MAX_BATCH = 20 +MAX_BATCH = 50 def options(opt): global MAX_BATCH