diff -r 5e7562f67577 -r c327db0664bb sbsv2/raptor/bin/createvmap.py --- a/sbsv2/raptor/bin/createvmap.py Sun May 16 13:06:27 2010 +0100 +++ b/sbsv2/raptor/bin/createvmap.py Mon May 17 20:20:32 2010 +0100 @@ -1,310 +1,310 @@ -# -# Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). -# All rights reserved. -# This component and the accompanying materials are made available -# under the terms of the License "Eclipse Public License v1.0" -# which accompanies this distribution, and is available -# at the URL "http://www.eclipse.org/legal/epl-v10.html". -# -# Initial Contributors: -# Nokia Corporation - initial contribution. -# -# Contributors: -# -# Description: -# - -# Python Script to create the vmap file for Binary Variation support in SBSv2 - -import sys -import os -import re -import subprocess -import tempfile -import traceback -from optparse import OptionParser - -# the script will exit with 0 if there are no errors -global exitCode -exitCode = 0 - -# are we running on Windows? -onWindows = sys.platform.lower().startswith("win") - -# error messages go to stderr -def error(format, *extras): - sys.stderr.write("createvmap: error: " + (format % extras) + "\n") - global exitCode - exitCode = 1 - -# warning messages go to stderr -def warning(format, *extras): - sys.stderr.write("createvmap: warning: " + (format % extras) + "\n") - -# debug messages go to stderr -global printDebug -# -def debug(format, *extras): - if printDebug: - sys.stderr.write("createvmap: " + (format % extras) + "\n") - -# Return a dictionary with the feature names and values from the preinclude file, by running cpp over the source -def getVmapMacros(aPreInclude, aPreprocessedFile=None, aCPP="cpp", aDefines="", aIncludes = ""): - - validmacros = {} - # Run the pre-processor - command = aCPP + " -include " + os.path.abspath(aPreInclude) + " -dU " + aDefines + aIncludes - - # Feed in the file to stdin, because we must set the stdin to something - # other than the parent stdin anyway as that may not exist - for example - # when using Talon. - infile = open(aPreprocessedFile, "r") - - if onWindows: - p = subprocess.Popen(command, bufsize=65535, - stdin=infile, - stdout=subprocess.PIPE, - stderr=sys.stderr, - universal_newlines=True) - else: - p = subprocess.Popen(command, bufsize=65535, - stdin=infile, - stdout=subprocess.PIPE, - stderr=sys.stderr, - close_fds=True, shell=True) - stream = p.stdout - - # Parse the pre-processor output to look for - - # lines "#define NAME VALUE" and "#undef NAME" - defineRE = re.compile('^#define (?P\w+)(\s+(?P\w+))?') - undefRE = re.compile('^#undef (?P\w+)') - - data = " " - while data: - data = stream.readline() - - definedmacro = defineRE.match(data) - if definedmacro: - name = definedmacro.group('FEATURENAME') - value = definedmacro.group('VALUE') - if value: - validmacros[name] = value - else: - validmacros[name] = "defined" - - else: - undefinedmacro = undefRE.match(data) - if undefinedmacro: - validmacros[undefinedmacro.group('FEATURENAME')] = "undefined" - - if p.wait() != 0: - error("in command '%s'", command) - - infile.close() - - return validmacros - -# Extract the features from a featurelist file -def getFeatures(aFeatureList): - features = set() - for f in aFeatureList: - try: - file = open(os.path.abspath(f),'r') - - for data in file.readlines(): - data = data.strip() - features.add(data) - - file.close() - - except IOError: - error("Feature list file %s not found", f) - - return sorted(list(features)) - -# Returns a dictionary of the features to be put in the vmap file -def getVariationFeatures(aFeatureList = [] ,aPreinclude = None,aPreprocessedFile = None,aCPP = "cpp",aDefines="",aIncludes = ""): - - variation_features = {'FEATURENAME':[],'VALUE':[]} - macros = getVmapMacros(aPreinclude,aPreprocessedFile,aCPP,aDefines,aIncludes) - - # Co-relate the macros obtained from the pre-processor to the featurelist - for f in aFeatureList: - if f in macros: - variation_features['FEATURENAME'].append(f) - variation_features['VALUE'].append(macros[f]) - - return variation_features - -# Write to the vmap file, with the supplied dictionary containing the features -# The vmap path will be created if it doesn't exist -def createVmapFile(aMacroDictionary,aOutputfile): - if not os.path.exists(os.path.dirname(aOutputfile)): - os.makedirs(os.path.dirname(aOutputfile)) - try: - vmapfile = open(aOutputfile,'w') - except IOError: - error("Cannot write to " + aOutputfile) - i = 0 - while i < len(aMacroDictionary['FEATURENAME']): - vmapfile.write(aMacroDictionary['FEATURENAME'][i]+"="+aMacroDictionary['VALUE'][i]+"\n") - i += 1 - vmapfile.close() - -def check_exists(thing, filenames): - if not filenames: - error("No %s specified", thing) - return - - if not isinstance(filenames, list): - # we just have a single string - filenames = [filenames] - - for filename in filenames: - if not os.path.exists(filename): - error("The %s '%s' does not exist", thing, filename) - -# Main function, creates the vmap file -def main(): - - try: - global exitCode, printDebug - - # any exceptions make us traceback and exit - - parser = OptionParser(prog = "createvmap.py") - - parser.add_option("-c","--cpploc",action="store",dest="cpplocation",help="Full path of the preprocessor") - parser.add_option("-d","--debug",action="store_true",default=False,dest="debug",help="Turn debug information on") - parser.add_option("-D","--define",action="append",dest="defines",help="Macro definition") - parser.add_option("-f","--featurelist",action="append",dest="featurelistfile",help="List of featureslist files") - parser.add_option("-o","--output",action="store",dest="outputvmapfile",help="Output VMAP file name") - parser.add_option("-p","--preinclude",action="store",dest="preinclude",help="Pre-include file ") - parser.add_option("-s","--source",action="append",dest="sourcefiles",help="List of source files") - parser.add_option("-u","--userinc",action="append",dest="user_include",help="User Include Folders") - parser.add_option("-x","--systeminc",action="append",dest="system_include",help="System Include Folders") - - (options, leftover_args) = parser.parse_args(sys.argv[1:]) - - if leftover_args: - for invalids in leftover_args: - warning("Unknown parameter '%s'" % invalids) - - printDebug = options.debug - debug("Source Files -> %s", options.sourcefiles) - debug("Macro defines -> %s", options.defines) - debug("Features Files -> %s", options.featurelistfile) - debug("Pre-Include File -> %s", options.preinclude) - debug("User Includes -> %s", options.user_include) - debug("System Includes -> %s", options.system_include) - debug("CPP Location -> %s", options.cpplocation) - debug("VMAP Output name -> %s", options.outputvmapfile) - - featurelist = [] - definelist = "" - user_includeslist = "" - system_includeslist = "" - includeslist = "" - - # Some error checking code - if not options.outputvmapfile: - error("No output vmap file name supplied") - - # Source files must be supplied - check_exists("source file", options.sourcefiles) - - # A valid preinclude file must be supplied - check_exists("pre-include file", options.preinclude) - - # Some feature lists are required - check_exists("feature list", options.featurelistfile) - - # A cpp tool is required - check_exists("cpp tool", options.cpplocation) - - # if an essential option was missing then we should stop now - if exitCode != 0: - sys.exit(exitCode) - - # macro definitions - if options.defines: - for macro in options.defines: - definelist += " -D" + macro.replace('__SBS__QUOTE__', '\\"') - - # Note that we have to use -isystem for user includes and system - # includes to match what happens in the compiler. Long story. - - # Add each source directory as a user-include, so that our temporary - # concatenated source file can find includes that were next to the - # original source files. - # Check that all the specified source files exist - # and collect a set of all the source directories - sourcedirs = set() - for src in options.sourcefiles: - sourcedirs.add(os.path.dirname(src)) - - for srcdir in sourcedirs: - user_includeslist += " -isystem " + srcdir - - # Convert the include list to a string to be passed to cpp - if options.user_include: - for userinc in options.user_include: - user_includeslist += " -isystem " + userinc - if options.system_include: - for sysinc in options.system_include: - system_includeslist += " -isystem " + sysinc - - includeslist = user_includeslist + system_includeslist - - # Get a list of all the features, from all the featurelist files - featurelist = getFeatures(options.featurelistfile) - - # concatenate the source files together into a temporary file - try: - (tempfd, tempname) = tempfile.mkstemp() - temp = os.fdopen(tempfd, "w") - for src in options.sourcefiles: - sfile = open(src, "r") - for sline in sfile: - temp.write(sline) - sfile.close() - temp.close() - except Exception,e: - error("Could not write source files into temporary file %s : %s" % (tempname, str(e))) - return 1 - - debug("Temporary file name : " + tempname) - - # extract the macros from the concatenated source files - macro_dictionary = getVariationFeatures(featurelist, - options.preinclude, - tempname, - options.cpplocation, - definelist, - includeslist) - debug("Macros extracted:") - for key,values in macro_dictionary.iteritems(): - debug(key + " " + str(values)) - - # if there were no macros then the vmap file will be empty... - if not macro_dictionary['FEATURENAME']: - warning("No feature macros were found in the source") - - # Get rid of the temporary file - try: - os.remove(tempname) - except: - error("Could not delete temporary %s" % tempname) - - createVmapFile(macro_dictionary, options.outputvmapfile) - - # exit with 0 if OK - return exitCode - - except Exception,ex: - traceback.print_exc() - return 1 - -if __name__ == "__main__": - sys.exit(main()) - +# +# Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of the License "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +# Python Script to create the vmap file for Binary Variation support in SBSv2 + +import sys +import os +import re +import subprocess +import tempfile +import traceback +from optparse import OptionParser + +# the script will exit with 0 if there are no errors +global exitCode +exitCode = 0 + +# are we running on Windows? +onWindows = sys.platform.lower().startswith("win") + +# error messages go to stderr +def error(format, *extras): + sys.stderr.write("createvmap: error: " + (format % extras) + "\n") + global exitCode + exitCode = 1 + +# warning messages go to stderr +def warning(format, *extras): + sys.stderr.write("createvmap: warning: " + (format % extras) + "\n") + +# debug messages go to stderr +global printDebug +# +def debug(format, *extras): + if printDebug: + sys.stderr.write("createvmap: " + (format % extras) + "\n") + +# Return a dictionary with the feature names and values from the preinclude file, by running cpp over the source +def getVmapMacros(aPreInclude, aPreprocessedFile=None, aCPP="cpp", aDefines="", aIncludes = ""): + + validmacros = {} + # Run the pre-processor + command = aCPP + " -include " + os.path.abspath(aPreInclude) + " -dU " + aDefines + aIncludes + + # Feed in the file to stdin, because we must set the stdin to something + # other than the parent stdin anyway as that may not exist - for example + # when using Talon. + infile = open(aPreprocessedFile, "r") + + if onWindows: + p = subprocess.Popen(command, bufsize=65535, + stdin=infile, + stdout=subprocess.PIPE, + stderr=sys.stderr, + universal_newlines=True) + else: + p = subprocess.Popen(command, bufsize=65535, + stdin=infile, + stdout=subprocess.PIPE, + stderr=sys.stderr, + close_fds=True, shell=True) + stream = p.stdout + + # Parse the pre-processor output to look for - + # lines "#define NAME VALUE" and "#undef NAME" + defineRE = re.compile('^#define (?P\w+)(\s+(?P\w+))?') + undefRE = re.compile('^#undef (?P\w+)') + + data = " " + while data: + data = stream.readline() + + definedmacro = defineRE.match(data) + if definedmacro: + name = definedmacro.group('FEATURENAME') + value = definedmacro.group('VALUE') + if value: + validmacros[name] = value + else: + validmacros[name] = "defined" + + else: + undefinedmacro = undefRE.match(data) + if undefinedmacro: + validmacros[undefinedmacro.group('FEATURENAME')] = "undefined" + + if p.wait() != 0: + error("in command '%s'", command) + + infile.close() + + return validmacros + +# Extract the features from a featurelist file +def getFeatures(aFeatureList): + features = set() + for f in aFeatureList: + try: + file = open(os.path.abspath(f),'r') + + for data in file.readlines(): + data = data.strip() + features.add(data) + + file.close() + + except IOError: + error("Feature list file %s not found", f) + + return sorted(list(features)) + +# Returns a dictionary of the features to be put in the vmap file +def getVariationFeatures(aFeatureList = [] ,aPreinclude = None,aPreprocessedFile = None,aCPP = "cpp",aDefines="",aIncludes = ""): + + variation_features = {'FEATURENAME':[],'VALUE':[]} + macros = getVmapMacros(aPreinclude,aPreprocessedFile,aCPP,aDefines,aIncludes) + + # Co-relate the macros obtained from the pre-processor to the featurelist + for f in aFeatureList: + if f in macros: + variation_features['FEATURENAME'].append(f) + variation_features['VALUE'].append(macros[f]) + + return variation_features + +# Write to the vmap file, with the supplied dictionary containing the features +# The vmap path will be created if it doesn't exist +def createVmapFile(aMacroDictionary,aOutputfile): + if not os.path.exists(os.path.dirname(aOutputfile)): + os.makedirs(os.path.dirname(aOutputfile)) + try: + vmapfile = open(aOutputfile,'w') + except IOError: + error("Cannot write to " + aOutputfile) + i = 0 + while i < len(aMacroDictionary['FEATURENAME']): + vmapfile.write(aMacroDictionary['FEATURENAME'][i]+"="+aMacroDictionary['VALUE'][i]+"\n") + i += 1 + vmapfile.close() + +def check_exists(thing, filenames): + if not filenames: + error("No %s specified", thing) + return + + if not isinstance(filenames, list): + # we just have a single string + filenames = [filenames] + + for filename in filenames: + if not os.path.exists(filename): + error("The %s '%s' does not exist", thing, filename) + +# Main function, creates the vmap file +def main(): + + try: + global exitCode, printDebug + + # any exceptions make us traceback and exit + + parser = OptionParser(prog = "createvmap.py") + + parser.add_option("-c","--cpploc",action="store",dest="cpplocation",help="Full path of the preprocessor") + parser.add_option("-d","--debug",action="store_true",default=False,dest="debug",help="Turn debug information on") + parser.add_option("-D","--define",action="append",dest="defines",help="Macro definition") + parser.add_option("-f","--featurelist",action="append",dest="featurelistfile",help="List of featureslist files") + parser.add_option("-o","--output",action="store",dest="outputvmapfile",help="Output VMAP file name") + parser.add_option("-p","--preinclude",action="store",dest="preinclude",help="Pre-include file ") + parser.add_option("-s","--source",action="append",dest="sourcefiles",help="List of source files") + parser.add_option("-u","--userinc",action="append",dest="user_include",help="User Include Folders") + parser.add_option("-x","--systeminc",action="append",dest="system_include",help="System Include Folders") + + (options, leftover_args) = parser.parse_args(sys.argv[1:]) + + if leftover_args: + for invalids in leftover_args: + warning("Unknown parameter '%s'" % invalids) + + printDebug = options.debug + debug("Source Files -> %s", options.sourcefiles) + debug("Macro defines -> %s", options.defines) + debug("Features Files -> %s", options.featurelistfile) + debug("Pre-Include File -> %s", options.preinclude) + debug("User Includes -> %s", options.user_include) + debug("System Includes -> %s", options.system_include) + debug("CPP Location -> %s", options.cpplocation) + debug("VMAP Output name -> %s", options.outputvmapfile) + + featurelist = [] + definelist = "" + user_includeslist = "" + system_includeslist = "" + includeslist = "" + + # Some error checking code + if not options.outputvmapfile: + error("No output vmap file name supplied") + + # Source files must be supplied + check_exists("source file", options.sourcefiles) + + # A valid preinclude file must be supplied + check_exists("pre-include file", options.preinclude) + + # Some feature lists are required + check_exists("feature list", options.featurelistfile) + + # A cpp tool is required + check_exists("cpp tool", options.cpplocation) + + # if an essential option was missing then we should stop now + if exitCode != 0: + sys.exit(exitCode) + + # macro definitions + if options.defines: + for macro in options.defines: + definelist += " -D" + macro.replace('__SBS__QUOTE__', '\\"') + + # Note that we have to use -isystem for user includes and system + # includes to match what happens in the compiler. Long story. + + # Add each source directory as a user-include, so that our temporary + # concatenated source file can find includes that were next to the + # original source files. + # Check that all the specified source files exist + # and collect a set of all the source directories + sourcedirs = set() + for src in options.sourcefiles: + sourcedirs.add(os.path.dirname(src)) + + for srcdir in sourcedirs: + user_includeslist += " -isystem " + srcdir + + # Convert the include list to a string to be passed to cpp + if options.user_include: + for userinc in options.user_include: + user_includeslist += " -isystem " + userinc + if options.system_include: + for sysinc in options.system_include: + system_includeslist += " -isystem " + sysinc + + includeslist = user_includeslist + system_includeslist + + # Get a list of all the features, from all the featurelist files + featurelist = getFeatures(options.featurelistfile) + + # concatenate the source files together into a temporary file + try: + (tempfd, tempname) = tempfile.mkstemp() + temp = os.fdopen(tempfd, "w") + for src in options.sourcefiles: + sfile = open(src, "r") + for sline in sfile: + temp.write(sline) + sfile.close() + temp.close() + except Exception,e: + error("Could not write source files into temporary file %s : %s" % (tempname, str(e))) + return 1 + + debug("Temporary file name : " + tempname) + + # extract the macros from the concatenated source files + macro_dictionary = getVariationFeatures(featurelist, + options.preinclude, + tempname, + options.cpplocation, + definelist, + includeslist) + debug("Macros extracted:") + for key,values in macro_dictionary.iteritems(): + debug(key + " " + str(values)) + + # if there were no macros then the vmap file will be empty... + if not macro_dictionary['FEATURENAME']: + warning("No feature macros were found in the source") + + # Get rid of the temporary file + try: + os.remove(tempname) + except: + error("Could not delete temporary %s" % tempname) + + createVmapFile(macro_dictionary, options.outputvmapfile) + + # exit with 0 if OK + return exitCode + + except Exception,ex: + traceback.print_exc() + return 1 + +if __name__ == "__main__": + sys.exit(main()) +