#! /usr/bin/env python
# more or less derived from scons qt.py
# this version makes less scans over the data and is thus faster
# it is less accurate however (when mocable classes become unmocable)
# Thomas Nagy, 2004, 2005 <tnagy2^8@yahoo.fr>

from time import *
import SCons.Util
import string

import os, re

BOLD   ="\033[1m"
RED    ="\033[91m"
GREEN  ="\033[92m"
YELLOW ="\033[1m" #"\033[93m" # unreadable on white backgrounds
CYAN   ="\033[96m"
NORMAL ="\033[0m"

# Returns the name of the shared object (i.e. libkdeui.so.4)
# referenced by a libtool archive (like libkdeui.la)
def getSOfromLA(lafile):
        contents = open(lafile, 'r').read()
        match = re.search("^dlname='([^']*)'$", contents, re.M)
        if match:
                return match.group(1)
        return None

def exists(env):
	return True

def detect_kde(env):
	""" Detect the qt and kde environment using kde-config mostly """

	prefix     = env['ARGS'].get('prefix', None)
	execprefix = env['ARGS'].get('execprefix', None)
	datadir    = env['ARGS'].get('datadir', None)
	libdir     = env['ARGS'].get('libdir', None)
	kdeincludes= env['ARGS'].get('kdeincludes', None)
	kdelibs    = env['ARGS'].get('kdelibs', None)
	qtincludes = env['ARGS'].get('qtincludes', None)
	tqtincludes= env['ARGS'].get('tqtincludes', None)
	qtlibs     = env['ARGS'].get('qtlibs', None)
	kdedir     = env['ARGS'].get('kdedir', None)

	## Detect the kde libraries
	print "Checking for kde-config           : ",
	str="which kde-config 2>/dev/null"
	if kdedir: str="which %s 2>/dev/null" % (kdedir+'/bin/kde-config')
	kde_config = os.popen(str).read().strip()
	if len(kde_config):
		print GREEN + 'kde-config was found as ' + kde_config + NORMAL
	else:
		if kdedir: print RED + 'kde-config was NOT found in the folder given ' + kdedir + NORMAL
		else: print RED + 'kde-config was NOT found in your PATH' + NORMAL
		print "Make sure kde is installed properly"
		print "(missing package kdebase-devel?)"
		env.Exit(1)
	if kdedir: env['KDEDIR']=kdedir
	else: env['KDEDIR'] = os.popen(kde_config+' -prefix').read().strip()

	print "Checking for kde version          : ",
	kde_version = os.popen(kde_config+" --version|grep KDE").read().strip().split()[1]
	kde_major = kde_version.split('.')[0].lstrip('R')
	kde_minor = kde_version.split('.')[1]
	kde_patch = kde_version.split('.')[2]
	try:
		env['KDEm1']=int(kde_major)
	except:
		pass
	try:
		env['KDEm2']=int(kde_minor)
	except:
		pass
	try:
		env['KDEm3']=int(kde_patch)
	except:
		pass
	if int(kde_major) != 3 or int(kde_minor) < 2:
		print RED + kde_version
		print RED + "Your kde version might be too old" + NORMAL
		print RED + "Please make sure TDE is at least 3.2" + NORMAL
	else:
		print GREEN + kde_version + NORMAL

	## Detect the qt library
	print "Checking for the qt library       : ",
	qtdir = os.getenv("QTDIR")
	if qtdir:
		print GREEN + "qt is in " + qtdir + NORMAL
	else:
		libdir = os.popen(kde_config + ' --expandvars --install lib').read().strip()
		libkdeuiSO = libdir+'/'+getSOfromLA(libdir+'/libkdeui.la')
		try:
			m = re.search('(.*)/lib/libqt.*', os.popen('ldd '+libkdeuiSO+' | grep libqt').read().strip().split()[2])
		except:
			m = re.search('(.*)/lib/libtqt.*', os.popen('ldd ' + libkdeuiSO + ' | grep libtqt').read().strip().split()[2])
			pass
		if m:
			qtdir = m.group(1)
			print YELLOW+"qt was found as " + m.group(1) + NORMAL
		else:
			print RED+"qt was not found"+NORMAL
			print RED+"Please set QTDIR first (/usr/lib/qt3?)"+NORMAL
			env.Exit(1)
	env['QTDIR'] = qtdir.strip()

	## Find the necessary programs uic-tqt and moc
	print "Checking for uic-tqt              : ",
	uic = qtdir + "/bin/uic-tqt"
	if os.path.isfile(uic):
		print GREEN+"uic-tqt was found as "+uic+NORMAL
	else:
		uic = os.popen("which uic-tqt 2>/dev/null").read().strip()
		if len(uic):
			print YELLOW+"uic-tqt was found as "+uic+NORMAL
		else:
			uic = os.popen("which uic-tqt 2>/dev/null").read().strip()
			if len(uic):
				print YELLOW+"uic-tqt was found as "+uic+NORMAL
			else:
				print RED+"uic-tqt was not found - set QTDIR put it in your PATH ?"+NORMAL
				env.Exit(1)
	env['QT_UIC'] = uic

	print "Checking for moc                  : ",
	moc = qtdir + "/bin/moc"
	if os.path.isfile(moc):
		print GREEN+"moc was found as "+moc+NORMAL
	else:
		moc = os.popen("which moc 2>/dev/null").read().strip()
		if len(moc):
			print YELLOW+"moc was found as "+moc+NORMAL
		elif os.path.isfile("/usr/share/qt3/bin/moc"):
			moc = "/usr/share/qt3/bin/moc"
			print YELLOW+"moc was found as "+moc+NORMAL
		else:
			print RED+"moc was not found - set QTDIR or put it in your PATH ?"+NORMAL
			env.Exit(1)
	env['QT_MOC'] = moc

	## check for the tqt includes
	print "Checking for the tqt includes     : ",
	if tqtincludes and os.path.isfile(tqtincludes + "/tqlayout.h"):
		# The user told where to look for and it looks valid
		print GREEN + "ok " + tqtincludes + NORMAL
	else:
		if os.path.isfile(qtdir + "/include/tqlayout.h"):
			# Automatic detection
			print GREEN + "ok " + qtdir + "/include/ " + NORMAL
			tqtincludes = qtdir + "/include/"
		elif os.path.isfile("/usr/include/tqt/tqlayout.h"):
			# Debian probably
			print YELLOW + "the qt headers were found in /usr/include/tqt/ " + NORMAL
			tqtincludes = "/usr/include/tqt"
		elif os.path.isfile("/usr/include/qt4/Qt/qglobal.h"):
			# Debian probably
			print YELLOW + "the qt headers were found in /usr/include/qt4/ " + NORMAL
			tqtincludes = "/usr/include/qt4"
		else:
			print RED + "the qt headers were not found" + NORMAL
			env.Exit(1)
			
	## check for the qt includes
	print "Checking for the qt includes      : ",
	if qtincludes and os.path.isfile(qtincludes + "/qglobal.h"):
		# The user told where to look for and it looks valid
		print GREEN + "ok " + qtincludes + NORMAL
	else:
		if os.path.isfile(qtdir + "/include/qglobal.h"):
			# Automatic detection
			print GREEN + "ok " + qtdir + "/include/ " + NORMAL
			qtincludes = qtdir + "/include/"
		elif os.path.isfile("/usr/include/qt3/qglobal.h"):
			# Debian probably
			print YELLOW + "the qt headers were found in /usr/include/qt3/ " + NORMAL
			qtincludes = "/usr/include/qt3"
		else:
			print RED + "the qt headers were not found" + NORMAL
			env.Exit(1)

	print "Checking for the kde includes     : ",
	kdeprefix = os.popen(kde_config + " --prefix").read().strip()
	if not kdeincludes:
		kdeincludes = kdeprefix+"/include/"
	if os.path.isfile(kdeincludes + "/klineedit.h"):
		print GREEN+"ok "+kdeincludes+NORMAL
	else:
		if os.path.isfile(kdeprefix+"/include/kde/klineedit.h"):
			# Debian, Fedora probably
			print YELLOW+"the kde headers were found in "+kdeprefix+"/include/kde/"+NORMAL
			kdeincludes = kdeprefix + "/include/kde/"
		else:
			print RED+"The kde includes were NOT found"+NORMAL
			env.Exit(1)

	if prefix:
		## use the user-specified prefix
		if not execprefix:
			execprefix = prefix
		if not datadir:
			datadir = prefix+"/share"
		if not libdir:
			libdir = execprefix+"/lib"

		subst_vars = lambda x: x.replace('${exec_prefix}',execprefix).replace('${datadir}',datadir).replace('${libdir}',libdir)
		env['KDEBIN']   = subst_vars(os.popen(kde_config + ' --install exe').read().strip())
		env['KDEAPPS']  = subst_vars(os.popen(kde_config + ' --install apps').read().strip())		
		env['KDEDATA']  = subst_vars(os.popen(kde_config + ' --install data').read().strip())
		env['KDEMODULE']= subst_vars(os.popen(kde_config + ' --install module').read().strip())
		env['KDELOCALE']= subst_vars(os.popen(kde_config + ' --install locale').read().strip())
		env['KDEDOC']   = subst_vars(os.popen(kde_config + ' --install html').read().strip())
		env['KDEKCFG']  = subst_vars(os.popen(kde_config + ' --install kcfg').read().strip())
		env['KDEXDG']   = subst_vars(os.popen(kde_config + ' --install xdgdata-apps').read().strip())
		env['KDEMENU']  = subst_vars(os.popen(kde_config + ' --install apps').read().strip())
		env['KDEMIME']  = subst_vars(os.popen(kde_config + ' --install mime').read().strip())
		env['KDEICONS'] = subst_vars(os.popen(kde_config + ' --install icon').read().strip())
		env['KDESERV']  = subst_vars(os.popen(kde_config + ' --install services').read().strip())
	else:
		# the user has given no prefix, install as a normal kde app
		env['PREFIX'] = os.popen(kde_config + ' --prefix').read().strip()
		env['KDEBIN']   = os.popen(kde_config + ' --expandvars --install exe').read().strip()
		env['KDEAPPS']  = os.popen(kde_config + ' --expandvars --install apps').read().strip()
		env['KDEDATA']  = os.popen(kde_config + ' --expandvars --install data').read().strip()
		env['KDEMODULE']= os.popen(kde_config + ' --expandvars --install module').read().strip()
		env['KDELOCALE']= os.popen(kde_config + ' --expandvars --install locale').read().strip()
		env['KDEDOC']   = os.popen(kde_config + ' --expandvars --install html').read().strip()
		env['KDEKCFG']  = os.popen(kde_config + ' --expandvars --install kcfg').read().strip()
		env['KDEXDG']   = os.popen(kde_config + ' --expandvars --install xdgdata-apps').read().strip()
		env['KDEMENU']  = os.popen(kde_config + ' --expandvars --install apps').read().strip()
		env['KDEMIME']  = os.popen(kde_config + ' --expandvars --install mime').read().strip()
		env['KDEICONS'] = os.popen(kde_config + ' --expandvars --install icon').read().strip()
		env['KDESERV']  = os.popen(kde_config + ' --expandvars --install services').read().strip()

	env['QTPLUGINS']=os.popen(kde_config + ' --expandvars --install qtplugins').read().strip()

	## kde libs and includes
	env['KDEINCLUDEPATH']= kdeincludes
	if not kdelibs:
		kdelibs = os.popen(kde_config + ' --expandvars --install lib').read().strip()
	env['KDELIBPATH']= kdelibs

	## qt libs and includes
	env['QTINCLUDEPATH']= qtincludes
	env['TQTINCLUDEPATH']=tqtincludes
	if not qtlibs:
		qtlibs = qtdir+"/lib"
	env['QTLIBPATH']= qtlibs

