#! /usr/bin/env python
# encoding: utf-8
# Alexander Afanasyev (UCLA), 2014

"""
Enable precompiled C++ header support (currently only clang++ and g++ are supported)

To use this tool, wscript should look like:

	def options(opt):
		opt.load('pch')
		# This will add `--with-pch` configure option.
		# Unless --with-pch during configure stage specified, the precompiled header support is disabled

	def configure(conf):
		conf.load('pch')
		# this will set conf.env.WITH_PCH if --with-pch is specified and the supported compiler is used
		# Unless conf.env.WITH_PCH is set, the precompiled header support is disabled

	def build(bld):
		bld(features='cxx pch',
			target='precompiled-headers',
			name='precompiled-headers',
			headers='a.h b.h c.h', # headers to pre-compile into `precompiled-headers`

			# Other parameters to compile precompiled headers
			# includes=...,
			# export_includes=...,
			# use=...,
			# ...

			# Exported parameters will be propagated even if precompiled headers are disabled
		)

		bld(
			target='test',
			features='cxx cxxprogram',
			source='a.cpp b.cpp d.cpp main.cpp',
			use='precompiled-headers',
		)

		# or

		bld(
			target='test',
			features='pch cxx cxxprogram',
			source='a.cpp b.cpp d.cpp main.cpp',
			headers='a.h b.h c.h',
		)

Note that precompiled header must have multiple inclusion guards.  If the guards are missing, any benefit of precompiled header will be voided and compilation may fail in some cases.
"""

import os
from waflib import Task, TaskGen, Logs, Utils
from waflib.Tools import c_preproc, cxx


PCH_COMPILER_OPTIONS = {
	'clang++': [['-include'], '.pch', ['-x', 'c++-header']],
	'g++':     [['-include'], '.gch', ['-x', 'c++-header']],
}


def options(opt):
	opt.add_option('--without-pch', action='store_false', default=True, dest='with_pch', help='''Try to use precompiled header to speed up compilation (only g++ and clang++)''')

def configure(conf):
	if (conf.options.with_pch and conf.env['COMPILER_CXX'] in PCH_COMPILER_OPTIONS.keys()):
		conf.env.WITH_PCH = True
		flags = PCH_COMPILER_OPTIONS[conf.env['COMPILER_CXX']]
		conf.env.CXXPCH_F = flags[0]
		conf.env.CXXPCH_EXT = flags[1]
		conf.env.CXXPCH_FLAGS = flags[2]


@TaskGen.feature('pch')
@TaskGen.before('process_source')
def apply_pch(self):
	if not self.env.WITH_PCH:
		return

	if getattr(self.bld, 'pch_tasks', None) is None:
		self.bld.pch_tasks = {}

        if getattr(self, 'headers', None) is None:
		return

	self.headers = self.to_nodes(self.headers)

	if getattr(self, 'name', None):
		try:
			task = self.bld.pch_tasks[self.name]
			self.bld.fatal("Duplicated 'pch' task with name %r" % self.name)
		except KeyError:
			pass

	out = '%s.%d%s' % (self.target, self.idx, self.env['CXXPCH_EXT'])
	out = self.path.find_or_declare(out)
	task = self.create_task('gchx', self.headers, out)

	# target should be an absolute path of `out`, but without precompiled header extension
	task.target = out.abspath()[:-len(out.suffix())]

        self.pch_task = task
	if getattr(self, 'name', None):
		self.bld.pch_tasks[self.name] = task

@TaskGen.feature('cxx')
@TaskGen.after_method('process_source', 'propagate_uselib_vars')
def add_pch(self):
	if not (self.env['WITH_PCH'] and getattr(self, 'use', None) and getattr(self, 'compiled_tasks', None) and getattr(self.bld, 'pch_tasks', None)):
		return

	pch = None
	# find pch task, if any

	if getattr(self, 'pch_task', None):
		pch = self.pch_task
	else:
		for use in Utils.to_list(self.use):
			try:
				pch = self.bld.pch_tasks[use]
			except KeyError:
				pass

	if pch:
		for x in self.compiled_tasks:
			x.env.append_value('CXXFLAGS', self.env['CXXPCH_F'] + [pch.target])

class gchx(Task.Task):
	run_str = '${CXX} ${ARCH_ST:ARCH} ${CXXFLAGS} ${CPPFLAGS} ${CXXPCH_FLAGS} ${FRAMEWORKPATH_ST:FRAMEWORKPATH} ${CPPPATH_ST:INCPATHS} ${DEFINES_ST:DEFINES} ${CXXPCH_F:SRC} ${CXX_SRC_F}${SRC[0].abspath()} ${CXX_TGT_F}${TGT[0].abspath()}'
	scan    = c_preproc.scan
	color   = 'BLUE'
	ext_out=['.h']

	def runnable_status(self):
		try:
			node_deps = self.generator.bld.node_deps[self.uid()]
		except KeyError:
			node_deps = []
		ret = Task.Task.runnable_status(self)
		if ret == Task.SKIP_ME and self.env.CXX_NAME == 'clang':
			t = os.stat(self.outputs[0].abspath()).st_mtime
			for n in self.inputs + node_deps:
				if os.stat(n.abspath()).st_mtime > t:
					return Task.RUN_ME
		return ret
