blob: c0e3039e2675efd38a1a42fb4c7f1dfdefc03406 [file] [log] [blame]
Alexander Afanasyev8552a382014-05-15 20:13:42 -07001#! /usr/bin/env python
2# encoding: utf-8
3
4from waflib import Logs, Utils, Task, TaskGen, Build
5from waflib.Tools import c_preproc, cxx
6
7def options(opt):
8 opt.add_option('--with-pch', action='store_true', default=False, dest='with_pch',
9 help='''Try to use precompiled header to speed up compilation '''
10 '''(only gcc and clang)''')
11
12def configure(conf):
13 conf.env['WITH_PCH'] = conf.options.with_pch
14
15class gchx(Task.Task):
16 run_str = '${CXX} -x c++-header ${CXXFLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ' + \
17 '${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ' + \
18 '${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT}'
19 scan = c_preproc.scan
20 color = 'BLUE'
21
22
23PCH_COMPILER_OPTIONS = {
24 'clang++': ['-include', '.pch', ''],
25 'g++': ['-include', '.gch', ''],
26}
27
28@TaskGen.extension('.cpp')
29def cxx_hook(self, node):
30 if (self.env.WITH_PCH and
31 self.env['COMPILER_CXX'] in PCH_COMPILER_OPTIONS.keys() and
32 getattr(self, 'pch', None)):
33
34 (flag, pch_ext, include_ext) = PCH_COMPILER_OPTIONS[self.env['COMPILER_CXX']]
35
36 if not getattr(self, 'pch_task', None):
37 if isinstance(self.pch, str):
38 self.pch = self.path.find_node(self.pch)
39
40 output = self.pch.change_ext('.hpp%s' % pch_ext)
41
42 try:
43 # == Will reuse the existing task ==
44 # This could cause problem if different compiler flags were used for
45 # previous compilation of the precompiled header
46 existingTask = self.bld.get_tgen_by_name(output.abspath())
47 self.pch_task = existingTask
48 except:
49 self.pch_task = self.create_task('gchx', self.pch, output)
50 self.pch_task.name = output.abspath()
51
52 self.bld.task_gen_cache_names = {}
53 self.bld.add_to_group(self.pch_task, group=getattr(self, 'group', None))
54
55 task = self.create_compiled_task('cxx_pch', node)
56 # task.run_after.update(set([self.pch_task]))
57
58 task.pch_flag = flag
59 task.pch_include_file = self.pch.change_ext('.hpp%s' % include_ext).get_bld()
60
61 out = '%s%s' % (self.pch.name, pch_ext)
62 task.pch_file = self.pch.parent.get_bld().find_or_declare(out)
63 else:
64 self.create_compiled_task('cxx', node)
65
66class cxx_pch(Task.classes['cxx']):
67 run_str = '${CXX} ${tsk.pch_flag} ${tsk.pch_include_file.abspath()} '\
68 '${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ' \
69 '${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ' \
70 '${CXX_SRC_F}${SRC} ${CXX_TGT_F}${TGT[0].abspath()}'
71
72 def scan(self):
73 (nodes, names) = c_preproc.scan(self)
74 nodes.append(self.pch_file)
75 return (nodes, names)