1## @file 2# This file is used to define each component of tools_def.txt file 3# 4# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> 5# This program and the accompanying materials 6# are licensed and made available under the terms and conditions of the BSD License 7# which accompanies this distribution. The full text of the license may be found at 8# http://opensource.org/licenses/bsd-license.php 9# 10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 12# 13 14## 15# Import Modules 16# 17import Common.LongFilePathOs as os 18import re 19import EdkLogger 20 21from Dictionary import * 22from BuildToolError import * 23from TargetTxtClassObject import * 24from Common.LongFilePathSupport import OpenLongFilePath as open 25 26## 27# Static variables used for pattern 28# 29gMacroRefPattern = re.compile('(DEF\([^\(\)]+\))') 30gEnvRefPattern = re.compile('(ENV\([^\(\)]+\))') 31gMacroDefPattern = re.compile("DEFINE\s+([^\s]+)") 32gDefaultToolsDefFile = "tools_def.txt" 33 34## ToolDefClassObject 35# 36# This class defined content used in file tools_def.txt 37# 38# @param object: Inherited from object class 39# @param Filename: Input value for full path of tools_def.txt 40# 41# @var ToolsDefTxtDictionary: To store keys and values defined in target.txt 42# @var MacroDictionary: To store keys and values defined in DEFINE statement 43# 44class ToolDefClassObject(object): 45 def __init__(self, FileName=None): 46 self.ToolsDefTxtDictionary = {} 47 self.MacroDictionary = {} 48 for Env in os.environ: 49 self.MacroDictionary["ENV(%s)" % Env] = os.environ[Env] 50 51 if FileName != None: 52 self.LoadToolDefFile(FileName) 53 54 ## LoadToolDefFile 55 # 56 # Load target.txt file and parse it, return a set structure to store keys and values 57 # 58 # @param Filename: Input value for full path of tools_def.txt 59 # 60 def LoadToolDefFile(self, FileName): 61 FileContent = [] 62 if os.path.isfile(FileName): 63 try: 64 F = open(FileName, 'r') 65 FileContent = F.readlines() 66 except: 67 EdkLogger.error("tools_def.txt parser", FILE_OPEN_FAILURE, ExtraData=FileName) 68 else: 69 EdkLogger.error("tools_def.txt parser", FILE_NOT_FOUND, ExtraData=FileName) 70 71 self.ToolsDefTxtDatabase = { 72 TAB_TOD_DEFINES_TARGET : [], 73 TAB_TOD_DEFINES_TOOL_CHAIN_TAG : [], 74 TAB_TOD_DEFINES_TARGET_ARCH : [], 75 TAB_TOD_DEFINES_COMMAND_TYPE : [] 76 } 77 78 for Index in range(len(FileContent)): 79 Line = FileContent[Index].strip() 80 if Line == "" or Line[0] == '#': 81 continue 82 NameValuePair = Line.split("=", 1) 83 if len(NameValuePair) != 2: 84 EdkLogger.warn("tools_def.txt parser", "Line %d: not correct assignment statement, skipped" % (Index + 1)) 85 continue 86 87 Name = NameValuePair[0].strip() 88 Value = NameValuePair[1].strip() 89 90 if Name == "IDENTIFIER": 91 EdkLogger.debug(EdkLogger.DEBUG_8, "Line %d: Found identifier statement, skipped: %s" % ((Index + 1), Value)) 92 continue 93 94 MacroDefinition = gMacroDefPattern.findall(Name) 95 if MacroDefinition != []: 96 Done, Value = self.ExpandMacros(Value) 97 if not Done: 98 EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE, 99 "Macro or Environment has not been defined", 100 ExtraData=Value[4:-1], File=FileName, Line=Index+1) 101 102 MacroName = MacroDefinition[0].strip() 103 self.MacroDictionary["DEF(%s)" % MacroName] = Value 104 EdkLogger.debug(EdkLogger.DEBUG_8, "Line %d: Found macro: %s = %s" % ((Index + 1), MacroName, Value)) 105 continue 106 107 Done, Value = self.ExpandMacros(Value) 108 if not Done: 109 EdkLogger.error("tools_def.txt parser", ATTRIBUTE_NOT_AVAILABLE, 110 "Macro or Environment has not been defined", 111 ExtraData=Value[4:-1], File=FileName, Line=Index+1) 112 113 List = Name.split('_') 114 if len(List) != 5: 115 EdkLogger.verbose("Line %d: Not a valid name of definition: %s" % ((Index + 1), Name)) 116 continue 117 elif List[4] == '*': 118 EdkLogger.verbose("Line %d: '*' is not allowed in last field: %s" % ((Index + 1), Name)) 119 continue 120 else: 121 self.ToolsDefTxtDictionary[Name] = Value 122 if List[0] != '*': 123 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] += [List[0]] 124 if List[1] != '*': 125 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] += [List[1]] 126 if List[2] != '*': 127 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] += [List[2]] 128 if List[3] != '*': 129 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] += [List[3]] 130 if List[4] == TAB_TOD_DEFINES_FAMILY and List[2] == '*' and List[3] == '*': 131 if TAB_TOD_DEFINES_FAMILY not in self.ToolsDefTxtDatabase: 132 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY] = {} 133 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value 134 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY] = {} 135 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value 136 elif List[1] not in self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]: 137 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] = Value 138 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value 139 elif self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY][List[1]] != Value: 140 EdkLogger.verbose("Line %d: No override allowed for the family of a tool chain: %s" % ((Index + 1), Name)) 141 if List[4] == TAB_TOD_DEFINES_BUILDRULEFAMILY and List[2] == '*' and List[3] == '*': 142 if TAB_TOD_DEFINES_BUILDRULEFAMILY not in self.ToolsDefTxtDatabase \ 143 or List[1] not in self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_FAMILY]: 144 EdkLogger.verbose("Line %d: The family is not specified, but BuildRuleFamily is specified for the tool chain: %s" % ((Index + 1), Name)) 145 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_BUILDRULEFAMILY][List[1]] = Value 146 147 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET])) 148 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG])) 149 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH])) 150 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE] = list(set(self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE])) 151 152 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET].sort() 153 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TOOL_CHAIN_TAG].sort() 154 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_TARGET_ARCH].sort() 155 self.ToolsDefTxtDatabase[TAB_TOD_DEFINES_COMMAND_TYPE].sort() 156 157 KeyList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH, TAB_TOD_DEFINES_COMMAND_TYPE] 158 for Index in range(3, -1, -1): 159 for Key in dict(self.ToolsDefTxtDictionary): 160 List = Key.split('_') 161 if List[Index] == '*': 162 for String in self.ToolsDefTxtDatabase[KeyList[Index]]: 163 List[Index] = String 164 NewKey = '%s_%s_%s_%s_%s' % tuple(List) 165 if NewKey not in self.ToolsDefTxtDictionary: 166 self.ToolsDefTxtDictionary[NewKey] = self.ToolsDefTxtDictionary[Key] 167 continue 168 del self.ToolsDefTxtDictionary[Key] 169 elif List[Index] not in self.ToolsDefTxtDatabase[KeyList[Index]]: 170 del self.ToolsDefTxtDictionary[Key] 171 172 ## ExpandMacros 173 # 174 # Replace defined macros with real value 175 # 176 # @param Value: The string with unreplaced macros 177 # 178 # @retval Value: The string which has been replaced with real value 179 # 180 def ExpandMacros(self, Value): 181 EnvReference = gEnvRefPattern.findall(Value) 182 for Ref in EnvReference: 183 if Ref not in self.MacroDictionary: 184 Value = Value.replace(Ref, "") 185 else: 186 Value = Value.replace(Ref, self.MacroDictionary[Ref]) 187 188 189 MacroReference = gMacroRefPattern.findall(Value) 190 for Ref in MacroReference: 191 if Ref not in self.MacroDictionary: 192 return False, Ref 193 Value = Value.replace(Ref, self.MacroDictionary[Ref]) 194 195 return True, Value 196 197## ToolDefDict 198# 199# Load tools_def.txt in input Conf dir 200# 201# @param ConfDir: Conf dir 202# 203# @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt 204# 205def ToolDefDict(ConfDir): 206 Target = TargetTxtDict(ConfDir) 207 ToolDef = ToolDefClassObject() 208 if DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF in Target.TargetTxtDictionary: 209 ToolsDefFile = Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF] 210 if ToolsDefFile: 211 ToolDef.LoadToolDefFile(os.path.normpath(ToolsDefFile)) 212 else: 213 ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(ConfDir, gDefaultToolsDefFile))) 214 else: 215 ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(ConfDir, gDefaultToolsDefFile))) 216 return ToolDef 217 218## 219# 220# This acts like the main() function for the script, unless it is 'import'ed into another 221# script. 222# 223if __name__ == '__main__': 224 ToolDef = ToolDefDict(os.getenv("WORKSPACE")) 225 pass 226