def mocscan(target, source, env):
	splitext = SCons.Util.splitext

	q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]')

	for obj in source:

		if not obj.has_builder():
			# binary obj file provided
			continue

		cpp = obj.sources[0]
		if not splitext(str(cpp))[1] == '.cpp':
			# not a cplusplus source
			continue

		# if we have a .ui file, it is automatically handled by Uic
		uiname = string.split(cpp.abspath, '.cpp')[0] + ".ui"
		if os.path.isfile(uiname):
			continue

                hname = splitext(cpp.name)[0] + ".h"
		h = SCons.Node.FS.find_file(hname, (cpp.get_dir(),) )

		if h:
			# h file with the Q_OBJECT macro found -> add .moc file
			mocfile = string.split(cpp.abspath, '.cpp')[0] + ".moc"
			# trick : check if the moc file already exists (avoid a scan)
			if os.path.isfile(mocfile):
				env.Moc(h)
			elif q_object_search.search(h.get_contents()):
				# FIXME : strong assumption
				env.Moc(h)

	return (target, source)

def generate(env):

	import SCons.Defaults
	import SCons.Tool
	env.Help("""
"""+BOLD+
"""*** KDE options ***
-------------------"""+NORMAL+"""
"""+BOLD+"""* prefix     """+NORMAL+""": base install path,         ie: /usr/local
"""+BOLD+"""* execprefix """+NORMAL+""": install path for binaries, ie: /usr/bin
"""+BOLD+"""* datadir    """+NORMAL+""": install path for the data, ie: /usr/local/share
"""+BOLD+"""* libdir     """+NORMAL+""": install path for the libs, ie: /usr/lib
"""+BOLD+"""* kdedir     """+NORMAL+""": path to TDE directory,     ie: /opt/trinity
"""+BOLD+"""* kdeincludes"""+NORMAL+""": path to the kde includes (/usr/include/kde on debian, ...)
"""+BOLD+"""* qtincludes """+NORMAL+""": same punishment, for qt includes (/usr/include/qt on debian, ...)
"""+BOLD+"""* kdelibs    """+NORMAL+""": path to the kde libs, for linking the programs
"""+BOLD+"""* qtlibs     """+NORMAL+""": same punishment, for qt libraries
ie: """+BOLD+"""scons configure libdir=/usr/local/lib qtincludes=/usr/include/qt
"""+NORMAL)
	
	CLVar = SCons.Util.CLVar
	splitext = SCons.Util.splitext
	Builder = SCons.Builder.Builder
	
	# Detect the environment - replaces ./configure implicitely
	# and store the options into a cache
	from SCons.Options import Options
	cachefile=env['CACHEDIR']+'/kde.cache.py'
	opts = Options(cachefile)
	opts.AddOptions(
		( 'QTDIR', 'root of qt directory' ),
		( 'QTLIBPATH', 'path to the qt libraries' ),
		( 'QTINCLUDEPATH', 'path to the qt includes' ),
		( 'QT_UIC', 'moc directory'),
		( 'QT_MOC', 'moc executable command'),
		( 'QTPLUGINS', 'uic executable command'),
		( 'KDEDIR', 'root of kde directory' ),
		( 'KDELIBPATH', 'path to the kde libs' ),
		( 'KDEINCLUDEPATH', 'path to the kde includes' ),

		( 'PREFIX', 'root of the program installation'),

		( 'KDEBIN', 'installation path of the kde binaries'),
		( 'KDEMODULE', 'installation path of the parts and libs'),
		( 'KDEAPPS', ''),
		( 'KDEDATA', 'installation path of the application data'),
		( 'KDELOCALE', ''),
		( 'KDEDOC', 'installation path of the application documentation'),
		( 'KDEKCFG', 'installation path of the .kcfg files'),
		( 'KDEXDG', 'installation path of the service types'),
		( 'KDEMENU', ''),
		( 'KDEMIME', 'installation path of to the mimetypes'),
		( 'KDEICONS', ''),
		( 'KDESERV', ''),
	)
	opts.Update(env)

	# reconfigure when things are missing
	if 'configure' in env['TARGS'] or not env.has_key('QTDIR') or not env.has_key('KDEDIR'):
		detect_kde(env)

	# finally save the configuration
	opts.Save(cachefile, env)

	## set default variables, one can override them in sconscript files
	env.Append(CXXFLAGS = ['-I'+env['KDEINCLUDEPATH'], '-I'+env['QTINCLUDEPATH'], '-I'+env['TQTINCLUDEPATH'], '-include', 'tqt.h' ])
	env.Append(LIBPATH = [env['KDELIBPATH'], env['QTLIBPATH'] ])
	
	env['STATIC_AND_SHARED_OBJECTS_ARE_THE_SAME'] = 1
	
	env['QT_AUTOSCAN']     = 1
	env['QT_DEBUG']        = 0
	
	env['QT_UIC_HFLAGS']   = '-L $QTPLUGINS -nounload'
	env['QT_UIC_CFLAGS']   = '$QT_UIC_HFLAGS -tr tr2i18n'
	env['QT_LIBS']         = 'tqt'
	
	env['LIBTOOL_FLAGS']   = '--silent --mode=compile --tag=CXX'
	
	env['QT_UICIMPLPREFIX'] = ''
	env['QT_UICIMPLSUFFIX'] = '.cpp'
	env['QT_MOCHPREFIX']    = ''
	env['QT_MOCHSUFFIX']    = '.moc'
	env['KDE_KCFG_IMPLPREFIX'] = ''
	env['KDE_KCFG_IMPL_HSUFFIX'] = '.h'
	env['KDE_KCFG_IMPL_CSUFFIX'] = '.cpp'
	env['KDE_SKEL_IMPL_SUFFIX']  = '.skel'
	env['MEINPROC']              = 'meinproc'
	env['MSGFMT']                = 'msgfmt'


	###### ui file processing
	def uicGenerator(target, source, env, for_signature):
		act=[]
		act.append('$QT_UIC $QT_UIC_HFLAGS -o '+target[0].path+' '+source[0].path)
		act.append('rm -f '                           +target[1].path)
		act.append('echo \'#include <klocale.h>\' >> '+target[1].path)
		act.append('echo \'#include <kdialog.h>\' >> '+target[1].path)
		act.append('$QT_UIC $QT_UIC_CFLAGS -impl '+target[0].path+' -o '+target[1].path+'.tmp '+source[0].path)
		act.append('cat '+target[1].path+'.tmp >> '+target[1].path)
		act.append('rm -f '+target[1].path+'.tmp')
		act.append('echo \'#include "' + target[2].name + '"\' >> '+target[1].path)
		act.append('moc-tqt $QT_MOC '+target[0].path+' '+target[2].path)
		return act
	
	def uicEmitter(target, source, env):
		adjustixes = SCons.Util.adjustixes
		bs = SCons.Util.splitext(str(source[0].name))[0]
		bs = os.path.join(str(target[0].get_dir()),bs)
		# first target is automatically added by builder (.h file)
		if len(target) < 2:
			# second target is .cpp file
			target.append(adjustixes(bs,
				env.subst('$QT_UICIMPLPREFIX'),
				env.subst('$QT_UICIMPLSUFFIX')))
		if len(target) < 3:
			# third target is .moc file
			target.append(adjustixes(bs,
				env.subst('$QT_MOCHPREFIX'),
				env.subst('$QT_MOCHSUFFIX')))
		return target, source
	
	UIC_BUILDER = Builder(
		generator  = uicGenerator,
		emitter    = uicEmitter,
		suffix     = '.h',
		src_suffix = '.ui' )
	
	###### moc file processing
	env['QT_MOCCOM'] = ('moc-tqt $QT_MOC $SOURCE ${TARGETS[0]}')
	
	MOC_BUILDER = Builder(
		action     = '$QT_MOCCOM',
		suffix     = '.moc',
		src_suffix = '.h' )
	
	MOCCPP_BUILDER = Builder(
		action     = '$QT_MOCCOM',
		suffix     = '_moc.cpp',
		src_suffix = '.h' )
	
	###### kcfg file processing
	def kcfgGenerator(target, source, env, for_signature):
		act=[]
		act.append('kconfig_compiler -d'+str(source[0].get_dir())+' '+source[1].path+' '+source[0].path)
		return act
	
	def kcfgEmitter(target, source, env):
		adjustixes = SCons.Util.adjustixes
		bs = SCons.Util.splitext(str(source[0].name))[0]
		bs = os.path.join(str(target[0].get_dir()),bs)
		# first target is automatically added by builder (.h file)
		if len(target) < 2:
			# second target is .cpp file
			target.append(adjustixes(bs, env.subst('$KDE_KCFG_IMPLPREFIX'), env.subst('$KDE_KCFG_IMPL_CSUFFIX')))
	
		if len(source) <2:
			kcfgfilename = os.popen("cat "+str(source[0])+"|grep File|sed 's/File.*=//i'").read().rstrip()
			source.append( str(source[0].get_dir())+'/'+kcfgfilename )
		return target, source

	KCFG_BUILDER = Builder(
		generator  = kcfgGenerator,
		emitter    = kcfgEmitter,
		suffix     = '.h',
		src_suffix = '.kcfgc' )
	
	###### dcop processing
	def dcopGenerator(target, source, env, for_signature):
		act=[]
		act.append('dcopidl '+source[0].path+' > '+target[1].path+'|| ( rm -f '+target[1].path+' ; false )')
		act.append('dcopidl2cpp --c++-suffix cpp --no-signals --no-stub '+target[1].path)
		return act

	def dcopEmitter(target, source, env):
		bs = SCons.Util.splitext(str(source[0].name))[0]
		bs = os.path.join(str(target[0].get_dir()),bs)
		target.append(bs+'.kidl')
		#target.append(bs+'_skel.cpp')
		return target, source

	DCOP_BUILDER = Builder(
		generator  = dcopGenerator,
		emitter    = dcopEmitter,
		suffix     = '_skel.cpp',
		src_suffix = '.h' )

	###### documentation (meinproc) processing
	MEINPROC_BUILDER = Builder(
		action     = '$MEINPROC --check --cache $TARGET $SOURCE',
		suffix     = '.cache.bz2',
		src_suffix = '.docbook' )

	###### translation files builder
	TRANSFILES_BUILDER = Builder(
		action     = '$MSGFMT $SOURCE -o $TARGET',
		suffix     = '.gmo',
		src_suffix = '.po' )

	###### libtool file builder
	def laGenerator(target, source, env, for_signature):
		act=[]
		act.append('echo "dlname=\''+source[0].name+'\'" > '+target[0].path)
		act.append('echo "library_names=\''+source[0].name+' '+source[0].name+' '+source[0].name+'\'" >> '+target[0].path)
		act.append('echo "old_library=\'\'">> '+target[0].path)
		act.append('echo "dependency_libs=\'\'">> '+target[0].path)
		act.append('echo "current=0">> '+target[0].path)
		act.append('echo "age=0">> '+target[0].path)
		act.append('echo "revision=0">> '+target[0].path)
		act.append('echo "installed=yes">> '+target[0].path)
		act.append('echo "shouldnotlink=no">> '+target[0].path)
		act.append('echo "dlopen=\'\'">> '+target[0].path)
		act.append('echo "dlpreopen=\'\'">> '+target[0].path)
		act.append('echo "libdir=\''+env['KDEMODULE']+'\'" >> '+target[0].path)
		return act
	
	LA_BUILDER = Builder(
		generator  = laGenerator,
		suffix     = '.la',
		src_suffix = '.so' )
	
	##### register the builders
	env['BUILDERS']['Uic']        = UIC_BUILDER
	env['BUILDERS']['Moc']        = MOC_BUILDER
	env['BUILDERS']['Moccpp']     = MOCCPP_BUILDER
	env['BUILDERS']['Dcop']       = DCOP_BUILDER
	env['BUILDERS']['Kcfg']       = KCFG_BUILDER
	env['BUILDERS']['LaFile']     = LA_BUILDER
	env['BUILDERS']['Meinproc']   = MEINPROC_BUILDER
	env['BUILDERS']['Transfiles'] = TRANSFILES_BUILDER

	static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
	static_obj.src_builder.append('Uic')
	shared_obj.src_builder.append('Uic')
	static_obj.src_builder.append('Kcfg')
	shared_obj.src_builder.append('Kcfg')
	static_obj.src_builder.append('LaFile')
	shared_obj.src_builder.append('LaFile')
	static_obj.src_builder.append('Meinproc')
	shared_obj.src_builder.append('Meinproc')
	static_obj.src_builder.append('Transfiles')
	shared_obj.src_builder.append('Transfiles')

	## find the files to moc, dcop, and link against kde and qt
        env.AppendUnique(PROGEMITTER=[mocscan], SHLIBEMITTER=[mocscan], LIBEMITTER =[mocscan])

	###########################################
	## Handy helpers for building kde programs
	## You should not have to modify them ..

	#import SCons.Util
	skel_ext = [".skel", ".SKEL"]
	def KDEfiles(lenv, target, source):
		""" Returns a list of files for scons (handles kde tricks like .skel)
		It also makes custom checks against double includes like : ['file.ui', 'file.cpp']
		(file.cpp is already included because of file.ui) """

		src=[]
		ui_files=[]
		kcfg_files=[]
		skel_files=[]
		other_files=[]

		# For each file, check wether it is a dcop file or not, and create the complete list of sources
		for file in source:
			bs  = SCons.Util.splitext(file)[0]
			ext = SCons.Util.splitext(file)[1]
			if ext in skel_ext:
				lenv.Dcop(bs+'.h')
				src.append(bs+'_skel.cpp')
			elif ext == ".moch":
				lenv.Moccpp(bs+'.h')
				src.append(bs+'_moc.cpp')
			else:
				src.append(file)

			if ext == '.ui':
				ui_files.append(bs)
			elif ext == '.kcfgc':
				kcfg_files.append(bs)
			elif ext == '.skel':
                                skel_files.append(bs)
                        else:
                                other_files.append(bs)
		return src

	"""
	In the future, these functions will contain the code that will dump the
	configuration for re-use from an IDE
	"""
	import glob
	def KDEinstall(lenv, restype, subdir, files):
		if not 'install' in env['TARGS']:
			return
		basedir=env['DESTDIR']
		if len(restype)>0:
			if not lenv.has_key(restype):
				print RED+"unknown resource type "+restype+NORMAL
			else:
				basedir += lenv[restype]+'/'
		#print file # <- useful to trace stuff :)
		install_list =  env.Install(basedir+subdir, files)
		env.Alias('install', install_list)
		return install_list

	def KDEinstallas(lenv, restype, destfile, file):
		if not 'install' in env['TARGS']:
			return
		basedir=env['DESTDIR']
		if len(restype)>0:
			if not lenv.has_key(restype):
				print RED+"unknown resource type "+restype+NORMAL
			else:
				basedir += lenv[restype]+'/'
		install_list = env.InstallAs(basedir+destfile, file)
		env.Alias('install', install_list)
		return install_list

	def KDEprogram(lenv, target, source):
		""" Makes a kde program
		The program is installed except if one sets env['NOAUTOINSTALL'] """
		src = KDEfiles(lenv, target, source)
		program_list = lenv.Program(target, src)
		if not lenv.has_key('NOAUTOINSTALL'):
			KDEinstall(lenv, 'KDEBIN', '', target)
		return program_list

	def KDEshlib(lenv, target, source, kdelib=0):
		""" Makes a shared library for kde (.la file for klibloader)
		The library is installed except if one sets env['NOAUTOINSTALL'] """
		src = KDEfiles(lenv, target, source)
		library_list = lenv.SharedLibrary(target, src)
		lafile_list  = lenv.LaFile(target, library_list)
		if not lenv.has_key('NOAUTOINSTALL'):
			install_dir = 'KDEMODULE'
			if kdelib==1:
				install_dir = 'KDELIBPATH'
			KDEinstall(lenv, install_dir, '', library_list)
			KDEinstall(lenv, install_dir, '', lafile_list)
		return library_list

	def KDEstaticlib(lenv, target, source):
		""" Makes a static library for kde - in practice you should not use static libraries
		1. they take more memory than shared ones
		2. makefile.am needed it because of limitations
		(cannot handle sources in separate folders - takes extra processing) """
		src = KDEfiles(lenv, target, source)
		return lenv.StaticLibrary(target, src)
		# do not install static libraries by default

	def KDEaddflags_cxx(lenv, fl):
		""" Compilation flags for C++ programs """
		lenv.AppendUnique(CXXFLAGS = fl)

	def KDEaddflags_c(lenv, fl):
		""" Compilation flags for C programs """
		lenv.AppendUnique(CFLAGS = fl)

	def KDEaddflags_link(lenv, fl):
		""" Add link flags - Use this if KDEaddlibs below is not enough """
		lenv.AppendUnique(LINKFLAGS = fl)

	def KDEaddlibs(lenv, libs):
		""" Helper function """
		lenv.AppendUnique(LIBS = libs)

	def KDEaddpaths_includes(lenv, paths):
		""" Add new include paths """
		lenv.AppendUnique(CPPPATH = paths)

	def KDEaddpaths_libs(lenv, paths):
		""" Add paths to libraries """
		lenv.AppendUnique(LIBPATH = paths)

	def KDElang(lenv, folder, appname):
		""" Process translations (.po files) in a po/ dir """
		transfiles = glob.glob(folder+'/*.po')
		for lang in transfiles:
			result = lenv.Transfiles(lang)
			country = SCons.Util.splitext(result[0].name)[0]
			KDEinstallas(lenv, 'KDELOCALE', country+'/LC_MESSAGES/'+appname+'.mo', result)

	def KDEicon(lenv, icname):
		""" Emulates the behaviour of Makefile.am to install icons
		Contributed by: "Andrey Golovizin" <grooz@gorodok@net> """
		type_dic = { 'action' : 'actions', 'app' : 'apps', 'device' : 
			'devices', 'filesys' : 'filesystems', 'mime' : 'mimetypes' } 
		dir_dic = {
		'los'  :'locolor/16x16',
		'lom'  :'locolor/32x32',
		'him'  :'hicolor/32x32',
		'hil'  :'hicolor/48x48',
		'lo16' :'locolor/16x16',
		'lo22' :'locolor/22x22',
		'lo32' :'locolor/32x32',
		'hi16' :'hicolor/16x16',
		'hi22' :'hicolor/22x22',
		'hi32' :'hicolor/32x32',
		'hi48' :'hicolor/48x48',
		'hi64' :'hicolor/64x64',
		'hi128':'hicolor/128x128',
		'hisc' :'hicolor/scalable',
		'cr16' :'crystalsvg/16x16',
		'cr22' :'crystalsvg/22x22',
		'cr32' :'crystalsvg/32x32',
		'cr48' :'crystalsvg/48x48',
		'cr64' :'crystalsvg/64x64',
		'cr128':'crystalsvg/128x128',
		'crsc' :'crystalsvg/scalable'
		}

		import glob
		iconfiles = []
		for ext in ['png', 'xpm', 'mng', 'svg', 'svgz']:
			files = glob.glob('*-*-%s.%s' % (icname, ext))
			iconfiles += files
		for iconfile in iconfiles:
			tmp = iconfile.split('-')
			if len(tmp) != 3:
				print RED + 'WARNING: icon filename has unknown format: ' + iconfile + NORMAL
				continue
			[icon_dir, icon_type, icon_filename] = tmp
			try:
				destfile = '%s/%s/%s/%s' % (lenv['KDEICONS'], dir_dic[icon_dir], type_dic[icon_type], icon_filename)
			except KeyError:
				print RED + 'WARNING: unknown icon type: ' + iconfile + NORMAL
				continue
			## do not use KDEinstallas here, as parsing from an ide will be necessary
			if 'install' in env['TARGS']:
				env.Alias('install', env.InstallAs( env['DESTDIR']+'/'+destfile, iconfile ) )

	# Attach the functions to the environment so that sconscripts can use them
	from SCons.Script.SConscript import SConsEnvironment
	SConsEnvironment.KDEprogram = KDEprogram
	SConsEnvironment.KDEshlib = KDEshlib
	SConsEnvironment.KDEstaticlib = KDEstaticlib
	SConsEnvironment.KDEinstall = KDEinstall
	SConsEnvironment.KDEinstallas = KDEinstallas
	SConsEnvironment.KDElang = KDElang
	SConsEnvironment.KDEicon = KDEicon

	SConsEnvironment.KDEaddflags_cxx = KDEaddflags_cxx
	SConsEnvironment.KDEaddflags_c = KDEaddflags_c
	SConsEnvironment.KDEaddflags_link = KDEaddflags_link
	SConsEnvironment.KDEaddlibs = KDEaddlibs
	SConsEnvironment.KDEaddpaths_includes = KDEaddpaths_includes
	SConsEnvironment.KDEaddpaths_libs = KDEaddpaths_libs
