diff -r e1eecf4d390d -r 593a8820b912 sbsv2/raptor/python/raptor_meta.py --- a/sbsv2/raptor/python/raptor_meta.py Mon Nov 16 09:46:46 2009 +0000 +++ b/sbsv2/raptor/python/raptor_meta.py Mon Nov 16 20:39:37 2009 +0000 @@ -232,6 +232,19 @@ return commentDetail +def getSpecName(aFileRoot, fullPath=False): + """Returns a build spec name: this is the file root (full path + or simple file name) made safe for use as a file name.""" + + if fullPath: + specName = str(aFileRoot).replace("/","_") + specName = specName.replace(":","") + else: + specName = aFileRoot.File() + + return specName.lower() + + # Classes class MetaDataError(Exception): @@ -398,11 +411,13 @@ on the selected build platform. This class provides a generic means of wrapping up the preprocessing of such files.""" - def __init__(self, aFilename, gnucpp, aRootLocation=None, log=None): + def __init__(self, aFilename, gnucpp, depfiles, aRootLocation=None, log=None): """ @param aFilename An MMP, bld.inf or other preprocessable build spec file @param aDefaultPlatform Default preprocessed version of this file @param aCPP location of GNU CPP + @param depfiles list to add dependency file tuples to + @param aRootLocation where the file is @param log A class with Debug(), Info() and Error() methods """ self.filename = aFilename @@ -410,6 +425,7 @@ # Dictionary with key of build platform and a text string of processed output as values self.__PreProcessedContent = {} self.log = log + self.depfiles = depfiles self.__gnucpp = gnucpp if gnucpp is None: @@ -436,7 +452,7 @@ else: metatarget = "'$(PARSETARGET)'" generateDepsOptions = "-MD -MF%s -MT%s" % (adepfilename, metatarget) - aBuildPlatform['METADEPS'].append((adepfilename, metatarget)) + self.depfiles.append((adepfilename, metatarget)) try: os.makedirs(os.path.dirname(adepfilename)) except Exception, e: @@ -515,15 +531,17 @@ on the selected build platform. This class provides a generic means of wrapping up the preprocessing of such files.""" - def __init__(self, aFilename, gnucpp, bldinf, log=None): + def __init__(self, aFilename, gnucpp, bldinf, depfiles, log=None): """ @param aFilename An MMP, bld.inf or other preprocessable build spec file @param gnucpp location of GNU CPP - @param bldinf the bldinf file that this mmp comes from - @param log A class with Debug(), Info() and Error() methods + @param bldinf the bld.inf file this mmp was specified in + @param depfiles list to fill with mmp dependency files + @param log A class with Debug(), Info() and Error() methods """ - super(MMPFile, self).__init__(aFilename, gnucpp, str(bldinf.filename.Dir()), log) + super(MMPFile, self).__init__(aFilename, gnucpp, depfiles, str(bldinf.filename.Dir()), log) self.__bldinf = bldinf + self.depfiles = depfiles self.__gnucpp = gnucpp if gnucpp is None: @@ -878,8 +896,8 @@ class BldInfFile(MetaDataFile): """Representation of a Symbian bld.inf file""" - def __init__(self, aFilename, gnucpp, log=None): - MetaDataFile.__init__(self, aFilename, gnucpp, None, log) + def __init__(self, aFilename, gnucpp, depfiles, log=None): + MetaDataFile.__init__(self, aFilename, gnucpp, depfiles, None, log) self.__Raptor = log self.testManual = 0 self.testAuto = 0 @@ -1194,7 +1212,8 @@ super(MMPRaptorBackend,self).__init__() self.platformblock = None self.__Raptor = aRaptor - self.BuildVariant = raptor_data.Variant() + self.__debug("-----+++++ %s " % aMmpfilename) + self.BuildVariant = raptor_data.Variant(name = "mmp") self.ResourceVariants = [] self.BitmapVariants = [] self.StringTableVariants = [] @@ -1208,11 +1227,11 @@ self.__systeminclude = "" self.__bitmapSourcepath = self.__sourcepath self.__current_resource = "" - self.__capabilities = [] - self.__resourceFiles = [] self.__pageConflict = [] self.__debuggable = "" + self.__resourceFiles = [] self.sources = [] + self.capabilities = [] self.__TARGET = "" self.__TARGETEXT = "" @@ -1423,9 +1442,8 @@ elif varname=='CAPABILITY': for cap in toks[1]: - self.BuildVariant.AddOperation(raptor_data.Append(varname,cap," ")) self.__debug("Setting "+toks[0]+": " + cap) - self.__capabilities.append(cap.lower()) + self.capabilities.append(cap) elif varname=='DEFFILE': self.__defFileRoot = self.__currentMmpFile self.deffile = toks[1] @@ -1767,7 +1785,7 @@ replace = "" if len(matches): replace = matches.pop() - + searchReplacePairs.append('%s<->%s' % (search, replace)) # Replace spaces to maintain word-based grouping in downstream makefile lists @@ -1886,7 +1904,7 @@ self.__currentLineNumber += 1 self.__debug("Start BITMAP "+toks[1]) - self.__currentBitmapVariant = raptor_data.Variant(toks[1].replace('.','_')) + self.__currentBitmapVariant = raptor_data.Variant(name = toks[1].replace('.','_')) # Use BMTARGET and BMTARGET_lower because that prevents # confusion with the TARGET and TARGET_lower of our parent MMP # when setting the OUTPUTPATH. This in turn allows us to @@ -1976,7 +1994,7 @@ self.__debug("stringtable: " + toks[1]) self.__debug("adjusted stringtable source=" + source) - self.__currentStringTableVariant = raptor_data.Variant(uniqname) + self.__currentStringTableVariant = raptor_data.Variant(name = uniqname) self.__currentStringTableVariant.AddOperation(raptor_data.Set("SOURCE", source)) self.__currentStringTableVariant.AddOperation(raptor_data.Set("EXPORTPATH", "")) self.__stringtableExported = False @@ -2169,11 +2187,14 @@ self.ResourceVariants[i].AddOperation(raptor_data.Set("MAIN_TARGET_lower", self.__TARGET.lower())) self.ResourceVariants[i].AddOperation(raptor_data.Set("MAIN_REQUESTEDTARGETEXT", self.__TARGETEXT.lower())) + # Create Capability variable in one SET operation (more efficient than multiple appends) + self.BuildVariant.AddOperation(raptor_data.Set("CAPABILITY"," ".join(self.capabilities))) + # Resolve combined capabilities as hex flags, for configurations that require them capabilityFlag1 = 0 capabilityFlag2 = 0 # Always 0 - for capability in self.__capabilities: + for capability in [c.lower() for c in self.capabilities]: invert = 0 if capability.startswith('-'): @@ -2285,6 +2306,32 @@ return resolvedDefFile +def CheckedGet(self, key, default = None): + """extract a value from an self and raise an exception if None. + + An optional default can be set to replace a None value. + + This function belongs in the Evaluator class logically. But + Evaluator doesn't know how to raise a Metadata error. Since + being able to raise a metadata error is the whole point of + the method, it makes sense to adapt the Evaluator class from + raptor_meta for the use of everything inside raptor_meta. + + ... so it will be added to the Evaluator class. + """ + + value = self.Get(key) + if value == None: + if default == None: + raise MetaDataError("configuration " + self.buildUnit.name + + " has no variable " + key) + else: + return default + return value + +raptor_data.Evaluator.CheckedGet = CheckedGet + + class MetaReader(object): """Entry point class for Symbian metadata processing. @@ -2301,10 +2348,10 @@ # Get the version of CPP that we are using metadata = self.__Raptor.cache.FindNamedVariant("meta") evaluator = self.__Raptor.GetEvaluator(None, raptor_data.BuildUnit(metadata.name, [metadata]) ) - self.__gnucpp = self.CheckValue(evaluator, "GNUCPP") - self.__defaultplatforms = self.CheckValue(evaluator, "DEFAULT_PLATFORMS") - self.__basedefaultplatforms = self.CheckValue(evaluator, "BASE_DEFAULT_PLATFORMS") - self.__baseuserdefaultplatforms = self.CheckValue(evaluator, "BASE_USER_DEFAULT_PLATFORMS") + self.__gnucpp = evaluator.CheckedGet("GNUCPP") + self.__defaultplatforms = evaluator.CheckedGet("DEFAULT_PLATFORMS") + self.__basedefaultplatforms = evaluator.CheckedGet("BASE_DEFAULT_PLATFORMS") + self.__baseuserdefaultplatforms = evaluator.CheckedGet("BASE_USER_DEFAULT_PLATFORMS") # Only read each variant.cfg once variantCfgs = {} @@ -2323,24 +2370,25 @@ # with the same "export platform". exports = {} + self.__Raptor.Debug("MetaReader: configsToBuild: %s", [b.name for b in configsToBuild]) for buildConfig in configsToBuild: # get everything we need to know about the configuration evaluator = self.__Raptor.GetEvaluator(None, buildConfig) detail = {} - detail['PLATFORM'] = self.CheckValue(evaluator, "TRADITIONAL_PLATFORM") - epocroot = self.CheckValue(evaluator, "EPOCROOT") + detail['PLATFORM'] = evaluator.CheckedGet("TRADITIONAL_PLATFORM") + epocroot = evaluator.CheckedGet("EPOCROOT") detail['EPOCROOT'] = generic_path.Path(epocroot) - sbs_build_dir = self.CheckValue(evaluator, "SBS_BUILD_DIR") + sbs_build_dir = evaluator.CheckedGet("SBS_BUILD_DIR") detail['SBS_BUILD_DIR'] = generic_path.Path(sbs_build_dir) - flm_export_dir = self.CheckValue(evaluator, "FLM_EXPORT_DIR") + flm_export_dir = evaluator.CheckedGet("FLM_EXPORT_DIR") detail['FLM_EXPORT_DIR'] = generic_path.Path(flm_export_dir) detail['CACHEID'] = flm_export_dir if raptor_utilities.getOSPlatform().startswith("win"): - detail['PLATMACROS'] = self.CheckValue(evaluator,"PLATMACROS.WINDOWS") + detail['PLATMACROS'] = evaluator.CheckedGet("PLATMACROS.WINDOWS") else: - detail['PLATMACROS'] = self.CheckValue(evaluator,"PLATMACROS.LINUX") + detail['PLATMACROS'] = evaluator.CheckedGet("PLATMACROS.LINUX") # Apply OS variant provided we are not ignoring this if not self.__Raptor.ignoreOsDetection: @@ -2352,11 +2400,11 @@ # is this a feature variant config or an ordinary variant fv = evaluator.Get("FEATUREVARIANTNAME") if fv: - variantHdr = self.CheckValue(evaluator, "VARIANT_HRH") + variantHdr = evaluator.CheckedGet("VARIANT_HRH") variantHRH = generic_path.Path(variantHdr) detail['ISFEATUREVARIANT'] = True else: - variantCfg = self.CheckValue(evaluator, "VARIANT_CFG") + variantCfg = evaluator.CheckedGet("VARIANT_CFG") variantCfg = generic_path.Path(variantCfg) if not variantCfg in variantCfgs: # get VARIANT_HRH from the variant.cfg file @@ -2371,19 +2419,18 @@ detail['VARIANT_HRH'] = variantHRH self.__Raptor.Info("'%s' uses variant hrh file '%s'", buildConfig.name, variantHRH) - detail['SYSTEMINCLUDE'] = self.CheckValue(evaluator, "SYSTEMINCLUDE") - - detail['METADEPS'] = [] # Dependency targets for all metadata files in this platform + detail['SYSTEMINCLUDE'] = evaluator.CheckedGet("SYSTEMINCLUDE") + # find all the interface names we need - ifaceTypes = self.CheckValue(evaluator, "INTERFACE_TYPES") + ifaceTypes = evaluator.CheckedGet("INTERFACE_TYPES") interfaces = ifaceTypes.split() for iface in interfaces: - detail[iface] = self.CheckValue(evaluator, "INTERFACE." + iface) + detail[iface] = evaluator.CheckedGet("INTERFACE." + iface) # not test code unless positively specified - detail['TESTCODE'] = self.CheckValue(evaluator, "TESTCODE", "") + detail['TESTCODE'] = evaluator.CheckedGet("TESTCODE", "") # make a key that identifies this platform uniquely # - used to tell us whether we have done the pre-processing @@ -2454,20 +2501,8 @@ # that are supposedly platform independent (e.g. PRJ_PLATFORMS) self.defaultPlatform = self.ExportPlatforms[0] - def CheckValue(self, evaluator, key, default = None): - """extract a value from an evaluator and raise an exception if None. - - An optional default can be set to replace a None value.""" - value = evaluator.Get(key) - if value == None: - if default == None: - raise MetaDataError("configuration " + evaluator.config.name + - " has no variable " + key) - else: - return default - return value - - def ReadBldInfFiles(self, aFileList, doExportOnly): + + def ReadBldInfFiles(self, aComponentList, doExportOnly): """Take a list of bld.inf files and return a list of build specs. The returned specification nodes will be suitable for all the build @@ -2477,7 +2512,7 @@ # we need a Filter node per export platform exportNodes = [] for i,ep in enumerate(self.ExportPlatforms): - filter = raptor_data.Filter("export_" + str(i)) + filter = raptor_data.Filter(name = "export_" + str(i)) # what configurations is this node active for? for config in ep['configs']: @@ -2488,7 +2523,7 @@ # we need a Filter node per build platform platformNodes = [] for i,bp in enumerate(self.BuildPlatforms): - filter = raptor_data.Filter("build_" + str(i)) + filter = raptor_data.Filter(name = "build_" + str(i)) # what configurations is this node active for? for config in bp['configs']: @@ -2504,18 +2539,18 @@ # check that each bld.inf exists and add a Specification node for it # to the nodes of the export and build platforms that it supports. - for bif in aFileList: - if bif.isFile(): - self.__Raptor.Info("Processing %s", str(bif)) + for c in aComponentList: + if c.bldinf_filename.isFile(): + self.__Raptor.Info("Processing %s", str(c.bldinf_filename)) try: - self.AddComponentNodes(bif, exportNodes, platformNodes) + self.AddComponentNodes(c, exportNodes, platformNodes) except MetaDataError, e: - self.__Raptor.Error(e.Text, bldinf=str(bif)) + self.__Raptor.Error(e.Text, bldinf=str(c.bldinf_filename)) if not self.__Raptor.keepGoing: return [] else: - self.__Raptor.Error("build info file does not exist", bldinf=str(bif)) + self.__Raptor.Error("build info file does not exist", bldinf=str(c.bldinf_filename)) if not self.__Raptor.keepGoing: return [] @@ -2617,74 +2652,78 @@ return moduleName - def AddComponentNodes(self, buildFile, exportNodes, platformNodes): + def AddComponentNodes(self, component, exportNodes, platformNodes): """Add Specification nodes for a bld.inf to the appropriate platforms.""" - bldInfFile = BldInfFile(buildFile, self.__gnucpp, self.__Raptor) - - specName = self.getSpecName(buildFile, fullPath=True) - - if isinstance(buildFile, raptor_xml.SystemModelComponent): + bldInfFile = BldInfFile(component.bldinf_filename, self.__gnucpp, component.depfiles, self.__Raptor) + component.bldinf = bldInfFile + + specName = getSpecName(component.bldinf_filename, fullPath=True) + + if isinstance(component.bldinf, raptor_xml.SystemModelComponent): # this component came from a system_definition.xml - layer = buildFile.GetContainerName("layer") - component = buildFile.GetContainerName("component") + layer = component.bldinf.GetContainerName("layer") + componentName = component.bldinf.GetContainerName("component") else: # this is a plain old bld.inf file from the command-line layer = "" - component = "" + componentName = "" # exports are independent of build platform for i,ep in enumerate(self.ExportPlatforms): - specNode = raptor_data.Specification(specName) + specNode = raptor_data.Specification(name = specName) # keep the BldInfFile object for later - specNode.bldinf = bldInfFile + specNode.component = component # add some basic data in a component-wide variant - var = raptor_data.Variant() - var.AddOperation(raptor_data.Set("COMPONENT_META", str(buildFile))) - var.AddOperation(raptor_data.Set("COMPONENT_NAME", component)) + var = raptor_data.Variant(name='component-wide') + var.AddOperation(raptor_data.Set("COMPONENT_META", str(component.bldinf_filename))) + var.AddOperation(raptor_data.Set("COMPONENT_NAME", componentName)) var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer)) specNode.AddVariant(var) # add this bld.inf Specification to the export platform exportNodes[i].AddChild(specNode) + component.exportspecs.append(specNode) # get the relevant build platforms listedPlatforms = bldInfFile.getBuildPlatforms(self.defaultPlatform) platforms = getBuildableBldInfBuildPlatforms(listedPlatforms, - self.__defaultplatforms, - self.__basedefaultplatforms, - self.__baseuserdefaultplatforms) - - - - outputDir = BldInfFile.outputPathFragment(buildFile) + self.__defaultplatforms, + self.__basedefaultplatforms, + self.__baseuserdefaultplatforms) + + + outputDir = BldInfFile.outputPathFragment(component.bldinf_filename) # Calculate "module name" - modulename = self.ModuleName(str(buildFile)) + modulename = self.ModuleName(str(component.bldinf_filename)) for i,bp in enumerate(self.BuildPlatforms): + plat = bp['PLATFORM'] if bp['PLATFORM'] in platforms: - specNode = raptor_data.Specification(specName) - - # keep the BldInfFile object for later - specNode.bldinf = bldInfFile + specNode = raptor_data.Specification(name = specName) + + # remember what component this spec node comes from for later + specNode.component = component # add some basic data in a component-wide variant - var = raptor_data.Variant() - var.AddOperation(raptor_data.Set("COMPONENT_META",str(buildFile))) - var.AddOperation(raptor_data.Set("COMPONENT_NAME", component)) + var = raptor_data.Variant(name='component-wide-settings-' + plat) + var.AddOperation(raptor_data.Set("COMPONENT_META",str(component.bldinf_filename))) + var.AddOperation(raptor_data.Set("COMPONENT_NAME", componentName)) var.AddOperation(raptor_data.Set("COMPONENT_LAYER", layer)) var.AddOperation(raptor_data.Set("MODULE", modulename)) var.AddOperation(raptor_data.Append("OUTPUTPATHOFFSET", outputDir, '/')) var.AddOperation(raptor_data.Append("OUTPUTPATH", outputDir, '/')) var.AddOperation(raptor_data.Append("BLDINF_OUTPUTPATH",outputDir, '/')) - var.AddOperation(raptor_data.Set("TEST_OPTION", specNode.bldinf.getRomTestType(bp))) + var.AddOperation(raptor_data.Set("TEST_OPTION", component.bldinf.getRomTestType(bp))) specNode.AddVariant(var) # add this bld.inf Specification to the build platform platformNodes[i].AddChild(specNode) + # also attach it into the component + component.specs.append(specNode) def ProcessExports(self, componentNode, exportPlatform): """Do the exports for a given platform and skeleton bld.inf node. @@ -2696,18 +2735,18 @@ [some MMP files #include exported .mmh files] """ if exportPlatform["TESTCODE"]: - exports = componentNode.bldinf.getTestExports(exportPlatform) + exports = componentNode.component.bldinf.getTestExports(exportPlatform) else: - exports = componentNode.bldinf.getExports(exportPlatform) + exports = componentNode.component.bldinf.getExports(exportPlatform) self.__Raptor.Debug("%i exports for %s", - len(exports), str(componentNode.bldinf.filename)) + len(exports), str(componentNode.component.bldinf.filename)) if exports: # each export is either a 'copy' or 'unzip' # maybe we should trap multiple exports to the same location here? epocroot = str(exportPlatform["EPOCROOT"]) - bldinf_filename = str(componentNode.bldinf.filename) + bldinf_filename = str(componentNode.component.bldinf.filename) exportwhatlog="\n" % bldinf_filename for export in exports: expSrc = export.getSource() @@ -2730,7 +2769,6 @@ # export the file exportwhatlog += self.CopyExport(fromFile, toFile, bldinf_filename) else: - # unzip the zip exportwhatlog += ("\n") members = self.UnzipExport(fromFile, toFile, str(exportPlatform['SBS_BUILD_DIR']), @@ -2917,12 +2955,12 @@ return # feature variation does not run extensions at all if buildPlatform["TESTCODE"]: - extensions = componentNode.bldinf.getTestExtensions(buildPlatform) + extensions = componentNode.component.bldinf.getTestExtensions(buildPlatform) else: - extensions = componentNode.bldinf.getExtensions(buildPlatform) + extensions = componentNode.component.bldinf.getExtensions(buildPlatform) self.__Raptor.Debug("%i template extension makefiles for %s", - len(extensions), str(componentNode.bldinf.filename)) + len(extensions), str(componentNode.component.bldinf.filename)) for i,extension in enumerate(extensions): if self.__Raptor.projects: @@ -3001,14 +3039,20 @@ gnuList = [] makefileList = [] + + component = componentNode.component + + if buildPlatform["TESTCODE"]: - MMPList = componentNode.bldinf.getTestMMPList(buildPlatform) + MMPList = component.bldinf.getTestMMPList(buildPlatform) else: - MMPList = componentNode.bldinf.getMMPList(buildPlatform) - - bldInfFile = componentNode.bldinf.filename + MMPList = component.bldinf.getMMPList(buildPlatform) + + bldInfFile = component.bldinf.filename for mmpFileEntry in MMPList['mmpFileList']: + component.AddMMP(mmpFileEntry.filename) # Tell the component another mmp is specified (for this platform) + projectname = mmpFileEntry.filename.File().lower() if self.__Raptor.projects: @@ -3026,7 +3070,8 @@ mmpFile = MMPFile(foundmmpfile, self.__gnucpp, - bldinf = componentNode.bldinf, + component.bldinf, + component.depfiles, log = self.__Raptor) mmpFilename = mmpFile.filename @@ -3060,7 +3105,7 @@ continue # now build the specification tree - mmpSpec = raptor_data.Specification(self.getSpecName(mmpFilename)) + mmpSpec = raptor_data.Specification(generic_path.Path(getSpecName(mmpFilename))) var = backend.BuildVariant var.AddOperation(raptor_data.Set("PROJECT_META", str(mmpFilename))) @@ -3096,7 +3141,7 @@ # Although not part of the MMP, some MMP-based build specs additionally require knowledge of their # container bld.inf exported headers - for export in componentNode.bldinf.getExports(buildPlatform): + for export in componentNode.component.bldinf.getExports(buildPlatform): destination = export.getDestination() if isinstance(destination, list): exportfile = str(destination[0]) @@ -3152,7 +3197,7 @@ self.projectList.remove(projectname) self.__Raptor.Debug("%i gnumakefile extension makefiles for %s", - len(gnuList), str(componentNode.bldinf.filename)) + len(gnuList), str(componentNode.component.bldinf.filename)) var = raptor_data.Variant() gnuSpec = raptor_data.Specification("gnumakefile " + str(g.getMakefileName())) interface = buildPlatform["ext_makefile"] @@ -3184,7 +3229,7 @@ projectList.remove(projectname) self.__Raptor.Debug("%i makefile extension makefiles for %s", - len(makefileList), str(componentNode.bldinf.filename)) + len(makefileList), str(componentNode.component.bldinf.filename)) var = raptor_data.Variant() gnuSpec = raptor_data.Specification("makefile " + str(m.getMakefileName())) interface = buildPlatform["ext_makefile"] @@ -3205,17 +3250,6 @@ gnuSpec.AddVariant(var) componentNode.AddChild(gnuSpec) - def getSpecName(self, aFileRoot, fullPath=False): - """Returns a build spec name: this is the file root (full path - or simple file name) made safe for use as a file name.""" - - if fullPath: - specName = str(aFileRoot).replace("/","_") - specName = specName.replace(":","") - else: - specName = aFileRoot.File() - - return specName.lower() def ApplyOSVariant(self, aBuildUnit, aEpocroot): # Form path to kif.xml and path to buildinfo.txt