Enable Visual Studio support in batched_cc for Issue 1537 (the unity tool provides best performance though)

This commit is contained in:
Thomas Nagy 2015-02-22 13:30:25 +01:00
parent 49911f72a8
commit 17ab93f32a
No known key found for this signature in database
GPG Key ID: 67A565EDFDF90E64
2 changed files with 43 additions and 25 deletions

View File

@ -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)

View File

@ -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