]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/AutoGen/GenDepex.py
BaseTools: AutoGen - add Opcode constants
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / GenDepex.py
CommitLineData
30fdf114
LG
1## @file\r
2# This file is used to generate DEPEX file for module's dependency expression\r
3#\r
31ff1c44 4# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
40d841f6 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## Import Modules\r
14#\r
15import sys\r
1be2ed90 16import Common.LongFilePathOs as os\r
30fdf114
LG
17import re\r
18import traceback\r
1be2ed90 19from Common.LongFilePathSupport import OpenLongFilePath as open\r
30fdf114
LG
20from StringIO import StringIO\r
21from struct import pack\r
22from Common.BuildToolError import *\r
23from Common.Misc import SaveFileOnChange\r
24from Common.Misc import GuidStructureStringToGuidString\r
25from Common import EdkLogger as EdkLogger\r
b36d134f 26from Common.BuildVersion import gBUILD_VERSION\r
8bb63e37 27from Common.DataType import *\r
30fdf114
LG
28\r
29## Regular expression for matching "DEPENDENCY_START ... DEPENDENCY_END"\r
30gStartClosePattern = re.compile(".*DEPENDENCY_START(.+)DEPENDENCY_END.*", re.S)\r
31\r
32## Mapping between module type and EFI phase\r
33gType2Phase = {\r
8bb63e37
CJ
34 SUP_MODULE_BASE : None,\r
35 SUP_MODULE_SEC : "PEI",\r
36 SUP_MODULE_PEI_CORE : "PEI",\r
37 SUP_MODULE_PEIM : "PEI",\r
38 SUP_MODULE_DXE_CORE : "DXE",\r
39 SUP_MODULE_DXE_DRIVER : "DXE",\r
40 SUP_MODULE_DXE_SMM_DRIVER : "DXE",\r
41 SUP_MODULE_DXE_RUNTIME_DRIVER: "DXE",\r
42 SUP_MODULE_DXE_SAL_DRIVER : "DXE",\r
43 SUP_MODULE_UEFI_DRIVER : "DXE",\r
44 SUP_MODULE_UEFI_APPLICATION : "DXE",\r
45 SUP_MODULE_SMM_CORE : "DXE",\r
46 SUP_MODULE_MM_STANDALONE : "MM",\r
47 SUP_MODULE_MM_CORE_STANDALONE : "MM",\r
30fdf114
LG
48}\r
49\r
50## Convert dependency expression string into EFI internal representation\r
51#\r
52# DependencyExpression class is used to parse dependency expression string and\r
53# convert it into its binary form.\r
54#\r
55class DependencyExpression:\r
56\r
57 ArchProtocols = set([\r
58 '665e3ff6-46cc-11d4-9a38-0090273fc14d', # 'gEfiBdsArchProtocolGuid'\r
59 '26baccb1-6f42-11d4-bce7-0080c73c8881', # 'gEfiCpuArchProtocolGuid'\r
60 '26baccb2-6f42-11d4-bce7-0080c73c8881', # 'gEfiMetronomeArchProtocolGuid'\r
61 '1da97072-bddc-4b30-99f1-72a0b56fff2a', # 'gEfiMonotonicCounterArchProtocolGuid'\r
62 '27cfac87-46cc-11d4-9a38-0090273fc14d', # 'gEfiRealTimeClockArchProtocolGuid'\r
63 '27cfac88-46cc-11d4-9a38-0090273fc14d', # 'gEfiResetArchProtocolGuid'\r
64 'b7dfb4e1-052f-449f-87be-9818fc91b733', # 'gEfiRuntimeArchProtocolGuid'\r
65 'a46423e3-4617-49f1-b9ff-d1bfa9115839', # 'gEfiSecurityArchProtocolGuid'\r
66 '26baccb3-6f42-11d4-bce7-0080c73c8881', # 'gEfiTimerArchProtocolGuid'\r
67 '6441f818-6362-4e44-b570-7dba31dd2453', # 'gEfiVariableWriteArchProtocolGuid'\r
68 '1e5668e2-8481-11d4-bcf1-0080c73c8881', # 'gEfiVariableArchProtocolGuid'\r
69 '665e3ff5-46cc-11d4-9a38-0090273fc14d' # 'gEfiWatchdogTimerArchProtocolGuid'\r
70 ]\r
71 )\r
72\r
73 OpcodePriority = {\r
31ff1c44
CJ
74 DEPEX_OPCODE_AND : 1,\r
75 DEPEX_OPCODE_OR : 1,\r
76 DEPEX_OPCODE_NOT : 2,\r
30fdf114
LG
77 }\r
78\r
79 Opcode = {\r
80 "PEI" : {\r
31ff1c44
CJ
81 DEPEX_OPCODE_PUSH : 0x02,\r
82 DEPEX_OPCODE_AND : 0x03,\r
83 DEPEX_OPCODE_OR : 0x04,\r
84 DEPEX_OPCODE_NOT : 0x05,\r
85 DEPEX_OPCODE_TRUE : 0x06,\r
86 DEPEX_OPCODE_FALSE : 0x07,\r
87 DEPEX_OPCODE_END : 0x08\r
30fdf114
LG
88 },\r
89\r
90 "DXE" : {\r
31ff1c44
CJ
91 DEPEX_OPCODE_BEFORE: 0x00,\r
92 DEPEX_OPCODE_AFTER : 0x01,\r
93 DEPEX_OPCODE_PUSH : 0x02,\r
94 DEPEX_OPCODE_AND : 0x03,\r
95 DEPEX_OPCODE_OR : 0x04,\r
96 DEPEX_OPCODE_NOT : 0x05,\r
97 DEPEX_OPCODE_TRUE : 0x06,\r
98 DEPEX_OPCODE_FALSE : 0x07,\r
99 DEPEX_OPCODE_END : 0x08,\r
100 DEPEX_OPCODE_SOR : 0x09\r
5a9c3e3e
SV
101 },\r
102\r
103 "MM" : {\r
31ff1c44
CJ
104 DEPEX_OPCODE_BEFORE: 0x00,\r
105 DEPEX_OPCODE_AFTER : 0x01,\r
106 DEPEX_OPCODE_PUSH : 0x02,\r
107 DEPEX_OPCODE_AND : 0x03,\r
108 DEPEX_OPCODE_OR : 0x04,\r
109 DEPEX_OPCODE_NOT : 0x05,\r
110 DEPEX_OPCODE_TRUE : 0x06,\r
111 DEPEX_OPCODE_FALSE : 0x07,\r
112 DEPEX_OPCODE_END : 0x08,\r
113 DEPEX_OPCODE_SOR : 0x09\r
30fdf114
LG
114 }\r
115 }\r
116\r
117 # all supported op codes and operands\r
31ff1c44
CJ
118 SupportedOpcode = [DEPEX_OPCODE_BEFORE, DEPEX_OPCODE_AFTER, DEPEX_OPCODE_PUSH, DEPEX_OPCODE_AND, DEPEX_OPCODE_OR, DEPEX_OPCODE_NOT, DEPEX_OPCODE_END, DEPEX_OPCODE_SOR]\r
119 SupportedOperand = [DEPEX_OPCODE_TRUE, DEPEX_OPCODE_FALSE]\r
30fdf114 120\r
31ff1c44
CJ
121 OpcodeWithSingleOperand = [DEPEX_OPCODE_NOT, DEPEX_OPCODE_BEFORE, DEPEX_OPCODE_AFTER]\r
122 OpcodeWithTwoOperand = [DEPEX_OPCODE_AND, DEPEX_OPCODE_OR]\r
30fdf114
LG
123\r
124 # op code that should not be the last one\r
31ff1c44 125 NonEndingOpcode = [DEPEX_OPCODE_AND, DEPEX_OPCODE_OR, DEPEX_OPCODE_NOT, DEPEX_OPCODE_SOR]\r
30fdf114 126 # op code must not present at the same time\r
31ff1c44 127 ExclusiveOpcode = [DEPEX_OPCODE_BEFORE, DEPEX_OPCODE_AFTER]\r
30fdf114 128 # op code that should be the first one if it presents\r
31ff1c44 129 AboveAllOpcode = [DEPEX_OPCODE_SOR, DEPEX_OPCODE_BEFORE, DEPEX_OPCODE_AFTER]\r
30fdf114
LG
130\r
131 #\r
132 # open and close brace must be taken as individual tokens\r
133 #\r
134 TokenPattern = re.compile("(\(|\)|\{[^{}]+\{?[^{}]+\}?[ ]*\}|\w+)")\r
135\r
136 ## Constructor\r
137 #\r
138 # @param Expression The list or string of dependency expression\r
139 # @param ModuleType The type of the module using the dependency expression\r
140 #\r
141 def __init__(self, Expression, ModuleType, Optimize=False):\r
142 self.ModuleType = ModuleType\r
143 self.Phase = gType2Phase[ModuleType]\r
144 if type(Expression) == type([]):\r
145 self.ExpressionString = " ".join(Expression)\r
146 self.TokenList = Expression\r
147 else:\r
148 self.ExpressionString = Expression\r
149 self.GetExpressionTokenList()\r
150\r
151 self.PostfixNotation = []\r
152 self.OpcodeList = []\r
153\r
154 self.GetPostfixNotation()\r
155 self.ValidateOpcode()\r
156\r
157 EdkLogger.debug(EdkLogger.DEBUG_8, repr(self))\r
158 if Optimize:\r
159 self.Optimize()\r
160 EdkLogger.debug(EdkLogger.DEBUG_8, "\n Optimized: " + repr(self))\r
161\r
162 def __str__(self):\r
163 return " ".join(self.TokenList)\r
164\r
165 def __repr__(self):\r
166 WellForm = ''\r
167 for Token in self.PostfixNotation:\r
168 if Token in self.SupportedOpcode:\r
169 WellForm += "\n " + Token\r
170 else:\r
171 WellForm += ' ' + Token\r
172 return WellForm\r
173\r
174 ## Split the expression string into token list\r
175 def GetExpressionTokenList(self):\r
176 self.TokenList = self.TokenPattern.findall(self.ExpressionString)\r
177\r
178 ## Convert token list into postfix notation\r
179 def GetPostfixNotation(self):\r
180 Stack = []\r
181 LastToken = ''\r
182 for Token in self.TokenList:\r
183 if Token == "(":\r
184 if LastToken not in self.SupportedOpcode + ['(', '', None]:\r
185 EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before open parentheses",\r
186 ExtraData="Near %s" % LastToken)\r
187 Stack.append(Token)\r
188 elif Token == ")":\r
189 if '(' not in Stack:\r
190 EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: mismatched parentheses",\r
191 ExtraData=str(self))\r
192 elif LastToken in self.SupportedOpcode + ['', None]:\r
193 EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before close parentheses",\r
194 ExtraData="Near %s" % LastToken)\r
195 while len(Stack) > 0:\r
196 if Stack[-1] == '(':\r
197 Stack.pop()\r
198 break\r
199 self.PostfixNotation.append(Stack.pop())\r
200 elif Token in self.OpcodePriority:\r
31ff1c44 201 if Token == DEPEX_OPCODE_NOT:\r
30fdf114
LG
202 if LastToken not in self.SupportedOpcode + ['(', '', None]:\r
203 EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before NOT",\r
204 ExtraData="Near %s" % LastToken)\r
205 elif LastToken in self.SupportedOpcode + ['(', '', None]:\r
206 EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operand before " + Token,\r
207 ExtraData="Near %s" % LastToken)\r
208\r
209 while len(Stack) > 0:\r
210 if Stack[-1] == "(" or self.OpcodePriority[Token] >= self.OpcodePriority[Stack[-1]]:\r
211 break\r
212 self.PostfixNotation.append(Stack.pop())\r
213 Stack.append(Token)\r
214 self.OpcodeList.append(Token)\r
215 else:\r
216 if Token not in self.SupportedOpcode:\r
217 # not OP, take it as GUID\r
218 if LastToken not in self.SupportedOpcode + ['(', '', None]:\r
219 EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: missing operator before %s" % Token,\r
220 ExtraData="Near %s" % LastToken)\r
221 if len(self.OpcodeList) == 0 or self.OpcodeList[-1] not in self.ExclusiveOpcode:\r
222 if Token not in self.SupportedOperand:\r
31ff1c44 223 self.PostfixNotation.append(DEPEX_OPCODE_PUSH)\r
30fdf114
LG
224 # check if OP is valid in this phase\r
225 elif Token in self.Opcode[self.Phase]:\r
31ff1c44 226 if Token == DEPEX_OPCODE_END:\r
30fdf114
LG
227 break\r
228 self.OpcodeList.append(Token)\r
229 else:\r
230 EdkLogger.error("GenDepex", PARSER_ERROR,\r
231 "Opcode=%s doesn't supported in %s stage " % (Token, self.Phase),\r
232 ExtraData=str(self))\r
233 self.PostfixNotation.append(Token)\r
234 LastToken = Token\r
235\r
236 # there should not be parentheses in Stack\r
237 if '(' in Stack or ')' in Stack:\r
238 EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid dependency expression: mismatched parentheses",\r
239 ExtraData=str(self))\r
240 while len(Stack) > 0:\r
241 self.PostfixNotation.append(Stack.pop())\r
31ff1c44
CJ
242 if self.PostfixNotation[-1] != DEPEX_OPCODE_END:\r
243 self.PostfixNotation.append(DEPEX_OPCODE_END)\r
30fdf114
LG
244\r
245 ## Validate the dependency expression\r
246 def ValidateOpcode(self):\r
247 for Op in self.AboveAllOpcode:\r
248 if Op in self.PostfixNotation:\r
249 if Op != self.PostfixNotation[0]:\r
250 EdkLogger.error("GenDepex", PARSER_ERROR, "%s should be the first opcode in the expression" % Op,\r
251 ExtraData=str(self))\r
252 if len(self.PostfixNotation) < 3:\r
253 EdkLogger.error("GenDepex", PARSER_ERROR, "Missing operand for %s" % Op,\r
254 ExtraData=str(self))\r
255 for Op in self.ExclusiveOpcode:\r
256 if Op in self.OpcodeList:\r
257 if len(self.OpcodeList) > 1:\r
258 EdkLogger.error("GenDepex", PARSER_ERROR, "%s should be the only opcode in the expression" % Op,\r
259 ExtraData=str(self))\r
260 if len(self.PostfixNotation) < 3:\r
261 EdkLogger.error("GenDepex", PARSER_ERROR, "Missing operand for %s" % Op,\r
262 ExtraData=str(self))\r
31ff1c44 263 if self.TokenList[-1] != DEPEX_OPCODE_END and self.TokenList[-1] in self.NonEndingOpcode:\r
30fdf114
LG
264 EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-1],\r
265 ExtraData=str(self))\r
31ff1c44 266 if self.TokenList[-1] == DEPEX_OPCODE_END and self.TokenList[-2] in self.NonEndingOpcode:\r
30fdf114
LG
267 EdkLogger.error("GenDepex", PARSER_ERROR, "Extra %s at the end of the dependency expression" % self.TokenList[-2],\r
268 ExtraData=str(self))\r
31ff1c44 269 if DEPEX_OPCODE_END in self.TokenList and DEPEX_OPCODE_END != self.TokenList[-1]:\r
30fdf114
LG
270 EdkLogger.error("GenDepex", PARSER_ERROR, "Extra expressions after END",\r
271 ExtraData=str(self))\r
272\r
273 ## Simply optimize the dependency expression by removing duplicated operands\r
274 def Optimize(self):\r
275 ValidOpcode = list(set(self.OpcodeList))\r
31ff1c44 276 if len(ValidOpcode) != 1 or ValidOpcode[0] not in [DEPEX_OPCODE_AND, DEPEX_OPCODE_OR]:\r
30fdf114
LG
277 return\r
278 Op = ValidOpcode[0]\r
279 NewOperand = []\r
280 AllOperand = set()\r
281 for Token in self.PostfixNotation:\r
282 if Token in self.SupportedOpcode or Token in NewOperand:\r
283 continue\r
284 AllOperand.add(Token)\r
31ff1c44
CJ
285 if Token == DEPEX_OPCODE_TRUE:\r
286 if Op == DEPEX_OPCODE_AND:\r
30fdf114
LG
287 continue\r
288 else:\r
289 NewOperand.append(Token)\r
290 break\r
31ff1c44
CJ
291 elif Token == DEPEX_OPCODE_FALSE:\r
292 if Op == DEPEX_OPCODE_OR:\r
30fdf114
LG
293 continue\r
294 else:\r
295 NewOperand.append(Token)\r
296 break\r
297 NewOperand.append(Token)\r
298\r
299 # don't generate depex if only TRUE operand left\r
31ff1c44 300 if self.ModuleType == SUP_MODULE_PEIM and len(NewOperand) == 1 and NewOperand[0] == DEPEX_OPCODE_TRUE:\r
30fdf114 301 self.PostfixNotation = []\r
47fea6af 302 return\r
30fdf114
LG
303\r
304 # don't generate depex if all operands are architecture protocols\r
8bb63e37 305 if self.ModuleType in [SUP_MODULE_UEFI_DRIVER, SUP_MODULE_DXE_DRIVER, SUP_MODULE_DXE_RUNTIME_DRIVER, SUP_MODULE_DXE_SAL_DRIVER, SUP_MODULE_DXE_SMM_DRIVER, SUP_MODULE_MM_STANDALONE] and \\r
31ff1c44 306 Op == DEPEX_OPCODE_AND and \\r
30fdf114
LG
307 self.ArchProtocols == set([GuidStructureStringToGuidString(Guid) for Guid in AllOperand]):\r
308 self.PostfixNotation = []\r
309 return\r
310\r
311 if len(NewOperand) == 0:\r
312 self.TokenList = list(AllOperand)\r
313 else:\r
314 self.TokenList = []\r
315 while True:\r
316 self.TokenList.append(NewOperand.pop(0))\r
317 if NewOperand == []:\r
318 break\r
319 self.TokenList.append(Op)\r
320 self.PostfixNotation = []\r
321 self.GetPostfixNotation()\r
322\r
323\r
324 ## Convert a GUID value in C structure format into its binary form\r
325 #\r
326 # @param Guid The GUID value in C structure format\r
327 #\r
328 # @retval array The byte array representing the GUID value\r
329 #\r
330 def GetGuidValue(self, Guid):\r
331 GuidValueString = Guid.replace("{", "").replace("}", "").replace(" ", "")\r
332 GuidValueList = GuidValueString.split(",")\r
333 if len(GuidValueList) != 11:\r
334 EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid GUID value string or opcode: %s" % Guid)\r
335 return pack("1I2H8B", *(int(value, 16) for value in GuidValueList))\r
336\r
337 ## Save the binary form of dependency expression in file\r
338 #\r
339 # @param File The path of file. If None is given, put the data on console\r
340 #\r
341 # @retval True If the file doesn't exist or file is changed\r
342 # @retval False If file exists and is not changed.\r
343 #\r
344 def Generate(self, File=None):\r
345 Buffer = StringIO()\r
346 if len(self.PostfixNotation) == 0:\r
347 return False\r
348\r
349 for Item in self.PostfixNotation:\r
350 if Item in self.Opcode[self.Phase]:\r
351 Buffer.write(pack("B", self.Opcode[self.Phase][Item]))\r
352 elif Item in self.SupportedOpcode:\r
353 EdkLogger.error("GenDepex", FORMAT_INVALID,\r
354 "Opcode [%s] is not expected in %s phase" % (Item, self.Phase),\r
355 ExtraData=self.ExpressionString)\r
356 else:\r
357 Buffer.write(self.GetGuidValue(Item))\r
358\r
359 FilePath = ""\r
360 FileChangeFlag = True\r
4231a819 361 if File is None:\r
30fdf114
LG
362 sys.stdout.write(Buffer.getvalue())\r
363 FilePath = "STDOUT"\r
364 else:\r
365 FileChangeFlag = SaveFileOnChange(File, Buffer.getvalue(), True)\r
366\r
367 Buffer.close()\r
368 return FileChangeFlag\r
369\r
b36d134f 370versionNumber = ("0.04" + " " + gBUILD_VERSION)\r
30fdf114 371__version__ = "%prog Version " + versionNumber\r
31ff1c44 372__copyright__ = "Copyright (c) 2007-2018, Intel Corporation All rights reserved."\r
30fdf114
LG
373__usage__ = "%prog [options] [dependency_expression_file]"\r
374\r
375## Parse command line options\r
376#\r
377# @retval OptionParser\r
378#\r
379def GetOptions():\r
380 from optparse import OptionParser\r
381\r
382 Parser = OptionParser(description=__copyright__, version=__version__, usage=__usage__)\r
383\r
384 Parser.add_option("-o", "--output", dest="OutputFile", default=None, metavar="FILE",\r
385 help="Specify the name of depex file to be generated")\r
386 Parser.add_option("-t", "--module-type", dest="ModuleType", default=None,\r
387 help="The type of module for which the dependency expression serves")\r
388 Parser.add_option("-e", "--dependency-expression", dest="Expression", default="",\r
389 help="The string of dependency expression. If this option presents, the input file will be ignored.")\r
390 Parser.add_option("-m", "--optimize", dest="Optimize", default=False, action="store_true",\r
391 help="Do some simple optimization on the expression.")\r
392 Parser.add_option("-v", "--verbose", dest="verbose", default=False, action="store_true",\r
393 help="build with verbose information")\r
394 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
395 Parser.add_option("-q", "--quiet", dest="quiet", default=False, action="store_true",\r
396 help="build with little information")\r
397\r
398 return Parser.parse_args()\r
399\r
400\r
401## Entrance method\r
402#\r
403# @retval 0 Tool was successful\r
404# @retval 1 Tool failed\r
405#\r
406def Main():\r
407 EdkLogger.Initialize()\r
408 Option, Input = GetOptions()\r
409\r
410 # Set log level\r
411 if Option.quiet:\r
412 EdkLogger.SetLevel(EdkLogger.QUIET)\r
413 elif Option.verbose:\r
414 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
4231a819 415 elif Option.debug is not None:\r
30fdf114
LG
416 EdkLogger.SetLevel(Option.debug + 1)\r
417 else:\r
418 EdkLogger.SetLevel(EdkLogger.INFO)\r
419\r
420 try:\r
4231a819 421 if Option.ModuleType is None or Option.ModuleType not in gType2Phase:\r
30fdf114
LG
422 EdkLogger.error("GenDepex", OPTION_MISSING, "Module type is not specified or supported")\r
423\r
424 DxsFile = ''\r
425 if len(Input) > 0 and Option.Expression == "":\r
426 DxsFile = Input[0]\r
427 DxsString = open(DxsFile, 'r').read().replace("\n", " ").replace("\r", " ")\r
428 DxsString = gStartClosePattern.sub("\\1", DxsString)\r
429 elif Option.Expression != "":\r
430 if Option.Expression[0] == '"':\r
431 DxsString = Option.Expression[1:-1]\r
432 else:\r
433 DxsString = Option.Expression\r
434 else:\r
435 EdkLogger.error("GenDepex", OPTION_MISSING, "No expression string or file given")\r
436\r
437 Dpx = DependencyExpression(DxsString, Option.ModuleType, Option.Optimize)\r
4231a819 438 if Option.OutputFile is not None:\r
14c48571 439 FileChangeFlag = Dpx.Generate(Option.OutputFile)\r
47fea6af 440 if not FileChangeFlag and DxsFile:\r
14c48571 441 #\r
442 # Touch the output file if its time stamp is older than the original\r
443 # DXS file to avoid re-invoke this tool for the dependency check in build rule.\r
444 #\r
445 if os.stat(DxsFile)[8] > os.stat(Option.OutputFile)[8]:\r
446 os.utime(Option.OutputFile, None)\r
30fdf114
LG
447 else:\r
448 Dpx.Generate()\r
449 except BaseException, X:\r
450 EdkLogger.quiet("")\r
4231a819 451 if Option is not None and Option.debug is not None:\r
30fdf114
LG
452 EdkLogger.quiet(traceback.format_exc())\r
453 else:\r
454 EdkLogger.quiet(str(X))\r
455 return 1\r
456\r
457 return 0\r
458\r
459if __name__ == '__main__':\r
460 sys.exit(Main())\r
461\r