def __init__( self, basicConfig: BasicConfig, basedUponXML: XmlConfigFileAddTemplateImportDirectory) -> None: super().__init__() self.BasedOn = basedUponXML self.Name = self.BasedOn.Name variableProcessor = VariableProcessor(basicConfig) # NOTE: workaround Union of tuples not being iterable bug in mypy https://github.com/python/mypy/issues/1575 tupleResult = variableProcessor.TrySplitLeadingEnvironmentVariablesNameAndPath( self.Name) envName = tupleResult[0] rest = tupleResult[1] if envName is None: raise Exception( "Template import dirs are expected to contain environment variables" ) rest = rest if rest is not None else "" self.DecodedName = envName self.BashName = IOUtil.Join('$' + self.DecodedName, rest) self.DosName = IOUtil.Join('%' + self.DecodedName + '%', rest) if self.Name is None: raise XmlException2( basedUponXML.XmlElement, "Dirs are expected to contain environment variables") self.ResolvedPath = IOUtil.Join( IOUtil.GetEnvironmentVariableForDirectory(self.DecodedName), rest) self.ResolvedPathEx = "{0}/".format( self.ResolvedPath) if len(self.ResolvedPath) > 0 else ""
def __LoadTemplateFolder( self, xmlElement: ET.Element) -> XmlConfigFileTemplateFolder: foundElement = xmlElement.find("TemplateFolder") if foundElement is None: raise XmlException2(xmlElement, "Could not locate the TemplateFolder element") return XmlConfigFileTemplateFolder(self.Log, foundElement)
def __LoadGenFileName(self, xmlElement: ET.Element) -> XmlConfigFileGenFile: foundElement = xmlElement.find("GenFile") if foundElement is None: raise XmlException2(xmlElement, "Could not locate the GenFile element") return XmlConfigFileGenFile(self.Log, foundElement)
def _GetElement(self, xmlElement: ET.Element, elementName: str) -> ET.Element: foundElement = xmlElement.find(elementName) if foundElement is None: raise XmlException2( xmlElement, "Could not locate the expected {0} element".format( elementName)) return foundElement
def __TryLoadPlatforms(self, log: Log, xmlElement: ET.Element) -> Dict[str, XmlExperimentalPlatform]: platformDict = {} # type: Dict[str, XmlExperimentalPlatform] platformElements = xmlElement.findall("Platform") if platformElements is not None and len(platformElements) > 0: for element in platformElements: platform = XmlExperimentalPlatform(log, element) if platform.Id in platformDict: errorMsg = "Multiple platforms called '{0}' found in Project.gen".format(platform.Id) raise XmlException2(element, errorMsg) platformDict[platform.Id] = platform return platformDict
def __TryReadStrictChecks( self, log: Log, xmlElement: ET.Element ) -> Optional[XmlClangTidyPlatformStrictChecks]: foundElements = xmlElement.findall("StrictChecks") if len(foundElements) > 1: raise XmlException2( "There can only be one 'StrictChecks' element in a ClangTidyConfiguration.Platform" ) if len(foundElements) <= 0: return None return XmlClangTidyPlatformStrictChecks(log, foundElements[0])
def __TryReadCompiler( self, log: Log, xmlElement: ET.Element) -> Optional[XmlClangTidyPlatformCompiler]: foundElements = xmlElement.findall("Compiler") if len(foundElements) > 1: raise XmlException2( "There can only be one 'Compiler' element in a ClangTidyConfiguration.Platform" ) if len(foundElements) <= 0: return None return XmlClangTidyPlatformCompiler(log, foundElements[0])
def __ReadRecipes( self, log: Log, xmlElement: ET.Element ) -> Optional[XmlExperimentalPlatformRecipes_DefaultValue]: foundElements = xmlElement.findall("Recipes.DefaultValue") if foundElements is None or len(foundElements) <= 0: return None if len(foundElements) > 1: errorMsg = "Multiple entries called '{0}' for platform found in Project.gen".format( foundElements) raise XmlException2(xmlElement, errorMsg) return XmlExperimentalPlatformRecipes_DefaultValue( log, foundElements[0])
def __ValidateNames(self, rNameDict: Dict[str, Union[XmlGenFileDependency, XmlGenFileExternalDependency, XmlGenFileDefine]], dependencyList: Union[List[XmlGenFileDependency], List[XmlGenFileExternalDependency], List[XmlGenFileDefine]], errorStr: str) -> None: for entry in dependencyList: entryId = entry.Name.lower() if hasattr(entry, 'IfCondition') and cast(Any, entry).IfCondition is not None: entryId = "{0}|'{1}'".format(entryId, cast(Any, entry).IfCondition) if not entryId in rNameDict: rNameDict[entryId] = entry else: nameStr = "{0} ({1})".format(entry.Name, entryId) raise XmlException2(entry.XMLElement, errorStr.format(entry.Name))
def __ResolvePackageConfiguration(self, xmlPackageConfigurations: List[XmlConfigPackageConfiguration]) -> Dict[str, XmlConfigPackageConfiguration]: # prepare the package configurations packageConfigurationDict = {} # type: Dict[str, XmlConfigPackageConfiguration] for entry in xmlPackageConfigurations: if entry.Name in packageConfigurationDict: firstEntry = packageConfigurationDict[entry.Name] raise XmlException2(entry.XMLElement, "Duplicated package configuration name '{0}' found in '{1}' and '{2}'".format(entry.Name, entry.SourceFile, firstEntry.SourceFile)) packageConfigurationDict[entry.Name] = entry if 'default' not in packageConfigurationDict: raise XmlException("The file did not contain the 'default' PackageConfiguration element") return packageConfigurationDict
def __ValidateNames(self, rNameDict: Dict[str, Union[XmlGenFileDependency, XmlGenFileExternalDependency, XmlGenFileDefine]], dependencyList: Union[ List[XmlGenFileDependency], List[XmlGenFileExternalDependency], List[XmlGenFileDefine]], errorStr: str) -> None: for entry in dependencyList: entryId = entry.Name.lower() if not entryId in rNameDict: rNameDict[entryId] = entry else: raise XmlException2(entry.XMLElement, errorStr % (entry.Name))
def __ResolveAllowDependencyOnThis(self, packageType: PackageType) -> bool: if packageType == PackageType.Library: return True elif packageType == PackageType.Executable: return False elif packageType == PackageType.ExternalLibrary: return True elif packageType == PackageType.HeaderLibrary: return True elif packageType == PackageType.ToolRecipe: return True elif packageType == PackageType.TopLevel: return False else: raise XmlException2( "Unknown package type: {0}".format(packageType))
def Load(self, config: Config, packageTemplateLoader: PackageTemplateLoader, packageFile: PackageFile) -> None: filename = packageFile.AbsoluteFilePath if not os.path.isfile(filename): raise FileNotFoundException("Could not locate gen file %s", filename) self.SourceFilename = filename self.PackageLocation = packageFile.PackageRootLocation fileContent = IOUtil.ReadFile(filename) self.SourceFileHash = self.__CalcContentHash(fileContent) elem = ET.fromstring(fileContent) if elem.tag != 'FslBuildGen': raise XmlInvalidRootElement( "The file did not contain the expected root tag 'FslBuildGen'") elem, theType = self.__FindPackageElementAndType(elem) packageName = self._ReadAttrib(elem, 'Name') defaultValues = self.__GetDefaultValues(elem, packageName) allowNoInclude = self._ReadBoolAttrib(elem, 'NoInclude', False) companyName = self._ReadAttrib(elem, 'Company', config.ToolConfig.DefaultCompany) if config.ToolConfig.RequirePackageCreationYear: creationYear = self._ReadAttrib(elem, 'CreationYear') else: creationYear = self._ReadAttrib( elem, 'CreationYear', PackageCreationYearString.NotDefined) templateType = self._ReadAttrib(elem, 'TemplateType', "") self.AllowCheck = self._ReadBoolAttrib(elem, 'AllowCheck', True) # if this is set we allow '.cc' files for C++ code. self.EnableExtendedSourceExtensions = self._ReadBoolAttrib( elem, 'EnableExtendedSourceExtensions', False) self.BaseIncludePath = self._ReadAttrib(elem, 'OverrideInclude', 'include') self.BaseSourcePath = self._ReadAttrib(elem, 'OverrideSource', 'source') self.AllowCombinedDirectory = self._ReadBoolAttrib( elem, 'AllowCombinedDirectory', False) self.PackageNameBasedIncludePath = self._ReadBoolAttrib( elem, 'PackageNameBasedIncludePath', True) self.BaseLoad( elem, SubPackageSupportConfig(theType, config.SubPackageSupport)) requirements = self._GetXMLRequirements(elem) allowRecipes = self.__DoesTypeAllowRecipes(theType) # Add recipe and dependencies self.DirectExperimentalRecipe = self._TryGetExperimentalRecipe( elem, packageName, allowRecipes) if self.DirectExperimentalRecipe is not None: self.DirectDependencies += self.__AddExperimentalRecipeDependencies( self.DirectDependencies, [], self.DirectExperimentalRecipe) platforms = self.__GetXMLPlatforms(elem, packageName, self.DirectDependencies, allowRecipes, defaultValues) self.BuildCustomization = self.__GetBuildCustomizations( elem, packageName) templates = self.__GetXMLImportTemplates(elem) self.__ImportTemplates(packageTemplateLoader, templates, requirements, self.DirectDependencies, self.ExternalDependencies, self.DirectDefines) if self.BaseIncludePath == self.BaseSourcePath and not self.AllowCombinedDirectory: raise XmlException2( elem, "Package '{0}' uses the same directory for include and source '{1}'" .format(packageName, self.BaseIncludePath)) self.SourcePackageFile = packageFile self.XMLElement = elem self.Name = packageName self.ShortName = None self.Namespace = None self.SetType(theType) self.Platforms = platforms self.DirectRequirements = requirements self.AbsolutePath = None self.AbsoluteIncludePath = None self.AbsoluteSourcePath = None self.CompanyName = companyName self.CreationYear = creationYear self.TemplateType = templateType self.PlatformDefaultSupportedValue = defaultValues.Platform_Supported self.SystemDefaultValues = defaultValues self._ValidateName(elem, self.Name) # This check was moved to the package loader where it belongs #self.__ValidateFilename(config, filename) self.__ResolveNames(self.Name) self.__ValidateBasicDependencyCorrectness() self.__ValidateDefines() self.__ResolvePaths(config, filename, allowNoInclude)