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