# HG changeset patch
# User timothy.murphy@nokia.com
# Date 1264012113 0
# Node ID df63379a03bda3b9b183cdca12697734b247b7ae
# Parent 4afe202ba8fa16508cd6dc3361d340c550339d50# Parent a00bdef52597fe8e948e47277149a12cd70d55d8
Merge: installer stuff
diff -r a00bdef52597 -r df63379a03bd sbsv2/raptor/RELEASE-NOTES.txt
--- a/sbsv2/raptor/RELEASE-NOTES.txt Wed Jan 20 13:46:39 2010 +0000
+++ b/sbsv2/raptor/RELEASE-NOTES.txt Wed Jan 20 18:28:33 2010 +0000
@@ -3,32 +3,59 @@
Next version
-- Combine Linking and Postlinking into a single step
+
+New Features:
- New 'Patchable Constants' target type: TARGETTYPE pdll
-- Support exit codes from next version of the trace compiler which will issue them
+- Combine Linking and Postlinking into a single step - performance improvement.
+- Support exit codes from next version of the trace compiler which will issue
+ them
- New sbs_filter script and batchfile to ease the use of sbs_filter.py.
- Allows filters to be executed over a log after a build has been done.
+ Allows filters to be executed over a log after a build has been done.
e.g.
+
sbs_filter --filters=FilterWhat < logfile.log
+
(This runs a "--what" without regenerating any makefiles or reparsing
the matadata.)
- New (beta) FilterWhatComp filter. Simulates abld log output for
- use with parse_what.pl for packing up zips by component. Whatcomp output
- uses the incoming epocroot value. i.e. if epocroot is relative then so is
- the what output. e.g. if EPOCROOT=\ then the output will be of the form
- "\epoc32\release\armv5\...." If it's "..\myepocroot" then the output will
- be "..\myepocroot\epoc32\release\armv5". If it's absolute then the what
- output will also be absolute.
+ use with parse_what.pl for packing up zips by component. Whatcomp output
+ uses the incoming epocroot value. i.e. if epocroot is relative then so is
+ the what output. e.g. if EPOCROOT=\ then the output will be of the form:
+
+ "\epoc32\release\armv5\...."
+
+ If it's "..\myepocroot" then the output will be:
+
+ "..\myepocroot\epoc32\release\armv5".
+
+ If it's absolute then the what output will also be absolute.
- New FilterCheck filter. This can be used with sbs_filter to perform the
- equivalent of --check using the log output from a build. It is more
- efficient than --check because the metadata is not parsed and no makefiles
- are generated. e.g.
- sbs_filter --filters=FilterCheck < logfile.log
-- New (beta) graphical build visualisation tool (bin/timelines.py). Requires pygame
- and PyOpenGL. e.g. python timelines.py < filename.log
-- New (beta) log analyser (recipestats.py) for recording the total time spent in
- each type of recipe in the build. e.g. python recipestats.py < filename.log > stats.csv
- The output is in CSV format.
+ equivalent of --check using the log output from a build. It is more
+ efficient than --check because the metadata is not parsed and no makefiles
+ are generated. e.g.
+
+ sbs_filter --filters=FilterCheck < logfile.log
+
+- New (beta) graphical build visualisation tool (bin/timelines.py).
+ Requires pygame and PyOpenGL. e.g.
+
+ python timelines.py < filename.log
+
+- New (beta) log analyser (recipestats.py) for recording the total time spent
+ in each type of recipe in the build. e.g.
+
+ python recipestats.py < filename.log > stats.csv
+
+ The output is in CSV format.
+
+Defect Fixes:
+- SF bug 1570: Adding then removing a capability can produce incorrect
+ result: e.g. ALL TCB -TCB becomes ALL -TCB but it should be just ALL
+
+Other Changes:
+- Default to using Python 2.6.4 on windows (no change in compatibility with
+ older versions of Python).
+
diff -r a00bdef52597 -r df63379a03bd sbsv2/raptor/bin/sbs.bat
--- a/sbsv2/raptor/bin/sbs.bat Wed Jan 20 13:46:39 2010 +0000
+++ b/sbsv2/raptor/bin/sbs.bat Wed Jan 20 18:28:33 2010 +0000
@@ -30,9 +30,9 @@
@REM Use the python set by the environment if possible
@SET __PYTHON__=%SBS_PYTHON%
-@IF "%__PYTHON__%"=="" SET __PYTHON__=%SBS_HOME%\win32\python252\python.exe
+@IF "%__PYTHON__%"=="" SET __PYTHON__=%SBS_HOME%\win32\python264\python.exe
@SET PYTHONPATH=%SBS_PYTHONPATH%
-@IF "%PYTHONPATH%"=="" SET PYTHONPATH=%SBS_HOME%\win32\python252
+@IF "%PYTHONPATH%"=="" SET PYTHONPATH=%SBS_HOME%\win32\python264
@REM Use the mingw set by the environment if possible
@SET __MINGW__=%SBS_MINGW%
diff -r a00bdef52597 -r df63379a03bd sbsv2/raptor/lib/config/locations.xml
--- a/sbsv2/raptor/lib/config/locations.xml Wed Jan 20 13:46:39 2010 +0000
+++ b/sbsv2/raptor/lib/config/locations.xml Wed Jan 20 18:28:33 2010 +0000
@@ -72,7 +72,7 @@
-
+
diff -r a00bdef52597 -r df63379a03bd sbsv2/raptor/lib/flm/e32abiv2.flm
--- a/sbsv2/raptor/lib/flm/e32abiv2.flm Wed Jan 20 13:46:39 2010 +0000
+++ b/sbsv2/raptor/lib/flm/e32abiv2.flm Wed Jan 20 18:28:33 2010 +0000
@@ -385,9 +385,7 @@
ifneq ($(DOPOSTLINK),)
# Capabilities
-ADDED_CAPABILITIES:=$(subst $(CHAR_SPACE),+,$(filter-out -%,$(CAPABILITY)))
-SUBTRACTED_CAPABILITIES:=$(subst $(CHAR_SPACE),,$(filter -%,$(CAPABILITY)))
-FINAL_CAPABILITIES:=$(if $(ADDED_CAPABILITIES),$(ADDED_CAPABILITIES)$(SUBTRACTED_CAPABILITIES),NONE)
+FINAL_CAPABILITIES:=$(if $(CAPABILITY),$(CAPABILITY),NONE)
# Paging options for the old postlinker
POSTLINKER_PAGEDOPTION:=--defaultpaged
diff -r a00bdef52597 -r df63379a03bd sbsv2/raptor/python/raptor_meta.py
--- a/sbsv2/raptor/python/raptor_meta.py Wed Jan 20 13:46:39 2010 +0000
+++ b/sbsv2/raptor/python/raptor_meta.py Wed Jan 20 18:28:33 2010 +0000
@@ -1,3307 +1,3315 @@
-#
-# 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:
-# This module includes classes that process bld.inf and .mmp files to
-# generate Raptor build specifications
-#
-
-import copy
-import re
-import os.path
-import shutil
-import stat
-import hashlib
-import base64
-
-import raptor
-import raptor_data
-import raptor_utilities
-import raptor_xml
-import generic_path
-import subprocess
-import zipfile
-from mmpparser import *
-
-import time
-
-
-PiggyBackedBuildPlatforms = {'ARMV5':['GCCXML']}
-
-PlatformDefaultDefFileDir = {'WINSCW':'bwins',
- 'ARMV5' :'eabi',
- 'ARMV5SMP' :'eabi',
- 'GCCXML':'eabi',
- 'ARMV6':'eabi',
- 'ARMV7' : 'eabi',
- 'ARMV7SMP' : 'eabi'}
-
-def getVariantCfgDetail(aEPOCROOT, aVariantCfgFile):
- """Obtain pertinent build related detail from the Symbian variant.cfg file.
-
- This variant.cfg file, usually located relative to $(EPOCROOT), contains:
- (1) The $(EPOCROOT) relative location of the primary .hrh file used to configure the specific OS variant build
- (2) A flag determining whether ARMV5 represents an ABIV1 or ABIV2 build (currently unused by Raptor)."""
-
- variantCfgDetails = {}
- variantCfgFile = None
-
- try:
- variantCfgFile = open(str(aVariantCfgFile))
- except IOError, (number, message):
- raise MetaDataError("Could not read variant configuration file "+str(aVariantCfgFile)+" ("+message+")")
-
- for line in variantCfgFile.readlines():
- if re.search('^(\s$|\s*#)', line):
- continue
- # Note that this detection of the .hrh file matches the command line build i.e. ".hrh" somewhere
- # in the specified line
- elif re.search('\.hrh', line, re.I):
- variantHrh = line.strip()
- if variantHrh.startswith('\\') or variantHrh.startswith('/'):
- variantHrh = variantHrh[1:]
- variantHrh = aEPOCROOT.Append(variantHrh)
- variantCfgDetails['VARIANT_HRH'] = variantHrh
- else:
- lineContent = line.split()
-
- if len(lineContent) == 1:
- variantCfgDetails[lineContent.pop(0)] = 1
- else:
- variantCfgDetails[lineContent.pop(0)] = lineContent
-
- variantCfgFile.close()
-
- if not variantCfgDetails.has_key('VARIANT_HRH'):
- raise MetaDataError("No variant file specified in "+str(aVariantCfgFile))
- if not variantHrh.isFile():
- raise MetaDataError("Variant file "+str(variantHrh)+" does not exist")
-
- return variantCfgDetails
-
-def getOsVerFromKifXml(aPathToKifXml):
- """Obtain the OS version from the kif.xml file located at $EPOCROOT/epoc32/data/kif.xml.
-
- If successful, the function returns a string such as "v95" to indicate 9.5; None is
- returned if for any reason the function cannot determine the OS version."""
-
- releaseTagName = "ki:release"
- osVersion = None
-
- import xml.dom.minidom
-
- try:
- # Parsed document object
- kifDom = xml.dom.minidom.parse(str(aPathToKifXml))
-
- # elements - the elements whose names are releaseTagName
- elements = kifDom.getElementsByTagName(releaseTagName)
-
- # There should be exactly one of the elements whose name is releaseTagName
- # If more than one, osVersion is left as None, since the version should be
- # unique to the kif.xml file
- if len(elements) == 1:
- osVersionTemp = elements[0].getAttribute("version")
- osVersion = "v" + osVersionTemp.replace(".", "")
-
- kifDom.unlink() # Clean up
-
- except:
- # There's no documentation on which exceptions are raised by these functions.
- # We catch everything and assume any exception means there was a failure to
- # determine OS version. None is returned, and the code will fall back
- # to looking at the buildinfo.txt file.
- pass
-
- return osVersion
-
-def getOsVerFromBuildInfoTxt(aPathToBuildInfoTxt):
- """Obtain the OS version from the buildinfo.txt file located at $EPOCROOT/epoc32/data/buildinfo.txt.
-
- If successful, the function returns a string such as "v95" to indicate 9.5; None is
- returned if for any reason the function cannot determine the OS version.
-
- The file $EPOCROOT/epoc32/data/buildinfo.txt is presumed to exist. The client code should
- handle existance/non-existance."""
-
- pathToBuildInfoTxt = str(aPathToBuildInfoTxt) # String form version of path to buildinfo.txt
-
- # Open the file for reading; throw an exception if it could not be read - note that
- # it should exist at this point.
- try:
- buildInfoTxt = open(pathToBuildInfoTxt)
- except IOError, (number, message):
- raise MetaDataError("Could not read buildinfo.txt file at" + pathToBuildInfoTxt + ": (" + message + ")")
-
- # Example buildinfo.txt contents:
- #
- # DeviceFamily 100
- # DeviceFamilyRev 0x900
- # ManufacturerSoftwareBuild M08765_Symbian_OS_v9.5
- #
- # Regexp to match the line containing the OS version
- # Need to match things like M08765_Symbian_OS_v9.5 and M08765_Symbian_OS_vFuture
- # So for the version, match everything except whitespace after v. Whitespace
- # signifies the end of the regexp.
- osVersionMatcher = re.compile('.*_Symbian_OS_v([^\s]*)', re.I)
- osVersion = None
-
- # Search for a regexp match over all the times in the file
- # Note: if two or more lines match the search pattern then
- # the latest match will overwrite the osVersion string.
- for line in buildInfoTxt:
- matchResult = osVersionMatcher.match(line)
- if matchResult:
- result = matchResult.groups()
- osVersion = "v" + str(reduce(lambda x, y: x + y, result))
- osVersion = osVersion.replace(".", "")
-
- buildInfoTxt.close() # Clean-up
-
- return osVersion
-
-def getBuildableBldInfBuildPlatforms(aBldInfBuildPlatforms,
- aDefaultOSBuildPlatforms,
- aBaseDefaultOSBuildPlatforms,
- aBaseUserDefaultOSBuildPlatforms):
- """Obtain a set of build platform names supported by a bld.inf file
-
- Build platform deduction is based on both the contents of the PRJ_PLATFORMS section of
- a bld.inf file together with a hard-coded set of default build platforms supported by
- the build system itself."""
-
- expandedBldInfBuildPlatforms = []
- removePlatforms = set()
-
- for bldInfBuildPlatform in aBldInfBuildPlatforms:
- if bldInfBuildPlatform.upper() == "DEFAULT":
- expandedBldInfBuildPlatforms.extend(aDefaultOSBuildPlatforms.split())
- elif bldInfBuildPlatform.upper() == "BASEDEFAULT":
- expandedBldInfBuildPlatforms.extend(aBaseDefaultOSBuildPlatforms.split())
- elif bldInfBuildPlatform.upper() == "BASEUSERDEFAULT":
- expandedBldInfBuildPlatforms.extend(aBaseUserDefaultOSBuildPlatforms.split())
- elif bldInfBuildPlatform.startswith("-"):
- removePlatforms.add(bldInfBuildPlatform.lstrip("-").upper())
- else:
- expandedBldInfBuildPlatforms.append(bldInfBuildPlatform.upper())
-
- if len(expandedBldInfBuildPlatforms) == 0:
- expandedBldInfBuildPlatforms.extend(aDefaultOSBuildPlatforms.split())
-
- # make a set of platforms that can be built
- buildableBldInfBuildPlatforms = set(expandedBldInfBuildPlatforms)
-
- # Add platforms that are buildable by virtue of the presence of another
- for piggyBackedPlatform in PiggyBackedBuildPlatforms:
- if piggyBackedPlatform in buildableBldInfBuildPlatforms:
- buildableBldInfBuildPlatforms.update(PiggyBackedBuildPlatforms.get(piggyBackedPlatform))
-
- # Remove platforms that were negated
- buildableBldInfBuildPlatforms -= removePlatforms
-
- return buildableBldInfBuildPlatforms
-
-
-def getPreProcessorCommentDetail (aPreProcessorComment):
- """Takes a preprocessor comment and returns an array containing the filename and linenumber detail."""
-
- commentDetail = []
- commentMatch = re.search('# (?P\d+) "(?P.*)"', aPreProcessorComment)
-
- if commentMatch:
- filename = commentMatch.group('FILENAME')
- filename = os.path.abspath(filename)
- filename = re.sub(r'\\\\', r'\\', filename)
- filename = re.sub(r'//', r'/', filename)
- filename = generic_path.Path(filename)
- linenumber = int (commentMatch.group('LINENUMBER'))
-
- commentDetail.append(filename)
- commentDetail.append(linenumber)
-
- 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):
- """Fatal error wrapper, to be thrown directly back to whatever is calling."""
-
- def __init__(self, aText):
- self.Text = aText
- def __str__(self):
- return repr(self.Text)
-
-
-class PreProcessedLine(str):
- """Custom string class that accepts filename and line number information from
- a preprocessed context."""
-
- def __new__(cls, value, *args, **keywargs):
- return str.__new__(cls, value)
-
- def __init__(self, value, aFilename, aLineNumber):
- self.filename = aFilename
- self.lineNumber = aLineNumber
-
- def getFilename (self):
- return self.filename
-
- def getLineNumber (self):
- return self.lineNumber
-
-class PreProcessor(raptor_utilities.ExternalTool):
- """Preprocessor wrapper suitable for Symbian metadata file processing."""
-
- def __init__(self, aPreProcessor,
- aStaticOptions,
- aIncludeOption,
- aMacroOption,
- aPreIncludeOption,
- aRaptor):
- raptor_utilities.ExternalTool.__init__(self, aPreProcessor)
- self.__StaticOptions = aStaticOptions
- self.__IncludeOption = aIncludeOption
- self.__MacroOption = aMacroOption
- self.__PreIncludeOption = aPreIncludeOption
-
- self.filename = ""
- self.__Macros = []
- self.__IncludePaths = []
- self.__PreIncludeFile = ""
- self.raptor = aRaptor
-
- 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:
- # the actual call differs between Windows and Unix
- if raptor_utilities.getOSFileSystem() == "unix":
- p = subprocess.Popen(commandline, \
- shell=True, bufsize=65535, \
- stdin=subprocess.PIPE, \
- stdout=subprocess.PIPE, \
- stderr=subprocess.PIPE, \
- close_fds=True)
- else:
- p = subprocess.Popen(commandline, \
- bufsize=65535, \
- stdin=subprocess.PIPE, \
- stdout=subprocess.PIPE, \
- stderr=subprocess.PIPE, \
- universal_newlines=True)
-
- # run the command and wait for all the output
- (self._ExternalTool__Output, errors) = p.communicate()
-
- if self.raptor.debugOutput:
- self.raptor.Debug("Preprocessing Start %s", str(sourcefilename))
- self.raptor.Debug("Output:\n%s", self._ExternalTool__Output)
- self.raptor.Debug("Errors:\n%s", errors)
- self.raptor.Debug("Preprocessing End %s", str(sourcefilename))
-
- incRE = re.compile("In file included from")
- fromRE = re.compile(r"\s+from")
- warningRE = re.compile("warning:|pasting.+token|from.+:")
- remarkRE = re.compile("no newline at end of file|does not give a valid preprocessing token")
-
- actualErr = False
- if errors != "":
- for error in errors.splitlines():
- if incRE.search(error) or fromRE.search(error):
- continue
- if not remarkRE.search(error):
- if warningRE.search(error):
- self.raptor.Warn("%s: %s", tool, error)
- else:
- self.raptor.Error("%s: %s", tool, error)
- actualErr = True
- if actualErr:
- raise MetaDataError("Errors in %s" % str(sourcefilename))
-
- except Exception,e:
- raise MetaDataError("Preprocessor exception: '%s' : in command : '%s'" % (str(e), commandline))
-
- return 0 # all OK
-
- def setMacros(self, aMacros):
- self.__Macros = aMacros
-
- def addMacro(self, aMacro):
- self.__Macros.append(aMacro)
-
- def addMacros(self, aMacros):
- self.__Macros.extend(aMacros)
-
- def getMacros(self):
- return self.__Macros
-
-
- def addIncludePath(self, aIncludePath):
- p = str(aIncludePath)
- if p == "":
- self.raptor.Warn("attempt to set an empty preprocessor include path for %s" % str(self.filename))
- else:
- self.__IncludePaths.append(p)
-
- def addIncludePaths(self, aIncludePaths):
- for path in aIncludePaths:
- self.addIncludePath(path)
-
- def setIncludePaths(self, aIncludePaths):
- self.__IncludePaths = []
- self.addIncludePaths(aIncludePaths)
-
- def setPreIncludeFile(self, aPreIncludeFile):
- self.__PreIncludeFile = aPreIncludeFile
-
- def preprocess(self):
- preProcessorCall = self.__constructPreProcessorCall()
- returnValue = self.call(preProcessorCall, self.filename)
-
- return self.getOutput()
-
- def __constructPreProcessorCall(self):
-
- call = self.__StaticOptions
-
- if self.__PreIncludeFile:
- call += " " + self.__PreIncludeOption
- call += " " + str(self.__PreIncludeFile)
-
- for macro in self.__Macros:
- call += " " + self.__MacroOption + macro
-
- for includePath in self.__IncludePaths:
- call += " " + self.__IncludeOption
- call += " " + str(includePath)
-
- return call
-
-
-class MetaDataFile(object):
- """A generic representation of a Symbian metadata file
-
- Symbian metadata files are subject to preprocessing, primarily with macros based
- on the selected build platform. This class provides a generic means of wrapping
- up the preprocessing of such files."""
-
- 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
- self.__RootLocation = aRootLocation
- # 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:
- raise ValueError('gnucpp must be set')
-
- def depspath(self, platform):
- """ Where does dependency information go relative to platform's SBS_BUILD_DIR?
- Subclasses should redefine this
- """
- return str(platform['SBS_BUILD_DIR']) + "/" + str(self.__RootLocation) + "." + platform['key_md5'] + ".d"
-
- def getContent(self, aBuildPlatform):
-
- key = aBuildPlatform['key']
-
- config_macros = []
-
- adepfilename = self.depspath(aBuildPlatform)
- generateDepsOptions = ""
- if adepfilename:
-
- if raptor_utilities.getOSPlatform().startswith("win"):
- metatarget = "$(PARSETARGET)"
- else:
- metatarget = "'$(PARSETARGET)'"
- generateDepsOptions = "-MD -MF%s -MT%s" % (adepfilename, metatarget)
- self.depfiles.append((adepfilename, metatarget))
- try:
- os.makedirs(os.path.dirname(adepfilename))
- except Exception, e:
- self.log.Debug("Couldn't make bldinf outputpath for dependency generation")
-
- config_macros = (aBuildPlatform['PLATMACROS']).split()
-
- if not key in self.__PreProcessedContent:
-
- preProcessor = PreProcessor(self.__gnucpp, '-undef -nostdinc ' + generateDepsOptions + ' ',
- '-I', '-D', '-include', self.log)
- preProcessor.filename = self.filename
-
- # always have the current directory on the include path
- preProcessor.addIncludePath('.')
-
- # the SYSTEMINCLUDE directories defined in the build config
- # should be on the include path. This is added mainly to support
- # Feature Variation as SYSTEMINCLUDE is usually empty at this point.
- systemIncludes = aBuildPlatform['SYSTEMINCLUDE']
- if systemIncludes:
- preProcessor.addIncludePaths(systemIncludes.split())
-
- preInclude = aBuildPlatform['VARIANT_HRH']
-
- # for non-Feature Variant builds, the directory containing the HRH should
- # be on the include path
- if not aBuildPlatform['ISFEATUREVARIANT']:
- preProcessor.addIncludePath(preInclude.Dir())
-
- # and EPOCROOT/epoc32/include
- preProcessor.addIncludePath(aBuildPlatform['EPOCROOT'].Append('epoc32/include'))
-
- # and the directory containing the bld.inf file
- if self.__RootLocation is not None and str(self.__RootLocation) != "":
- preProcessor.addIncludePath(self.__RootLocation)
-
- # and the directory containing the file we are processing
- preProcessor.addIncludePath(self.filename.Dir())
-
- # there is always a pre-include file
- preProcessor.setPreIncludeFile(preInclude)
-
- macros = ["SBSV2"]
-
- if config_macros:
- macros.extend(config_macros)
-
- if macros:
- for macro in macros:
- preProcessor.addMacro(macro + "=_____" +macro)
-
- # extra "raw" macros that do not need protecting
- preProcessor.addMacro("__GNUC__=3")
-
- preProcessorOutput = preProcessor.preprocess()
-
- # Resurrect preprocessing replacements
- pattern = r'([\\|/]| |) ?_____(('+macros[0]+')'
- for macro in macros[1:]:
- pattern += r'|('+macro+r')'
-
- pattern += r'\s*)'
- # Work on all Macros in one substitution.
- text = re.sub(pattern, r"\1\2", preProcessorOutput)
- text = re.sub(r"\n[\t ]*", r"\n", text)
-
- self.__PreProcessedContent[key] = text
-
- return self.__PreProcessedContent[key]
-
-class MMPFile(MetaDataFile):
- """A generic representation of a Symbian metadata file
-
- Symbian metadata files are subject to preprocessing, primarily with macros based
- 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, depfiles, log=None):
- """
- @param aFilename An MMP, bld.inf or other preprocessable build spec file
- @param gnucpp location of GNU CPP
- @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, depfiles, str(bldinf.filename.Dir()), log)
- self.__bldinf = bldinf
- self.depfiles = depfiles
-
- self.__gnucpp = gnucpp
- if gnucpp is None:
- raise ValueError('gnucpp must be set')
-
- def depspath(self, platform):
- """ Where does dependency information go relative to platform's SBS_BUILD_DIR?
- Subclasses should redefine this
- """
- return self.__bldinf.outputpath(platform) + "/" + self.filename.File() + '.' + platform['key_md5'] + ".d"
-
-class Export(object):
- """Single processed PRJ_EXPORTS or PRJ_TESTEXPORTS entry from a bld.inf file"""
-
- def getPossiblyQuotedStrings(cls,spec):
- """ Split a string based on whitespace
- but keep double quoted substrings together.
- """
- inquotes=False
- intokengap=False
- sourcedest=[]
- word = 0
- for c in spec:
- if c == '"':
- if inquotes:
- inquotes = False
- word += 1
- intokengap = True
- else:
- inquotes = True
- intokengap = False
- pass
- elif c == ' ' or c == '\t':
- if inquotes:
- if len(sourcedest) == word:
- sourcedest.append(c)
- else:
- sourcedest[word] += c
- else:
- if intokengap:
- # gobble unquoted spaces
- pass
- else:
- word += 1
- intokengap=True
- pass
- else:
- intokengap = False
- if len(sourcedest) == word:
- sourcedest.append(c)
- else:
- sourcedest[word] += c
-
- return sourcedest
-
- getPossiblyQuotedStrings = classmethod(getPossiblyQuotedStrings)
-
-
- def __init__(self, aBldInfFile, aExportsLine, aType):
- """
- Rules from the OS library for convenience:
-
- For PRJ_TESTEXPORTS
- source_file_1 [destination_file]
- source_file_n [destination_file]
- If the source file is listed with a relative path, the path will
- be considered relative to the directory containing the bld.inf file.
- If a destination file is not specified, the source file will be copied
- to the directory containing the bld.inf file.
- If a relative path is specified with the destination file, the path
- will be considered relative to directory containing the bld.inf file.
-
- For PRJ_EXPORTS
- source_file_1 [destination_file]
- source_file_n [destination_file]
- :zip zip_file [destination_path]
-
- Note that:
- If a source file is listed with a relative path, the path will be
- considered relative to the directory containing the bld.inf file.
-
- If a destination file is not specified, the source file will be copied
- to epoc32\include\.
-
- If a destination file is specified with the relative path, the path will
- be considered relative to directory epoc32\include\.
-
- If a destination begins with a drive letter, then the file is copied to
- epoc32\data\\. For example,
-
- mydata.dat e:\appdata\mydata.dat
- copies mydata.dat to epoc32\data\e\appdata\mydata.dat.
- You can use any driveletter between A and Z.
-
- A line can start with the preface :zip. This instructs the build tools
- to unzip the specified zip file to the specified destination path. If a
- destination path is not specified, the source file will be unzipped in
- the root directory.
-
-
- """
-
- # Work out what action is required - unzip or copy?
- action = "copy"
- typematch = re.match(r'^\s*(?P:zip\s+)?(?P[^\s].*[^\s])\s*$',aExportsLine, re.I)
-
- spec = typematch.group('spec')
- if spec == None:
- raise ValueError('must specify at least a source file for an export')
-
- if typematch.group('type') is not None:
- action = "unzip"
-
- # Split the spec into source and destination but take care
- # to allow filenames with quoted strings.
- exportEntries = Export.getPossiblyQuotedStrings(spec)
-
- # Get the source path as specified by the bld.inf
- source_spec = exportEntries.pop(0).replace(' ','%20')
-
- # Resolve the source file
- sourcepath = generic_path.Path(raptor_utilities.resolveSymbianPath(str(aBldInfFile), source_spec))
-
- # Find it if the case of the filename is wrong:
- # Carry on even if we don't find it
- foundfile = sourcepath.FindCaseless()
- if foundfile != None:
- source = str(foundfile).replace(' ','%20')
- else:
- source = str(sourcepath).replace(' ','%20')
-
-
- # Get the destination path as specified by the bld.inf
- if len(exportEntries) > 0:
- dest_spec = exportEntries.pop(0).replace(' ','%20')
- else:
- dest_spec = None
- # Destination list - list of destinations. For the WINSCW resource building stage,
- # files exported to the emulated drives and there are several locations, for example,
- # PRJ_[TEST]EXPORTS
- # 1234ABCD.SPD z:/private/10009876/policy/1234ABCD.spd
- # needs to end up copied in
- # epoc32/data/z/private/10009876/policy/1234ABCD.spd *and* in
- # epoc32/release/winscw/udeb/z/private/10009876/policy/1234ABCD.spd *and* in
- # epoc32/release/winscw/urel/z/private/10009876/policy/1234ABCD.spd
- dest_list = []
-
- # Resolve the destination if one is specified
- if dest_spec:
- # check for troublesome characters
- if ':' in dest_spec and not re.search('^[a-z]:', dest_spec, re.I):
- raise ValueError("invalid filename " + dest_spec)
-
- dest_spec = dest_spec.replace(' ','%20')
- aSubType=""
- if action == "unzip":
- aSubType=":zip"
- dest_spec = dest_spec.rstrip("\\/")
-
- # Get the export destination(s) - note this can be a list of strings or just a string.
- dest_list = raptor_utilities.resolveSymbianPath(str(aBldInfFile), dest_spec, aType, aSubType)
-
- def process_dest(aDest):
- if dest_spec.endswith('/') or dest_spec.endswith('\\'):
- m = generic_path.Path(source)
- aDest += '/'+m.File()
- return aDest
-
- if isinstance(dest_list, list):
- # Process each file in the list
- dest_list = map(process_dest, dest_list)
- else:
- # Process the single destination
- dest_list = process_dest(dest_list)
-
- else:
- # No destination was specified so we assume an appropriate one
-
- dest_filename=generic_path.Path(source).File()
-
- if aType == "PRJ_EXPORTS":
- if action == "copy":
- destination = '$(EPOCROOT)/epoc32/include/'+dest_filename
- elif action == "unzip":
- destination = '$(EPOCROOT)'
- elif aType == "PRJ_TESTEXPORTS":
- d = aBldInfFile.Dir()
- if action == "copy":
- destination = str(d.Append(dest_filename))
- elif action == "unzip":
- destination = "$(EPOCROOT)"
- else:
- raise ValueError("Export type should be 'PRJ_EXPORTS' or 'PRJ_TESTEXPORTS'. It was: "+str(aType))
-
-
- self.__Source = source
- if len(dest_list) > 0: # If the list has length > 0, this means there are several export destinations.
- self.__Destination = dest_list
- else: # Otherwise the list has length zero, so there is only a single export destination.
- self.__Destination = destination
- self.__Action = action
-
- def getSource(self):
- return self.__Source
-
- def getDestination(self):
- return self.__Destination # Note that this could be either a list, or a string, depending on the export destination
-
- def getAction(self):
- return self.__Action
-
-class ExtensionmakefileEntry(object):
- def __init__(self, aGnuLine, aBldInfFile, tmp):
-
- self.__BldInfFile = aBldInfFile
- bldInfLocation = self.__BldInfFile.Dir()
- biloc = str(bldInfLocation)
- extInfLocation = tmp.filename.Dir()
- eiloc = str(extInfLocation)
-
- if eiloc is None or eiloc == "":
- eiloc="." # Someone building with a relative raptor path
- if biloc is None or biloc == "":
- biloc="." # Someone building with a relative raptor path
-
- self.__StandardVariables = {}
- # Relative step-down to the root - let's try ignoring this for now, as it
- # should amount to the same thing in a world where absolute paths are king
- self.__StandardVariables['TO_ROOT'] = ""
- # Top-level bld.inf location
- self.__StandardVariables['TO_BLDINF'] = biloc
- self.__StandardVariables['EXTENSION_ROOT'] = eiloc
-
- # Get the directory and filename from the full path containing the extension makefile
- self.__FullPath = generic_path.Join(eiloc,aGnuLine)
- self.__FullPath = self.__FullPath.GetLocalString()
- self.__Filename = os.path.split(self.__FullPath)[1]
- self.__Directory = os.path.split(self.__FullPath)[0]
-
- def getMakefileName(self):
- return self.__Filename
-
- def getMakeDirectory(self):
- return self.__Directory
-
- def getStandardVariables(self):
- return self.__StandardVariables
-
-class Extension(object):
- """Single processed PRJ_EXTENSIONS or PRJ_TESTEXTENSIONS START EXTENSIONS...END block
- from a bld.inf file"""
-
- def __init__(self, aBldInfFile, aStartLine, aOptionLines, aBuildPlatform, aRaptor):
- self.__BldInfFile = aBldInfFile
- self.__Options = {}
- self.interface = ""
- self.__Raptor = aRaptor
-
- makefile = ""
- makefileMatch = re.search(r'^\s*START EXTENSION\s+(?P\S+)\s*(?P\S*)$', aStartLine, re.I)
-
- self.__RawMakefile = ""
-
- if (makefileMatch):
- self.__RawMakefile = makefileMatch.group('MAKEFILE')
- self.nametag = makefileMatch.group('NAMETAG').lower()
-
- # Ensure all \'s are translated into /'s if required
- self.interface = self.__RawMakefile
- self.interface = self.interface.replace("\\", "/").replace("/", ".")
-
- # To support standalone testing, '$(' prefixed TEMs are assumed to start with
- # a makefile variable and hence be fully located in FLM operation
- if self.__RawMakefile.startswith("$("):
- self.__Makefile = self.__RawMakefile + ".mk"
- else:
- self.__Makefile = '$(MAKEFILE_TEMPLATES)/' + self.__RawMakefile + ".mk"
-
- for optionLine in aOptionLines:
- optionMatch = re.search(r'^\s*(OPTION\s+)?(?P\S+)\s+(?P\S+.*)$',optionLine, re.I)
- if optionMatch:
- self.__Options[optionMatch.group('VARIABLE').upper()] = optionMatch.group('VALUE')
-
- bldInfLocation = self.__BldInfFile.Dir()
-
- biloc = str(bldInfLocation)
- if biloc is None or biloc == "":
- biloc="." # Someone building with a relative raptor path
-
- extInfLocation = aStartLine.filename.Dir()
-
- eiloc = str(extInfLocation)
- if eiloc is None or eiloc == "":
- eiloc="." # Someone building with a relative raptor path
-
- self.__StandardVariables = {}
- # Relative step-down to the root - let's try ignoring this for now, as it
- # should amount to the same thing in a world where absolute paths are king
- self.__StandardVariables['TO_ROOT'] = ""
- # Top-level bld.inf location
- self.__StandardVariables['TO_BLDINF'] = biloc
- # Location of bld.inf file containing the current EXTENSION block
- self.__StandardVariables['EXTENSION_ROOT'] = eiloc
-
- # If the interface exists, this means it's not a Template Extension Makefile so don't look for a .meta file for it;
- # so do nothing if it's not a template extension makefile
- try:
- self.__Raptor.cache.FindNamedInterface(str(self.interface), aBuildPlatform['CACHEID'])
- except KeyError: # This means that this Raptor doesn't have the interface self.interface, so we are in a TEM
- # Read extension meta file and get default options from it. The use of TEM meta file is compulsory if TEM is used
- metaFilename = "%s/epoc32/tools/makefile_templates/%s.meta" % (aBuildPlatform['EPOCROOT'], self.__RawMakefile)
- metaFile = None
- try:
- metaFile = open(metaFilename, "r")
- except IOError, e:
- self.__warn("Extension: %s - cannot open Meta file: %s" % (self.__RawMakefile, metaFilename))
-
- if metaFile:
- for line in metaFile.readlines():
- defaultOptionMatch = re.search(r'^OPTION\s+(?P\S+)\s+(?P\S+.*)$',line, re.I)
- if defaultOptionMatch and defaultOptionMatch.group('VARIABLE').upper() not in self.__Options.keys():
- self.__Options[defaultOptionMatch.group('VARIABLE').upper()] = defaultOptionMatch.group('VALUE')
-
- metaFile.close()
-
- def __warn(self, format, *extras):
- if (self.__Raptor):
- self.__Raptor.Warn(format, *extras)
-
- def getIdentifier(self):
- return re.sub (r'\\|\/|\$|\(|\)', '_', self.__RawMakefile)
-
- def getMakefile(self):
- return self.__Makefile
-
- def getOptions(self):
- return self.__Options
-
- def getStandardVariables(self):
- return self.__StandardVariables
-
-class MMPFileEntry(object):
- def __init__(self, aFilename, aTestOption, aARMOption):
- self.filename = aFilename
- self.testoption = aTestOption
- if aARMOption:
- self.armoption = True
- else:
- self.armoption = False
-
-
-class BldInfFile(MetaDataFile):
- """Representation of a Symbian bld.inf file"""
-
- 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
- # Generic
-
- def getBuildPlatforms(self, aBuildPlatform):
- platformList = []
-
- for platformLine in self.__getSection(aBuildPlatform, 'PRJ_PLATFORMS'):
- for platformEntry in platformLine.split():
- platformList.append(platformEntry)
-
- return platformList
-
- # Build Platform Specific
- def getMMPList(self, aBuildPlatform, aType="PRJ_MMPFILES"):
- mmpFileList=[]
- gnuList = []
- makefileList = []
- extFound = False
- m = None
-
- hashValue = {'mmpFileList': [] , 'gnuList': [], 'makefileList' : []}
-
- for mmpFileEntry in self.__getSection(aBuildPlatform, aType):
-
- actualBldInfRoot = mmpFileEntry.getFilename()
- n = re.match('\s*(?P(GNUMAKEFILE|N?MAKEFILE))\s+(?P[^ ]+)\s*(support|manual)?\s*(?P\S+.*)?\s*$',mmpFileEntry,re.I)
- if n:
-
- if (n.groupdict()['invalid']):
- self.log.Error("%s (%d) : invalid .mmp file qualifier \"%s\"", mmpFileEntry.filename, mmpFileEntry.getLineNumber(), n.groupdict()['invalid'])
- if raptor_utilities.getOSFileSystem() == "unix":
- self.log.Warn("NMAKEFILE/GNUMAKEFILE/MAKEFILE keywords not supported on Linux")
- else:
- extmakefilearg = n.groupdict()['extmakefile']
- bldInfDir = actualBldInfRoot.Dir()
- extmakefilename = bldInfDir.Append(extmakefilearg)
- extmakefile = ExtensionmakefileEntry(extmakefilearg, self.filename, mmpFileEntry)
-
- if (n.groupdict()['makefiletype']).upper() == "GNUMAKEFILE":
- gnuList.append(extmakefile)
- else:
- makefileList.append(extmakefile)
- else:
- # Currently there is only one possible option - build as arm.
- # For TESTMMPFILES, the supported options are support, tidy, ignore, manual and build as arm
- if aType.upper()=="PRJ_TESTMMPFILES":
- if re.match('\s*(?P[^ ]+)\s*(?Pbuild_as_arm)?\s*(?Psupport)?\s*(?Pignore)?\s*(?Ptidy)?\s*(?Pmanual)?\s*(?P\S+.*)?\s*$', mmpFileEntry, re.I):
- m = re.match('\s*(?P[^ ]+)\s*(?Pbuild_as_arm)?\s*(?Psupport)?\s*(?Pignore)?\s*(?Ptidy)?\s*(?Pmanual)?\s*(?P\S+.*)?\s*$', mmpFileEntry, re.I)
- else:
- if re.match('\s*(?P[^ ]+)\s*(?Pbuild_as_arm)?\s*(?P\S+.*)?\s*$', mmpFileEntry, re.I):
- m = re.match('\s*(?P[^ ]+)\s*(?Pbuild_as_arm)?\s*(?P\S+.*)?\s*$', mmpFileEntry, re.I)
-
- if m:
- if (m.groupdict()['invalid']):
- self.log.Error("%s (%d) : invalid .mmp file qualifier \"%s\"", mmpFileEntry.filename, mmpFileEntry.getLineNumber(), m.groupdict()['invalid'])
-
- mmpFileName = m.groupdict()['name']
- testmmpoption = "auto" # Setup tests to be automatic by default
- tokens = m.groupdict()
- for key,item in tokens.iteritems():
- if key=="manual" and item=="manual":
- testmmpoption = "manual"
- elif key=="support" and item=="support":
- testmmpoption = "support"
- elif key=="ignore" and item=="ignore":
- testmmpoption = "ignore"
-
- buildasarm = False
- if m.groupdict()['baa']:
- if m.groupdict()['baa'].lower() == 'build_as_arm':
- buildasarm = True
-
- if not mmpFileName.lower().endswith('.mmp'):
- mmpFileName += '.mmp'
- bldInfDir = actualBldInfRoot.Dir()
- try:
- mmpFileName = bldInfDir.Append(mmpFileName)
- mmpfe = MMPFileEntry(mmpFileName, testmmpoption, buildasarm)
- mmpFileList.append(mmpfe)
- except ValueError, e:
- self.log.Error("invalid .mmp file name: %s" % str(e))
-
- m = None
-
-
- hashValue['mmpFileList'] = mmpFileList
- hashValue['gnuList'] = gnuList
- hashValue['makefileList'] = makefileList
-
- return hashValue
-
- # Return a list of gnumakefiles used in the bld.inf
- def getExtensionmakefileList(self, aBuildPlatform, aType="PRJ_MMPFILES",aString = ""):
- extMakefileList=[]
- m = None
- for extmakeFileEntry in self.__getSection(aBuildPlatform, aType):
-
- actualBldInfRoot = extmakeFileEntry.filename
- if aType.upper()=="PRJ_TESTMMPFILES":
- m = re.match('\s*GNUMAKEFILE\s+(?P[^ ]+)\s*(?Psupport)?\s*(?Pignore)?\s*(?Ptidy)?\s*(?Pmanual)?\s*(?P\S+.*)?\s*$',extmakeFileEntry,re.I)
- else:
- if aString == "gnumakefile":
- m = re.match('\s*GNUMAKEFILE\s+(?P[^ ]+)\s*(?P\S+.*)?\s*$',extmakeFileEntry,re.I)
- elif aString == "nmakefile":
- m = re.match('\s*NMAKEFILE\s+(?P[^ ]+)\s*(?P\S+.*)?\s*$',extmakeFileEntry,re.I)
- elif aString == "makefile":
- m = re.match('\s*MAKEFILE\s+(?P[^ ]+)\s*(?P\S+.*)?\s*$',extmakeFileEntry,re.I)
- if m:
- if (m.groupdict()['invalid']):
- self.log.Error("%s (%d) : invalid extension makefile qualifier \"%s\"", extmakeFileEntry.filename, extmakeFileEntry.getLineNumber(), m.groupdict()['invalid'])
-
- extmakefilearg = m.groupdict()['extmakefile']
- bldInfDir = actualBldInfRoot.Dir()
- extmakefilename = bldInfDir.Append(extmakefilearg)
- extmakefile = ExtensionmakefileEntry(extmakefilearg, self.filename, extmakeFileEntry)
- extMakefileList.append(extmakefile)
- m = None
-
- return extMakefileList
-
- def getTestExtensionmakefileList(self,aBuildPlatform,aString=""):
- return self.getExtensionmakefileList(aBuildPlatform,"PRJ_TESTMMPFILES",aString)
-
- def getTestMMPList(self, aBuildPlatform):
- return self.getMMPList(aBuildPlatform, "PRJ_TESTMMPFILES")
-
- def getRomTestType(self, aBuildPlatform):
- testMMPList = self.getTestMMPList(aBuildPlatform)
- for testMMPFileEntry in testMMPList['mmpFileList']:
- if aBuildPlatform["TESTCODE"]:
- # Calculate test type (manual or auto)
- if testMMPFileEntry.testoption == "manual":
- self.testManual += 1
- if not (testMMPFileEntry.testoption == "support" or testMMPFileEntry.testoption == "manual" or testMMPFileEntry.testoption == "ignore"):
- self.testAuto += 1
- if self.testManual and self.testAuto:
- return 'BOTH'
- elif self.testAuto:
- return 'AUTO'
- elif self.testManual:
- return 'MANUAL'
- else:
- return 'NONE'
-
- def getExports(self, aBuildPlatform, aType="PRJ_EXPORTS"):
- exportList = []
-
- for exportLine in self.__getSection(aBuildPlatform, aType):
-
- if not re.match(r'\S+', exportLine):
- continue
-
- try:
- exportList.append(Export(exportLine.getFilename(), exportLine, aType))
- except ValueError,e:
- self.log.Error(str(e))
-
- return exportList
-
- def getTestExports(self, aBuildPlatform):
- return self.getExports(aBuildPlatform, "PRJ_TESTEXPORTS")
-
- def getExtensions(self, aBuildPlatform, aType="PRJ_EXTENSIONS"):
- extensionObjects = []
- start = ""
- options = []
-
- for extensionLine in self.__getSection(aBuildPlatform, aType):
- if (re.search(r'^\s*START ',extensionLine, re.I)):
- start = extensionLine
- elif re.search(r'^\s*END\s*$',extensionLine, re.I):
- extensionObjects.append(Extension(self.filename, start, options, aBuildPlatform, self.__Raptor))
- start = ""
- options = []
- elif re.search(r'^\s*$',extensionLine, re.I):
- continue
- elif start:
- options.append(extensionLine)
-
- return extensionObjects
-
- def getTestExtensions(self, aBuildPlatform):
- return self.getExtensions(aBuildPlatform, "PRJ_TESTEXTENSIONS")
-
- def __getSection(self, aBuildPlatform, aSection):
-
- activeSection = False
- sectionContent = []
- lineContent = re.split(r'\n', self.getContent(aBuildPlatform));
-
- currentBldInfFile = self.filename
- currentLineNumber = 0
-
- for line in lineContent:
- if line.startswith("#"):
- commentDetail = getPreProcessorCommentDetail(line)
- currentBldInfFile = commentDetail[0]
- currentLineNumber = commentDetail[1]-1
- continue
-
- currentLineNumber += 1
-
- if not re.match(r'.*\S+', line):
- continue
- elif re.match(r'\s*' + aSection + r'\s*$', line, re.I):
- activeSection = True
- elif re.match(r'\s*PRJ_\w+\s*$', line, re.I):
- activeSection = False
- elif activeSection:
- sectionContent.append(PreProcessedLine(line, currentBldInfFile, currentLineNumber))
-
- return sectionContent
-
- @staticmethod
- def outputPathFragment(bldinfpath):
- """Return a relative path that uniquely identifies this bldinf file
- whilst being short so that it can be appended to epoc32/build.
- The build product of a particular bld.inf may be placed in here.
- This affects its TEMs and its MMPs"""
-
- absroot_str = os.path.abspath(str(bldinfpath)).lower().replace("\\","/")
-
- uniqueid = hashlib.md5()
- uniqueid.update(absroot_str)
-
- specnamecomponents = (re.sub("^[A-Za-z]:", "", absroot_str)).split('/') # split, removing any drive identifier (if present)
-
- pathlist=[]
- while len(specnamecomponents) > 0:
- top = specnamecomponents.pop()
- if top.endswith('.inf'):
- continue
- elif top == 'group':
- continue
- else:
- pathlist = [top]
- break
-
- pathlist.append("c_"+uniqueid.hexdigest()[:16])
- return "/".join(pathlist)
-
- def outputpath(self, platform):
- """ The full path where product from this bldinf is created."""
- return str(platform['SBS_BUILD_DIR']) + "/" + BldInfFile.outputPathFragment(self.filename)
-
- def depspath(self, platform):
- """ Where does dependency information go relative to platform's SBS_BUILD_DIR?
- Subclasses should redefine this
- """
- return self.outputpath(platform) + "/bldinf." + platform['key_md5'] + ".d"
-
-
-
-class MMPRaptorBackend(MMPBackend):
- """A parser "backend" for the MMP language
-
- This is used to map recognised MMP syntax onto a buildspec """
-
- # Support priorities, with case-fixed mappings for use
- epoc32priorities = {
- 'low':'Low',
- 'background':'Background',
- 'foreground':'Foreground',
- 'high':'High',
- 'windowserver':'WindowServer',
- 'fileserver':'FileServer',
- 'realtimeserver':'RealTimeServer',
- 'supervisor':'SuperVisor'
- }
-
- # Known capability flags with associated bitwise operations
- supportedCapabilities = {
- 'tcb':(1<<0),
- 'commdd':(1<<1),
- 'powermgmt':(1<<2),
- 'multimediadd':(1<<3),
- 'readdevicedata':(1<<4),
- 'writedevicedata':(1<<5),
- 'drm':(1<<6),
- 'trustedui':(1<<7),
- 'protserv':(1<<8),
- 'diskadmin':(1<<9),
- 'networkcontrol':(1<<10),
- 'allfiles':(1<<11),
- 'swevent':(1<<12),
- 'networkservices':(1<<13),
- 'localservices':(1<<14),
- 'readuserdata':(1<<15),
- 'writeuserdata':(1<<16),
- 'location':(1<<17),
- 'surroundingsdd':(1<<18),
- 'userenvironment':(1<<19),
- # Old capability names have zero value
- 'root':0,
- 'mediadd':0,
- 'readsystemdata':0,
- 'writesystemdata':0,
- 'sounddd':0,
- 'uidd':0,
- 'killanyprocess':0,
- 'devman':0,
- 'phonenetwork':0,
- 'localnetwork':0
- }
-
- library_re = re.compile(r"^(?P[^{]+?)(?P{(?P[0-9]+)\.(?P[0-9]+)})?(\.(lib|dso))?$",re.I)
-
-
- def __init__(self, aRaptor, aMmpfilename, aBldInfFilename):
- super(MMPRaptorBackend,self).__init__()
- self.platformblock = None
- self.__Raptor = aRaptor
- self.__debug("-----+++++ %s " % aMmpfilename)
- self.BuildVariant = raptor_data.Variant(name = "mmp")
- self.ApplyVariants = []
- self.ResourceVariants = []
- self.BitmapVariants = []
- self.StringTableVariants = []
- self.__bldInfFilename = aBldInfFilename
- self.__targettype = "UNKNOWN"
- self.__currentMmpFile = aMmpfilename
- self.__defFileRoot = self.__currentMmpFile
- self.__currentLineNumber = 0
- self.__sourcepath = raptor_utilities.resolveSymbianPath(self.__currentMmpFile, "")
- self.__userinclude = ""
- self.__systeminclude = ""
- self.__bitmapSourcepath = self.__sourcepath
- self.__current_resource = ""
- self.__resourceFiles = []
- self.__pageConflict = []
- self.__debuggable = ""
- self.__compressionKeyword = ""
- self.sources = []
- self.capabilities = []
-
- self.__TARGET = ""
- self.__TARGETEXT = ""
- self.deffile = ""
- self.__LINKAS = ""
- self.nostrictdef = False
- self.featureVariant = False
-
- self.__currentResourceVariant = None
- self.__currentStringTableVariant = None
- self.__explicitversion = False
- self.__versionhex = ""
-
- # "ALL" capability calculated based on the total capabilities currently supported
- allCapabilities = 0
- for supportedCapability in MMPRaptorBackend.supportedCapabilities.keys():
- allCapabilities = allCapabilities | MMPRaptorBackend.supportedCapabilities[supportedCapability]
- MMPRaptorBackend.supportedCapabilities['all'] = allCapabilities
-
- # Permit unit-testing output without a Raptor context
- def __debug(self, format, *extras):
- if (self.__Raptor):
- self.__Raptor.Debug(format, *extras)
-
- def __warn(self, format, *extras):
- if (self.__Raptor):
- self.__Raptor.Warn(format, *extras)
-
- def doPreProcessorComment(self,s,loc,toks):
- commentDetail = getPreProcessorCommentDetail(toks[0])
- self.__currentMmpFile = commentDetail[0].GetLocalString()
- self.__currentLineNumber = commentDetail[1]
- self.__debug("Current file %s, line number %s\n" % (self.__currentMmpFile,str(self.__currentLineNumber)))
- return "OK"
-
- def doBlankLine(self,s,loc,toks):
- self.__currentLineNumber += 1
-
- def doStartPlatform(self,s,loc,toks):
- self.__currentLineNumber += 1
- self.__debug( "Start Platform block "+toks[0])
- self.platformblock = toks[0]
- return "OK"
-
- def doEndPlatform(self,s,loc,toks):
- self.__currentLineNumber += 1
- self.__debug( "Finalise platform " + self.platformblock)
- return "OK"
-
- def doSetSwitch(self,s,loc,toks):
- self.__currentLineNumber += 1
- prefix=""
- varname = toks[0].upper()
-
- # A bright spark made the optionname the same as
- # the env variable. One will override the other if we pass this
- # on to make. Add a prefix to prevent the clash.
- if varname=='ARMINC':
- prefix="SET_"
- self.__debug( "Set switch "+toks[0]+" ON")
- self.BuildVariant.AddOperation(raptor_data.Set(prefix+varname, "1"))
-
- elif varname=='NOSTRICTDEF':
- self.nostrictdef = True
- self.__debug( "Set switch "+toks[0]+" ON")
- self.BuildVariant.AddOperation(raptor_data.Set(prefix+varname, "1"))
-
- elif varname == 'PAGED':
- self.BuildVariant.AddOperation(raptor_data.Set(varname, "1"))
- self.__debug( "Set switch PAGE ON")
- self.BuildVariant.AddOperation(raptor_data.Set("PAGEDCODE_OPTION", "paged"))
- self.__debug( "Set switch PAGEDCODE ON")
- self.BuildVariant.AddOperation(raptor_data.Set("PAGEDDATA_OPTION", "paged"))
- self.__debug( "Set data PAGEDDATA ON")
- self.__pageConflict.append("PAGEDCODE")
- self.__pageConflict.append("PAGEDDATA")
-
- elif varname == 'UNPAGED':
- self.BuildVariant.AddOperation(raptor_data.Set("PAGED", "0"))
- self.__debug( "Set switch PAGED OFF")
- self.BuildVariant.AddOperation(raptor_data.Set("PAGEDCODE_OPTION", "unpaged"))
- self.__debug( "Set switch PAGEDCODE OFF")
- self.BuildVariant.AddOperation(raptor_data.Set("PAGEDDATA_OPTION", "unpaged"))
- self.__debug( "Set data PAGEDDATA OFF")
- self.__pageConflict.append("UNPAGEDCODE")
- self.__pageConflict.append("UNPAGEDDATA")
-
- elif varname == 'PAGEDCODE':
- self.BuildVariant.AddOperation(raptor_data.Set("PAGEDCODE_OPTION", "paged"))
- self.__debug( "Set switch " + varname + " ON")
- self.__pageConflict.append(varname)
-
- elif varname == 'PAGEDDATA':
- self.BuildVariant.AddOperation(raptor_data.Set("PAGEDDATA_OPTION", "paged"))
- self.__debug( "Set switch " + varname + " ON")
- self.__pageConflict.append(varname)
-
- elif varname == 'UNPAGEDCODE':
- self.BuildVariant.AddOperation(raptor_data.Set("PAGEDCODE_OPTION", "unpaged"))
- self.__debug( "Set switch " + varname + " ON")
- self.__pageConflict.append(varname)
- elif varname == 'UNPAGEDDATA':
- self.BuildVariant.AddOperation(raptor_data.Set("PAGEDDATA_OPTION", "unpaged"))
- self.__debug( "Set switch " + varname + " ON")
- self.__pageConflict.append(varname)
-
- elif varname == 'NOLINKTIMECODEGENERATION':
- self.BuildVariant.AddOperation(raptor_data.Set("LTCG",""))
- self.__debug( "Set switch " + varname + " OFF")
- elif varname == 'NOMULTIFILECOMPILATION':
- self.BuildVariant.AddOperation(raptor_data.Set("MULTIFILE_ENABLED",""))
- self.__debug( "Set switch " + varname + " OFF")
-
- elif varname == 'DEBUGGABLE':
- if self.__debuggable != "udeb":
- self.__debuggable = "udeb urel"
- else:
- self.__Raptor.Warn("DEBUGGABLE keyword ignored as DEBUGGABLE_UDEBONLY is already specified")
- elif varname == 'DEBUGGABLE_UDEBONLY':
- if self.__debuggable != "":
- self.__Raptor.Warn("DEBUGGABLE keyword has no effect as DEBUGGABLE or DEBUGGABLE_UDEBONLY is already set")
- self.__debuggable = "udeb"
- 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"))
-
- return "OK"
-
- def doAssignment(self,s,loc,toks):
- self.__currentLineNumber += 1
- varname = toks[0].upper()
- if varname=='TARGET':
- (self.__TARGET, self.__TARGETEXT) = os.path.splitext(toks[1])
- self.__TARGETEXT = self.__TARGETEXT.lstrip('.')
-
- self.BuildVariant.AddOperation(raptor_data.Set("REQUESTEDTARGETEXT", self.__TARGETEXT.lower()))
-
- lowercase_TARGET = self.__TARGET.lower()
- self.__debug("Set "+toks[0]+" to " + lowercase_TARGET)
- self.__debug("Set REQUESTEDTARGETEXT to " + self.__TARGETEXT.lower())
-
- self.BuildVariant.AddOperation(raptor_data.Set("TARGET", self.__TARGET))
- self.BuildVariant.AddOperation(raptor_data.Set("TARGET_lower", lowercase_TARGET))
- if lowercase_TARGET != self.__TARGET:
- self.__debug("TARGET is not lowercase: '%s' - might cause BC problems." % self.__TARGET)
- elif varname=='TARGETTYPE':
- self.__debug("Set "+toks[0]+" to " + str(toks[1]))
- self.__targettype=toks[1]
- if self.__targettype.lower() == "none":
- self.BuildVariant.AddOperation(raptor_data.Set("TARGET", ""))
- self.BuildVariant.AddOperation(raptor_data.Set("TARGET_lower",""))
- self.BuildVariant.AddOperation(raptor_data.Set("REQUESTEDTARGETEXT", ""))
- self.BuildVariant.AddOperation(raptor_data.Set(varname,toks[1].lower()))
-
- elif varname=='TARGETPATH':
- value = toks[1].lower().replace('\\','/')
- self.__debug("Set "+varname+" to " + value)
- self.BuildVariant.AddOperation(raptor_data.Set(varname, value))
-
- elif varname=='OPTION' or varname=='LINKEROPTION':
- self.__debug("Set "+toks[1]+varname+" to " + str(toks[2]))
- self.BuildVariant.AddOperation(raptor_data.Append(varname+"_"+toks[1].upper()," ".join(toks[2])))
-
- # Warn about OPTION ARMASM
- if "armasm" in toks[1].lower():
- self.__Raptor.Warn(varname+" ARMASM has no effect (use OPTION ARMCC).")
-
- elif varname=='OPTION_REPLACE':
- # Warn about OPTION_REPLACE ARMASM
- if "armasm" in toks[1].lower():
- self.__Raptor.Warn("OPTION_REPLACE ARMASM has no effect (use OPTION_REPLACE ARMCC).")
- else:
- args = " ".join(toks[2])
-
- searchReplacePairs = self.resolveOptionReplace(args)
-
- for searchReplacePair in searchReplacePairs:
- self.__debug("Append %s to OPTION_REPLACE_%s", searchReplacePair, toks[1].upper())
- self.BuildVariant.AddOperation(raptor_data.Append(varname+"_"+toks[1].upper(),searchReplacePair))
-
- elif varname=='SYSTEMINCLUDE' or varname=='USERINCLUDE':
- for path in toks[1]:
- resolved = raptor_utilities.resolveSymbianPath(self.__currentMmpFile, path)
- self.BuildVariant.AddOperation(raptor_data.Append(varname,resolved))
-
- if varname=='SYSTEMINCLUDE':
- self.__systeminclude += ' ' + resolved
- self.__debug(" %s = %s",varname, self.__systeminclude)
- else:
- self.__userinclude += ' ' + resolved
- self.__debug(" %s = %s",varname, self.__userinclude)
-
- self.__debug("Appending %s to %s",resolved, varname)
-
- self.__systeminclude = self.__systeminclude.strip()
- self.__systeminclude = self.__systeminclude.rstrip('\/')
- self.__userinclude = self.__userinclude.strip()
- self.__userinclude = self.__userinclude.rstrip('\/')
-
- elif varname=='EXPORTLIBRARY':
- # Remove extension from the EXPORTLIBRARY name
- libName = toks[1].rsplit(".", 1)[0]
- self.__debug("Set "+varname+" to " + libName)
- self.BuildVariant.AddOperation(raptor_data.Set(varname,"".join(libName)))
-
- elif varname=='CAPABILITY':
- for cap in toks[1]:
- self.__debug("Setting "+toks[0]+": " + cap)
- self.capabilities.append(cap)
- elif varname=='DEFFILE':
- self.__defFileRoot = self.__currentMmpFile
- self.deffile = toks[1]
- elif varname=='LINKAS':
- self.__debug("Set "+toks[0]+" OPTION to " + str(toks[1]))
- self.__LINKAS = toks[1]
- self.BuildVariant.AddOperation(raptor_data.Set(varname, toks[1]))
- elif varname=='SECUREID' or varname=='VENDORID':
- hexoutput = MMPRaptorBackend.canonicalUID(toks[1])
- self.__debug("Set "+toks[0]+" OPTION to " + hexoutput)
- self.BuildVariant.AddOperation(raptor_data.Set(varname, hexoutput))
- elif varname=='VERSION':
- if toks[-1] == "EXPLICIT":
- self.__explicitversion = True
- self.BuildVariant.AddOperation(raptor_data.Set("EXPLICITVERSION", "1"))
-
- vm = re.match(r'^(\d+)(\.(\d+))?$', toks[1])
- if vm is not None:
- version = vm.groups()
- # the major version number
- major = int(version[0],10)
-
- # add in the minor number
- minor = 0
- 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)))
- self.BuildVariant.AddOperation(raptor_data.Set(varname+"HEX", self.__versionhex))
- self.__debug("Set "+toks[0]+" OPTION to " + toks[1])
- self.__debug("Set "+toks[0]+"HEX OPTION to " + "%04x%04x" % (major,minor))
-
- else:
- self.__Raptor.Warn("Invalid version supplied to VERSION (%s), using default value" % toks[1])
-
- elif varname=='EPOCHEAPSIZE':
- # Standardise on sending hex numbers to the FLMS.
-
- if toks[1].lower().startswith('0x'):
- min = long(toks[1],16)
- else:
- min = long(toks[1],10)
-
- if toks[2].lower().startswith('0x'):
- max = long(toks[2],16)
- else:
- max = long(toks[2],10)
-
- self.BuildVariant.AddOperation(raptor_data.Set(varname+"MIN", "%x" % min))
- self.__debug("Set "+varname+"MIN OPTION to '%x' (hex)" % min )
- self.BuildVariant.AddOperation(raptor_data.Set(varname+"MAX", "%x" % max))
- self.__debug("Set "+varname+"MAX OPTION to '%x' (hex)" % max )
-
- # Some toolchains require decimal versions of the min/max values, converted to KB and
- # rounded up to the next 1KB boundary
- min_dec_kb = (int(min) + 1023) / 1024
- max_dec_kb = (int(max) + 1023) / 1024
- self.BuildVariant.AddOperation(raptor_data.Set(varname+"MIN_DEC_KB", "%d" % min_dec_kb))
- self.__debug("Set "+varname+"MIN OPTION KB to '%d' (dec)" % min_dec_kb )
- self.BuildVariant.AddOperation(raptor_data.Set(varname+"MAX_DEC_KB", "%d" % max_dec_kb))
- self.__debug("Set "+varname+"MAX OPTION KB to '%d' (dec)" % max_dec_kb )
-
- elif varname=='EPOCSTACKSIZE':
- if toks[1].lower().startswith('0x'):
- stack = long(toks[1],16)
- else:
- stack = long(toks[1],10)
- self.BuildVariant.AddOperation(raptor_data.Set(varname, "%x" % stack))
- self.__debug("Set "+varname+" OPTION to '%x' (hex)" % stack )
- elif varname=='EPOCPROCESSPRIORITY':
- # low, background, foreground, high, windowserver, fileserver, realtimeserver or supervisor
- # These are case insensitive in metadata entries, but must be mapped to a static case pattern for use
- prio = toks[1].lower()
-
- # NOTE: Original validation here didn't actually work. This has been corrected to provide an error, but probably needs re-examination.
- if not MMPRaptorBackend.epoc32priorities.has_key(prio):
- self.__Raptor.Error("Priority setting '%s' is not a valid priority - should be one of %s.", prio, MMPRaptorBackend.epoc32priorities.values())
- else:
- self.__debug("Set "+toks[0]+" to " + MMPRaptorBackend.epoc32priorities[prio])
- self.BuildVariant.AddOperation(raptor_data.Set(varname,MMPRaptorBackend.epoc32priorities[prio]))
- elif varname=='ROMTARGET' or varname=='RAMTARGET':
- if len(toks) == 1:
- self.__debug("Set "+toks[0]+" to " )
- self.BuildVariant.AddOperation(raptor_data.Set(varname,""))
- else:
- toks1 = str(toks[1]).replace("\\","/")
- if toks1.find(","):
- 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])))
-
- if varname=='LINKAS':
- self.__LINKAS = toks[1]
-
- return "OK"
-
- def doAppend(self,s,loc,toks):
- self.__currentLineNumber += 1
- """MMP command
- """
- name=toks[0].upper()
- if len(toks) == 1:
- # list can be empty e.g. MACRO _FRED_ when fred it defined in the HRH
- # causes us to see just "MACRO" in the input - it is valid to ignore this
- self.__debug("Empty append list for " + name)
- return "OK"
- self.__debug("Append to "+name+" the values: " +str(toks[1]))
-
- if name=='MACRO':
- name='MMPDEFS'
- elif name=='LANG':
- # don't break the environment variable
- name='LANGUAGES'
-
- for item in toks[1]:
- if name=='MMPDEFS':
- # Unquote any macros since the FLM does it anyhow
- if item.startswith('"') and item.endswith('"') \
- or item.startswith("'") and item.endswith("'"):
- item = item.strip("'\"")
- if name=='LIBRARY' or name=='DEBUGLIBRARY':
- im = MMPRaptorBackend.library_re.match(item)
- if not im:
- self.__error("LIBRARY: %s Seems to have an invalid name.\nExpected xxxx.lib or xxxx.dso\n where xxxx might be\n\tname or \n\tname(n,m) where n is a major version number and m is a minor version number\n" %item)
- d = im.groupdict()
-
- item = d['name']
- if d['version'] is not None:
- item += "{%04x%04x}" % (int(d['major']), int(d['minor']))
- item += ".dso"
- elif name=='STATICLIBRARY':
- # the FLM will decide on the ending appropriate to the platform
- item = re.sub(r"^(.*)\.[Ll][Ii][Bb]$",r"\1", item)
- elif name=="LANGUAGES":
- item = item.lower()
- elif (name=="WIN32_LIBRARY" and (item.startswith(".") or re.search(r'[\\|/]',item))) \
- or (name=="WIN32_RESOURCE"):
- # Relatively pathed win32 libraries, and all win32 resources, are resolved in relation
- # to the wrapper bld.inf file in which their .mmp file is specified. This equates to
- # the current working directory in ABLD operation.
- item = raptor_utilities.resolveSymbianPath(self.__bldInfFilename, item)
-
- self.BuildVariant.AddOperation(raptor_data.Append(name,item," "))
-
- # maintain a debug library list, the same as LIBRARY but with DEBUGLIBRARY values
- # appended as they are encountered
- if name=='LIBRARY' or name=='DEBUGLIBRARY':
- self.BuildVariant.AddOperation(raptor_data.Append("LIBRARY_DEBUG",item," "))
-
- return "OK"
-
- def canonicalUID(number):
- """ convert a UID string into an 8 digit hexadecimal string without leading 0x """
- if number.lower().startswith("0x"):
- n = int(number,16)
- else:
- n = int(number,10)
-
- return "%08x" % n
-
- canonicalUID = staticmethod(canonicalUID)
-
- def doUIDAssignment(self,s,loc,toks):
- """A single UID command results in a number of spec variables"""
- self.__currentLineNumber += 1
-
- hexoutput = MMPRaptorBackend.canonicalUID(toks[1][0])
- self.__debug( "Set UID2 to %s" % hexoutput )
- self.BuildVariant.AddOperation(raptor_data.Set("UID2", hexoutput))
-
- if len(toks[1]) > 1:
- hexoutput = MMPRaptorBackend.canonicalUID(toks[1][1])
- self.__debug( "Set UID3 to %s" % hexoutput)
- self.BuildVariant.AddOperation(raptor_data.Set("UID3", hexoutput))
-
- self.__debug( "done set UID")
- return "OK"
-
- def doSourcePathAssignment(self,s,loc,toks):
- self.__currentLineNumber += 1
- self.__sourcepath = raptor_utilities.resolveSymbianPath(self.__currentMmpFile, toks[1])
- self.__debug( "Remembering self.sourcepath state: "+str(toks[0])+" is now " + self.__sourcepath)
- self.__debug("selfcurrentMmpFile: " + self.__currentMmpFile)
- return "OK"
-
-
- def doSourceAssignment(self,s,loc,toks):
- self.__currentLineNumber += 1
- self.__debug( "Setting "+toks[0]+" to " + str(toks[1]))
- for file in toks[1]:
- # file is always relative to sourcepath but some MMP files
- # have items that begin with a slash...
- file = file.lstrip("/")
- source = generic_path.Join(self.__sourcepath, file)
-
- # If the SOURCEPATH itself begins with a '/', then dont look up the caseless version, since
- # we don't know at this time what $(EPOCROOT) will evaluate to.
- if source.GetLocalString().startswith('$(EPOCROOT)'):
- self.sources.append(str(source))
- self.__debug("Append SOURCE " + str(source))
-
- else:
- foundsource = source.FindCaseless()
- if foundsource == None:
- # Hope that the file will be generated later
- self.__debug("Sourcefile not found: %s" % source)
- foundsource = source
-
- self.sources.append(str(foundsource))
- self.__debug("Append SOURCE " + str(foundsource))
-
-
- self.__debug(" sourcepath: " + self.__sourcepath)
- return "OK"
-
- # Resource
-
- def doOldResourceAssignment(self,s,loc,toks):
- # Technically deprecated, but still used, so...
- self.__currentLineNumber += 1
- self.__debug("Processing old-style "+toks[0]+" "+str(toks[1]))
-
- sysRes = (toks[0].lower() == "systemresource")
-
- for rss in toks[1]:
- variant = raptor_data.Variant()
-
- source = generic_path.Join(self.__sourcepath, rss)
- variant.AddOperation(raptor_data.Set("SOURCE", str(source)))
- self.__resourceFiles.append(str(source))
-
- target = source.File().rsplit(".", 1)[0] # remove the extension
- variant.AddOperation(raptor_data.Set("TARGET", target))
- variant.AddOperation(raptor_data.Set("TARGET_lower", target.lower()))
-
- header = target.lower() + ".rsg" # filename policy
- variant.AddOperation(raptor_data.Set("HEADER", header))
-
- if sysRes:
- dsrtp = self.getDefaultSystemResourceTargetPath()
- variant.AddOperation(raptor_data.Set("TARGETPATH", dsrtp))
-
- self.ResourceVariants.append(variant)
-
- return "OK"
-
- def getDefaultSystemResourceTargetPath(self):
- # the default systemresource TARGETPATH value should come from the
- # configuration rather than being hard-coded here. Then again, this
- # should really be deprecated away into oblivion...
- return "system/data"
-
-
- def getDefaultResourceTargetPath(self, targettype):
- # the different default TARGETPATH values should come from the
- # configuration rather than being hard-coded here.
- if targettype == "plugin":
- return "resource/plugins"
- if targettype == "pdl":
- return "resource/printers"
- return ""
-
- def resolveOptionReplace(self, content):
- """
- Constructs search/replace pairs based on .mmp OPTION_REPLACE entries for use on tool command lines
- within FLMS.
-
- Depending on what's supplied to OPTION_REPLACE , the core part of the command line
- in the relevant FLM will have search and replace actions performed on it post-expansion (but pre-
- any OPTION additions).
-
- In terms of logic, we try to follow what ABLD does, as the current behaviour is undocumented.
- What happens is a little inconsistent, and best described by some generic examples:
-
- OPTION_REPLACE TOOL existing_option replacement_value
-
- Replace all instances of "option existing_value" with "option replacement_value"
-
- OPTION_REPLACE TOOL existing_option replacement_option
-
- Replace all instances of "existing_option" with "replacement_option".
-
- If "existing_option" is present in isolation then a removal is performed.
-
- Any values encountered that don't follow an option are ignored.
- Options are identified as being prefixed with either '-' or '--'.
-
- The front-end processes each OPTION_REPLACE entry and then appends one or more search/replace pairs
- to an OPTION_REPLACE_ variable in the following format:
-
- search<->replace
- """
- # Note that, for compatibility reasons, the following is mostly a port to Python of the corresponding
- # ABLD Perl, and hence maintains ABLD's idiosyncrasies in what it achieves
-
- searchReplacePairs = []
- matches = re.findall("-{1,2}\S+\s*(?!-)\S*",content)
-
- if matches:
- # reverse so we can process as a stack whilst retaining original order
- matches.reverse()
-
- while (len(matches)):
- match = matches.pop()
-
- standaloneMatch = re.match('^(?P