Alexander Afanasyev | 8552a38 | 2014-05-15 20:13:42 -0700 | [diff] [blame] | 1 | #! /usr/bin/env python |
| 2 | # encoding: utf-8 |
| 3 | |
| 4 | from waflib import Logs, Utils, Task, TaskGen, Build |
| 5 | from waflib.Tools import c_preproc, cxx |
| 6 | |
| 7 | def 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 | |
| 12 | def configure(conf): |
| 13 | conf.env['WITH_PCH'] = conf.options.with_pch |
| 14 | |
| 15 | class 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 | |
| 23 | PCH_COMPILER_OPTIONS = { |
| 24 | 'clang++': ['-include', '.pch', ''], |
| 25 | 'g++': ['-include', '.gch', ''], |
| 26 | } |
| 27 | |
| 28 | @TaskGen.extension('.cpp') |
| 29 | def 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 | |
| 66 | class 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) |