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