diff -r 86356a777616 -r cf0c187b284a sbsv2/raptor/python/raptor_meta.py --- a/sbsv2/raptor/python/raptor_meta.py Mon Nov 16 12:59:20 2009 +0000 +++ b/sbsv2/raptor/python/raptor_meta.py Mon Dec 14 18:19:38 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): @@ -284,9 +297,8 @@ def call(self, aArgs, sourcefilename): """ Override call so that we can do our own error handling.""" tool = self._ExternalTool__Tool + commandline = tool + " " + aArgs + " " + str(sourcefilename) try: - commandline = tool + " " + aArgs + " " + str(sourcefilename) - # the actual call differs between Windows and Unix if raptor_utilities.getOSFileSystem() == "unix": p = subprocess.Popen(commandline, \ @@ -332,7 +344,7 @@ raise MetaDataError("Errors in %s" % str(sourcefilename)) except Exception,e: - raise MetaDataError("Preprocessor exception: %s" % str(e)) + raise MetaDataError("Preprocessor exception: '%s' : in command : '%s'" % (str(e), commandline)) return 0 # all OK @@ -398,11 +410,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 +424,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 +451,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 +530,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 +895,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 +1211,9 @@ 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.ApplyVariants = [] self.ResourceVariants = [] self.BitmapVariants = [] self.StringTableVariants = [] @@ -1208,11 +1227,12 @@ self.__systeminclude = "" self.__bitmapSourcepath = self.__sourcepath self.__current_resource = "" - self.__capabilities = [] self.__resourceFiles = [] self.__pageConflict = [] self.__debuggable = "" + self.__compressionKeyword = "" self.sources = [] + self.capabilities = [] self.__TARGET = "" self.__TARGETEXT = "" @@ -1338,6 +1358,14 @@ elif varname == 'FEATUREVARIANT': self.BuildVariant.AddOperation(raptor_data.Set(varname,"1")) self.featureVariant = True + elif varname in ['COMPRESSTARGET', 'NOCOMPRESSTARGET', 'INFLATECOMPRESSTARGET', 'BYTEPAIRCOMPRESSTARGET']: + if self.__compressionKeyword: + self.__Raptor.Warn("%s keyword in %s overrides earlier use of %s" % (varname, self.__currentMmpFile, self.__compressionKeyword)) + self.BuildVariant.AddOperation(raptor_data.Set(self.__compressionKeyword,"")) + self.__debug( "Set switch " + varname + " OFF") + self.BuildVariant.AddOperation(raptor_data.Set(varname,"1")) + self.__debug( "Set switch " + varname + " ON") + self.__compressionKeyword = varname else: self.__debug( "Set switch "+toks[0]+" ON") self.BuildVariant.AddOperation(raptor_data.Set(prefix+varname, "1")) @@ -1423,9 +1451,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] @@ -1450,8 +1477,10 @@ # add in the minor number minor = 0 - if len(version) > 1 and version[2] is not None: + if version[1] is not None: minor = int(version[2],10) + else: + self.__Raptor.Warn("VERSION (%s) missing '.minor' in %s, using '.0'" % (toks[1],self.__currentMmpFile)) self.__versionhex = "%04x%04x" % (major, minor) self.BuildVariant.AddOperation(raptor_data.Set(varname, "%d.%d" %(major, minor))) @@ -1517,7 +1546,8 @@ toks1 = re.sub("[,'\[\]]", "", toks1).replace("//","/") self.__debug("Set "+toks[0]+" to " + toks1) self.BuildVariant.AddOperation(raptor_data.Set(varname,toks1)) - + elif varname=='APPLY': + self.ApplyVariants.append(toks[1]) else: self.__debug("Set "+toks[0]+" to " + str(toks[1])) self.BuildVariant.AddOperation(raptor_data.Set(varname,"".join(toks[1]))) @@ -1765,7 +1795,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 @@ -1884,7 +1914,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 @@ -1974,7 +2004,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 @@ -2167,11 +2197,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('-'): @@ -2283,6 +2316,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. @@ -2299,10 +2358,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 = {} @@ -2321,24 +2380,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: @@ -2350,11 +2410,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 @@ -2369,19 +2429,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 @@ -2452,20 +2511,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, doexport, dobuild = True): """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 @@ -2475,7 +2522,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']: @@ -2486,7 +2533,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']: @@ -2502,18 +2549,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 [] @@ -2545,20 +2592,23 @@ # before we can do anything else (because raptor itself must do # some exports before the MMP files that include them can be # processed). - for i,p in enumerate(exportNodes): - exportPlatform = self.ExportPlatforms[i] - for s in p.GetChildSpecs(): - try: - self.ProcessExports(s, exportPlatform) - - except MetaDataError, e: - self.__Raptor.Error("%s",e.Text) - if not self.__Raptor.keepGoing: - return [] + if doexport: + for i,p in enumerate(exportNodes): + exportPlatform = self.ExportPlatforms[i] + for s in p.GetChildSpecs(): + try: + self.ProcessExports(s, exportPlatform) + + except MetaDataError, e: + self.__Raptor.Error("%s",e.Text) + if not self.__Raptor.keepGoing: + return [] + else: + self.__Raptor.Info("Not Processing Exports (--noexport enabled)") # this is a switch to return the function at this point if export # only option is specified in the run - if (self.__Raptor.doExportOnly): + if dobuild is not True: self.__Raptor.Info("Processing Exports only") return[] @@ -2601,8 +2651,8 @@ def LeftPortionOf(pth,sep): """ Internal function to return portion of str that is to the left of sep. - The partition is case-insentive.""" - length = len((pth.lower().partition(sep.lower()))[0]) + The split is case-insensitive.""" + length = len((pth.lower().split(sep.lower()))[0]) return pth[0:length] modulePath = LeftPortionOf(LeftPortionOf(os.path.dirname(aBldInfPath), "group"), "ongoing") @@ -2615,74 +2665,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. @@ -2694,18 +2748,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() @@ -2728,7 +2782,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']), @@ -2876,6 +2929,11 @@ expfile = open(expfilename, 'wb') expfile.write(exportzip.read(file)) expfile.close() + + # Resurrect any file execution permissions present in the archived version + if (exportzip.getinfo(file).external_attr >> 16L) & 0100: + os.chmod(expfilename, stat.S_IMODE(os.stat(expfilename).st_mode) | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) + # Each file keeps its modified time the same as what it was before unzipping accesstime = time.time() datetime = exportzip.getinfo(file).date_time @@ -2915,12 +2973,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: @@ -2999,14 +3057,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: @@ -3024,7 +3088,8 @@ mmpFile = MMPFile(foundmmpfile, self.__gnucpp, - bldinf = componentNode.bldinf, + component.bldinf, + component.depfiles, log = self.__Raptor) mmpFilename = mmpFile.filename @@ -3058,7 +3123,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))) @@ -3094,7 +3159,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]) @@ -3107,6 +3172,16 @@ # now we have something worth adding to the component mmpSpec.AddVariant(var) componentNode.AddChild(mmpSpec) + + # if there are APPLY variants then add them to the mmpSpec too + for applyVar in backend.ApplyVariants: + try: + mmpSpec.AddVariant(self.__Raptor.cache.FindNamedVariant(applyVar)) + except KeyError: + self.__Raptor.Error("APPLY unknown variant '%s' in %s", + applyVar, + str(mmpFileEntry.filename), + bldinf=str(bldInfFile)) # resources, stringtables and bitmaps are sub-nodes of this project # (do not add these for feature variant builds) @@ -3150,7 +3225,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"] @@ -3182,7 +3257,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"] @@ -3203,17 +3278,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