# 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, 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["%s.%s" % (self.name, self.idx)]
			self.bld.fatal("Duplicated 'pch' task with name %r" % "%s.%s" % (self.name, self.idx))
		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["%s.%s" % (self.name, self.idx)] = 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} ${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()} ${CPPFLAGS}'
	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
