Sophie

Sophie

distrib > Mandriva > 2009.1 > x86_64 > media > contrib-backports > by-pkgid > 5449138d6297d4beefc46ffe46a8c51a > files > 409

waf-1.5.11-1mdv2009.1.noarch.rpm

#!/usr/bin/env python
##
# @file
# waf Makefile.am related tools
#
# a Makefile.am to scons converter
#
# (@) 2005 LiuCougar  - published under the GPL license
#

import os, re, types, sys, string, shutil, stat, glob, amtool

## Class for automatically converting Makefile.am to SConscript
#
# The class can handle simple Makefile.am 100% correct, for complex ones, manual
# fine-tunning is required. These are something that can not handle:
#		- Custom make target
#		- extra moc files
#		- checking programs (test/EXTRA, how to enable checking?? )
#		- conditional compilation
#		- install dir support
#		- DATA files handling
#
#
# @TODO fix installation

class AM2Waf(amtool.AMFile):
	def __init__(self):
		amtool.AMFile.__init__(self)
		self.ignoreIncludePaths = ['$(top_srcdir)', '$(all_includes)']

		self.defaultUseLibs = 'QT QTCORE QTGUI QT3SUPPORT KDE4'

		self.LibHandlerMapping = {
		'noinst' : 'bld.createObj(\'kde\', \'convenience\')',
		'kdeinit' : 'bld.createObj()',
		'lib' : 'bld.createObj(\'kde\', \'shlib\')',
		'kde_module' : 'bld.createObj(\'kde\', \'module\')',
		'plugin' : 'bld.createObj(\'cpp\', \'shlib\')',
		}

		self.ProgHandlerMapping = {
		'bin' : 'bld.createObj(\'\kde\', \'program\')',
		'check' : 'env.kdeobj(\'program\')\nobj.env = env.Copy()\nobj.env[\'NOAUTOINSTALL\'] = 1',
		'EXTRA' : 'env.kdeobj(\'program\')\nobj.env = env.Copy()\nobj.env[\'NOAUTOINSTALL\'] = 1',
		}

		self.DataHandlerMapping = {
			'kde_htmldir' : '',
			'kde_appsdir' : 'KDEAPPS',
			'kde_icondir' : 'KDEICONS',
			'kde_sounddir' : '',
			'kde_datadir' : 'KDEAPPS',
			'kde_locale' : 'KDELOCALE',
			'kde_cgidir' : '',
			'kde_confdir' : 'KDECONF',
			'kde_kcfgdir' : 'KDEKCFG',
			'kde_mimedir' : 'KDEMIME',
			'kde_toolbardir' : '',
			'kde_wallpaperdir' : '',
			'kde_templatesdir' : '',
			'kde_bindir' : 'KDEBIN',
			'kde_servicesdir' : 'KDESERV',
			'kde_servicetypesdir' : 'KDESERVTYPES',
			'kde_moduledir' : 'KDEMODULE',
			'kde_styledir' : '',
			'kde_widgetdir' : '',
			'xdg_appsdir' : '',
			'xdg_menudir' : '',
			'xdg_directorydir' : '',
		}

		self.out_buf_header = """#! /usr/bin/env python
#generated from %s by am2waf.py

"""
	#generate source lists
	def generateSources(self):
		out_buf = ""
		for key in self.sources.keys():
			out_buf += "\t"
			out_buf += key + "_sources = \"\"\"\n"
			sources = self.sources[key].split()
			sources.sort()

			while len(sources) >= 4:
				out_buf += ' '.join(sources[:4]) + "\n"
				del sources[:4]
			if len(sources):
				out_buf += ' '.join(sources) + "\n"
			out_buf += "\"\"\"\n"
		return out_buf

	#generate header file lists
	def generateHeaders(self):
		out_buf = ""
		for key in self.headers.keys():
			out_buf += "\t"
			out_buf += key + "_headers = \"\"\"\n"
			headers = self.headers[key].split()
			headers.sort()

			while len(headers) >= 4:
				out_buf += ' '.join(headers[:4]) + "\n"
				del headers[:4]
			if len(headers):
				out_buf += ' '.join(headers) + "\n"
			out_buf += "\"\"\"\n"
		return out_buf

	def generateLibadds(self, name):
		reg = re.compile("(.*)lib([^/]*)\.la$")
		def convertLocalLibs(lib):
			lib = lib.replace('$(top_srcdir)', '#')
			lib = lib.replace('$(top_builddir)', '##')
			lib = lib.replace('$(srcdir)/', '')
			result=reg.match(lib)
			if result:
				path = result.group(1)
				if path.endswith('/'):	path = path[:-1]
				if path[:2] == "./": path = path[2:]
				return (path, result.group(2))

			return ('', lib)
		uselibs = self.defaultUseLibs.split()
		out_buf = ""
		if self.libadds.has_key(name):
			convertedlibs = []
			libpaths = []
			libs = self.libadds[name].split()
			for lib in libs:
				if lib[:2] == '$(' and lib[-1:] == ')':
					if lib[2:6] == "LIB_":
						uselibs.append(lib[6:-1])
					elif lib[2:5] == "LIB":
						uselibs.append(lib[5:-1])
					else:
						print "WARNING: UNKNOW makefile variable in LDADDS %s" % lib
				else:
					path, libname = convertLocalLibs(lib)
					if len(path) and not libpaths.count(path):
						libpaths.append(path)
					convertedlibs.append(libname)
			if len(convertedlibs):
				out_buf += "\tobj.libpaths = '%s '\n" % ' '.join(libpaths)
				out_buf += "\tobj.libs = '%s '\n" % ' '.join(convertedlibs)

		out_buf += '\tobj.uselib = \'%s \'\n' % ' '.join(uselibs)
		return out_buf

	def generateObj(self, islib, objtype, name):
		if islib:
			out_buf = "\tobj = %s\n" % self.LibHandlerMapping[objtype]
		else:
			out_buf = "\tobj = %s\n" % self.ProgHandlerMapping[objtype]

		include = ""

		#TARGET
		out_buf += "\tobj.target = '%s'\n" % name

		#FIXME: other LDFLAGS support
		#Version number
		if self.ldflags.has_key(name):
			flags = self.ldflags[name].split()
			if islib and flags.count('-version-info') > 0:
				index = flags.index('-version-info') + 1
				if index < len(flags):
					version = flags[index]
					if version.replace(':','').isdigit():
						tab = version.split(':')

						if len(tab) == 3:
							val = eval(tab[0])-eval(tab[2])
							newVal = str(val) + "." + tab[2]+ "." + tab[1]
						else:
							newVal = tab[0] + "." + tab[1]+ ".0"
						out_buf += "\tobj.vnum = '%s'\n" % newVal 
					else:
						print "WARNING: version-info format is incorrect"

		#SOURCES
		out_buf += "\tobj.source = %s_sources\n" % name

		#INCLUDES
		if self.includes.has_key(name):
			include = "'" + self.includes[name] + "'"
		elif self.includes.has_key('_DIR_GLOBAL_'):
			include = 'includes'

		if include:
			out_buf += "\tobj.includes = %s\n" % include

		#LIBADD
		out_buf += self.generateLibadds(name)

		#out_buf += 'obj.execute()\n\n'

		return out_buf

	def generateSubdirs(self):
		out_buf = ""
		if len(self.subdirs):
			dirs = self.subdirs.split()
			if dirs.count('.'): del dirs[dirs.index('.')]
			out_buf = "\tbld.add_subdirs(['%s'])\n\n" % "', '".join(dirs)
		return out_buf;

	def generateData(self, files, inst_dir):
		def getKDEInstType(rawdir):
			if rawdir[:2] != "$(":
				print "ERROR: Do not understand data install dir format %s\n" % rawdir
				return "",""
			instype = subdir = ""
			if rawdir.endswith(")"):
				instype = rawdir[2:-1]
			else:
				reg = re.compile("\$\((.*)\)/(.*)")
				result = reg.match(rawdir)
				if result:
					instype = result.group(1)
					subdir = result.group(2)

			if not len(instype) or not self.DataHandlerMapping.has_key(instype):
				instype = ""
			else:
				instype = self.DataHandlerMapping[instype]

			return (instype, subdir)

		out_buf = ""
		if len(files):
			(insttype, subdir) = getKDEInstType(inst_dir)
			if insttype:
				out_buf = "\tinstall_files('%s', '%s', '%s')\n\n" % (insttype, subdir, files)
		return out_buf

	def generateConscript(self):
		out_buf = self.out_buf_header % self.path
		out_buf +="def build(bld):\n"
		out_buf +="\t# process subfolders from here\n"

		self.getIncludes()	#fix path

		out_buf += self.generateSources()

		out_buf += self.generateHeaders()

		#find global includes setting for self dir:
		if self.includes.has_key('_DIR_GLOBAL_'):
			out_buf += "\tincludes = '%s '\n\n" % self.includes['_DIR_GLOBAL_']



		#generate library objects
		for libtypekey in self.libs.keys():
			if not self.LibHandlerMapping.has_key(libtypekey):
				print "ERROR: library type %s is not defined in LibHandlerMapping" % libtypekey
				return
			for key in self.libs[libtypekey].split():
				out_buf += self.generateObj(1, libtypekey, key)

		#generate program objects
		for progtypekey in self.progs.keys():
			if not self.ProgHandlerMapping.has_key(progtypekey):
				print "ERROR: Program type %s is not defined in ProgHandlerMapping" % progtypekey
				return
			#FIXME: implement test/check support
			if progtypekey in ['check', 'EXTRA']:
				continue
			for key in self.progs[progtypekey].split():
				out_buf += self.generateObj(0, progtypekey, key)

		#generate data files
		for dataname in self.data.keys():
			out_buf += self.generateData(self.data[dataname], self.datadirs[dataname])

		out_buf += self.generateSubdirs()
		if len(self.defines):
			out_buf += '\n"""Unhandled Defines \n'
			for key in self.defines.keys():
				out_buf += key  + ' = ' + self.defines[key] + "\n"
			out_buf += '"""\n'

		if len(self.targets):
			out_buf += '\n"""Unhandled Targets \n'
			for key in self.targets.keys():
				out_buf += key  + ' = ' + self.targets[key] + "\n"
			out_buf += '"""\n'


		return out_buf

	def getIncludes(self):
		amtool.AMFile.getIncludes(self)
		for key in self.includes.keys():
			self.includes[key] = self.convertIncludesPath(self.includes[key])
		return self.includes

	def convertIncludesPath(self, paths_str):
		retlist = []
		paths = paths_str.split()
		for path in paths:
			if path[:2] == '-I':
				path = path[2:]
			if path in self.ignoreIncludePaths:
				continue
			path = path.replace('$(top_srcdir)', '#')
			path = path.replace('$(top_builddir)', '#')
			path = path.replace('$(srcdir)/', '')
			retlist.append(self.convertMakeFileVariable(path))
		return ' '.join(retlist)

if len(sys.argv) == 1:
	print "am2waf [options] Makefile.am"
	print "Convert a Makefile.am to waf wscript"
	print "options:"
	print "    -o file  Write generated wscript to this file"
	print "    -w Write generated wscript to the same dir as the Makefile.am"
	print "By default, am2waf will output the generated wscript to stdout"
else:
	outputfile = ""
	for a in range(1,len(sys.argv)):
		if sys.argv[a][:2] == '-o' and a+1 < len(sys.argv):
			outputfile = sys.argv[a+1]
			a += 1
		elif sys.argv[a][:2] == '-w':
			outputfile = "#"

	for a in range(1,len(sys.argv)):
		if sys.argv[a][:1] == '-':
			continue

		am_file = AM2Waf()
		inputfile = sys.argv[a];
		if not am_file.read(inputfile):
			print "ERROR: can not read file %s" % inputfile
			continue

		if len(outputfile):
			try:
				if outputfile == "#":
					outputfile = inputfile.replace("Makefile.am", "wscript")
				dest = open(outputfile, 'w')
			except:
				exit

			dest.write(am_file.generateConscript())
			dest.close()
			print "File %s is successfully created." % outputfile
		else:
			print am_file.generateConscript()

		break