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