8e75db9b03174c362e0968f37af1db9a59ee7186
[people/mcb30/basetools.git] / Source / Python / AutoGen / AutoGen.py
1 ## @file\r
2 # Generate AutoGen.h, AutoGen.c and *.depex files\r
3 #\r
4 # Copyright (c) 2007, Intel Corporation\r
5 # All rights reserved. This program and the accompanying materials\r
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 ## Import Modules\r
15 #\r
16 import sys\r
17 import os\r
18 import re\r
19 import os.path as path\r
20 import imp\r
21 from optparse import OptionParser\r
22 from optparse import make_option\r
23 \r
24 import Common.EdkLogger\r
25 import GenC\r
26 import GenMake\r
27 import GenDepex\r
28 \r
29 from BuildInfo import *\r
30 from StrGather import *\r
31 from BuildEngine import *\r
32 \r
33 from Common.BuildToolError import *\r
34 from Common.EdkIIWorkspaceBuild import *\r
35 from Common.EdkIIWorkspace import *\r
36 from Common.DataType import *\r
37 from Common.Misc import *\r
38 from Common.String import *\r
39 \r
40 ## PlatformBuildClassObject database\r
41 gPlatformDatabase = {}      # {arch : {dsc file path : PlatformBuildClassObject}}\r
42 \r
43 ## ModuleBuildClassObject database\r
44 gModuleDatabase = {}        # {arch : {inf file path : ModuleBuildClassObject}}\r
45 \r
46 ## PackageBuildClassObject database\r
47 gPackageDatabase = {}       # {arch : {dec file path : PackageBuildClassObject}}\r
48 \r
49 ## AutoGen object database\r
50 gAutoGenDatabase = {}       # (module/package/platform obj, BuildTarget, ToolChain, Arch) : build info\r
51 \r
52 ## Shortcut global of WorkspaceBuild object representing current workspace\r
53 gWorkspace = None\r
54 \r
55 ## Shortcut global of current workspace directory\r
56 gWorkspaceDir = ""\r
57 \r
58 ## Regular expression for splitting Dependency Expression stirng into tokens\r
59 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
60 \r
61 ## Mapping Makefile type\r
62 gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}\r
63 \r
64 ## Default output flag for all tools\r
65 gDefaultOutputFlag = "-o "\r
66 \r
67 ## Output flags for specific tools\r
68 gOutputFlag = {\r
69     ("MSFT", "CC", "OUTPUT")      :   "/Fo",\r
70     ("MSFT", "SLINK", "OUTPUT")   :   "/OUT:",\r
71     ("MSFT", "DLINK", "OUTPUT")   :   "/OUT:",\r
72     ("MSFT", "ASMLINK", "OUTPUT") :   "/OUT:",\r
73     ("MSFT", "PCH", "OUTPUT")     :   "/Fp",\r
74     ("MSFT", "ASM", "OUTPUT")     :   "/Fo",\r
75 \r
76     ("INTEL", "CC", "OUTPUT")          :   "/Fo",\r
77     ("INTEL", "SLINK", "OUTPUT")       :   "/OUT:",\r
78     ("INTEL", "DLINK", "OUTPUT")       :   "/OUT:",\r
79     ("INTEL", "ASMLINK", "OUTPUT")     :   "/OUT:",\r
80     ("INTEL", "PCH", "OUTPUT")         :   "/Fp",\r
81     ("INTEL", "ASM", "OUTPUT")         :   "/Fo",\r
82 \r
83     ("GCC", "CC", "OUTPUT")        :   "-o ",\r
84     ("GCC", "SLINK", "OUTPUT")     :   "-cr ",\r
85     ("GCC", "DLINK", "OUTPUT")     :   "-o ",\r
86     ("GCC", "ASMLINK", "OUTPUT")   :   "-o ",\r
87     ("GCC", "PCH", "OUTPUT")       :   "-o ",\r
88     ("GCC", "ASM", "OUTPUT")       :   "-o ",\r
89 }\r
90 \r
91 ## Flag for include file search path\r
92 gIncludeFlag = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}\r
93 \r
94 ## Build rule configuration file\r
95 gBuildRuleFile = 'Conf/build_rule.txt'\r
96 \r
97 ## default file name for AutoGen\r
98 gAutoGenCodeFileName = "AutoGen.c"\r
99 gAutoGenHeaderFileName = "AutoGen.h"\r
100 gAutoGenDepexFileName = "%(module_name)s.depex"\r
101 \r
102 ## Find the package containing the module\r
103 #\r
104 # Find out the package which contains the given module, according to the path\r
105 # of the module and the package.\r
106 #\r
107 # @param  Module            The module to be found for\r
108 # @param  PackageDatabase   Database containing all packages found\r
109 #\r
110 # @retval package           Package object if found\r
111 # @retval None              None if not found\r
112 #\r
113 def FindModuleOwnerPackage(Module, PackageDatabase):\r
114     for PackagePath in PackageDatabase:\r
115         PackageDir = path.dirname(PackagePath)\r
116         #\r
117         # if package's path is the first part of module's path, bingo!\r
118         #\r
119         if str(Module).find(PackageDir) == 0:\r
120             return PackageDatabase[PackagePath]\r
121     # nothing found\r
122     return None\r
123 \r
124 ## AutoGen class\r
125 #\r
126 # This class encapsules the AutoGen behaviors for the build tools. In addition to\r
127 # the generation of AutoGen.h and AutoGen.c, it can generate *.depex file according\r
128 # to the [depex] section in module's inf file. The result of parsing unicode file\r
129 # has been incorporated either.\r
130 #\r
131 class AutoGen(object):\r
132 \r
133     def __init__(self, ModuleFile, PlatformFile, Workspace, Target, Toolchain, Arch):\r
134         global gModuleDatabase, gPackageDatabase, gPlatformDatabase, gAutoGenDatabase, gWorkspace, gWorkspaceDir, gBuildRuleDatabase\r
135 \r
136         if ModuleFile != None:\r
137             ModuleFile = NormPath(str(ModuleFile))\r
138         if PlatformFile != None:\r
139             PlatformFile = NormPath(str(PlatformFile))\r
140 \r
141         if gWorkspace == None:\r
142             gWorkspace = Workspace\r
143         if gWorkspaceDir == "":\r
144             gWorkspaceDir = Workspace.WorkspaceDir\r
145 \r
146         if gModuleDatabase == {}:\r
147             for a in Workspace.Build:\r
148                 gModuleDatabase[a] = gWorkspace.Build[a].ModuleDatabase\r
149         if gPackageDatabase == {}:\r
150             for a in Workspace.Build:\r
151                 gPackageDatabase[a] = gWorkspace.Build[a].PackageDatabase\r
152         if gPlatformDatabase == {}:\r
153             for a in Workspace.Build:\r
154                 gPlatformDatabase[a] = gWorkspace.Build[a].PlatformDatabase\r
155 \r
156         self.ToolChain = Toolchain\r
157         self.ToolChainFamily = "MSFT"\r
158         self.BuildTarget = Target\r
159         self.IsMakefileCreated = False\r
160         self.IsAutoGenCodeCreated = False\r
161 \r
162         Key = (self.BuildTarget, self.ToolChain, str(PlatformFile))\r
163         if ModuleFile == None:\r
164             #\r
165             # autogen for platform\r
166             #\r
167             self.PlatformBuildInfo = {}     # arch : PlatformBuildInfo Object\r
168             self.Platform = {}\r
169             self.IsPlatformAutoGen = True\r
170             if type(Arch) == type([]):\r
171                 self.Arch = Arch\r
172             else:\r
173                 self.Arch = [Arch]\r
174             EdkLogger.verbose("")\r
175             EdkLogger.verbose("\nAutoGen platform [%s] %s" % (PlatformFile, self.Arch))\r
176 \r
177             self.Platform = {}\r
178             self.BuildInfo = {}\r
179             for a in self.Arch:\r
180                 if a not in gPlatformDatabase or str(PlatformFile) not in gPlatformDatabase[a]:\r
181                     raise AutoGenError(msg="[%s] is not the active platform, or %s is not supported by the active platform!" % (PlatformFile, a))\r
182                 p = gPlatformDatabase[a][str(PlatformFile)]\r
183                 self.Platform[a] = p\r
184                 self.BuildInfo[a] = self.GetPlatformBuildInfo(p, self.BuildTarget, self.ToolChain, a)\r
185             gAutoGenDatabase[Key] = self\r
186             return\r
187         elif Key not in gAutoGenDatabase:\r
188             gAutoGenDatabase[Key] = AutoGen(None, PlatformFile, Workspace, Target, Toolchain, Arch)\r
189 \r
190         #\r
191         # autogen for module\r
192         #\r
193         self.IsPlatformAutoGen = False\r
194         if type(Arch) == type([]):\r
195             if len(Arch) > 1:\r
196                 raise AutoGenError(msg="Cannot AutoGen a module for more than one platform object at a time!")\r
197             self.Arch = Arch[0]\r
198         else:\r
199             self.Arch = Arch\r
200         EdkLogger.verbose("")\r
201         EdkLogger.verbose("AutoGen module [%s] [%s]" % (ModuleFile, self.Arch))\r
202 \r
203         if self.Arch not in gPlatformDatabase or str(PlatformFile) not in gPlatformDatabase[Arch]:\r
204             raise AutoGenError(msg="[%s] is not the active platform, or %s is not supported by the platform!" % (PlatformFile, self.Arch))\r
205         if self.Arch not in gModuleDatabase or str(ModuleFile) not in gModuleDatabase[self.Arch]:\r
206             raise AutoGenError(msg="[%s] architecture %s is not supported by active platform [%s]!" % (ModuleFile, self.Arch, PlatformFile))\r
207 \r
208         self.Platform = gPlatformDatabase[Arch][str(PlatformFile)]\r
209         if str(ModuleFile) not in self.Platform.Modules and str(ModuleFile) not in self.Platform.Libraries:\r
210             raise AutoGenError(msg="Cannot find module %s for architecture [%s] in the active platform:\n\t%s\n" % (ModuleFile, self.Arch, self.Platform))\r
211         self.Module = gModuleDatabase[Arch][str(ModuleFile)]\r
212 \r
213         self.Package = FindModuleOwnerPackage(self.Module, gPackageDatabase[Arch])\r
214 \r
215         self.AutoGenC = TemplateString()\r
216         self.AutoGenH = TemplateString()\r
217 \r
218         self.BuildInfo = None\r
219         self.GetModuleBuildInfo()\r
220         gAutoGenDatabase[self.BuildTarget, self.ToolChain, self.Arch, self.Module] = self\r
221 \r
222     def GetModuleBuildInfo(self):\r
223         Key = (self.BuildTarget, self.ToolChain, self.Arch, self.Module)\r
224         if Key in gAutoGenDatabase:\r
225             self.BuildInfo = gAutoGenDatabase[Key].BuildInfo\r
226             self.IsAutoGenCodeCreated = gAutoGenDatabase[Key].IsAutoGenCodeCreated\r
227             self.IsMakefileCreated = gAutoGenDatabase[Key].IsMakefileCreated\r
228             return gAutoGenDatabase[Key].BuildInfo\r
229 \r
230         Info = ModuleBuildInfo(self.Module)\r
231         self.BuildInfo = Info\r
232         Info.PlatformInfo = self.GetPlatformBuildInfo(self.Platform, self.BuildTarget, self.ToolChain, self.Arch)\r
233 \r
234         # basic information\r
235         Info.WorkspaceDir = gWorkspaceDir\r
236         Info.BuildTarget = self.BuildTarget\r
237         Info.ToolChain = self.ToolChain\r
238         Info.Arch = self.Arch\r
239         Info.IsBinary = False\r
240         Info.BaseName = self.Module.BaseName\r
241         Info.FileBase, Info.FileExt = path.splitext(path.basename(self.Module.DescFilePath))\r
242         Info.SourceDir = path.dirname(self.Module.DescFilePath)\r
243         Info.BuildDir = os.path.join(Info.PlatformInfo.BuildDir,\r
244                                      Info.Arch,\r
245                                      Info.SourceDir,\r
246                                      Info.FileBase)\r
247         Info.OutputDir = os.path.join(Info.BuildDir, "OUTPUT")\r
248         Info.DebugDir = os.path.join(Info.BuildDir, "DEBUG")\r
249         Info.MakefileDir = Info.BuildDir\r
250         if os.path.isabs(Info.BuildDir):\r
251             CreateDirectory(Info.OutputDir)\r
252             CreateDirectory(Info.DebugDir)\r
253         else:\r
254             CreateDirectory(os.path.join(gWorkspaceDir, Info.OutputDir))\r
255             CreateDirectory(os.path.join(gWorkspaceDir, Info.DebugDir))\r
256 \r
257         for Type in self.Module.CustomMakefile:\r
258             MakeType = gMakeTypeMap[Type]\r
259             Info.CustomMakefile[MakeType] = os.path.join(Info.SourceDir, self.Module.CustomMakefile[Type])\r
260 \r
261         if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
262             Info.IsLibrary = True\r
263             Info.DependentLibraryList = []\r
264         else:\r
265             Info.IsLibrary = False\r
266             Info.DependentLibraryList = self.GetSortedLibraryList()\r
267 \r
268         Info.DependentPackageList = self.GetDependentPackageList()\r
269         Info.DerivedPackageList = self.GetDerivedPackageList()\r
270 \r
271         Info.BuildOption = self.GetModuleBuildOption(Info.PlatformInfo)\r
272         if "DLINK" in Info.PlatformInfo.ToolStaticLib:\r
273             Info.SystemLibraryList = Info.PlatformInfo.ToolStaticLib["DLINK"]\r
274 \r
275         Info.PcdIsDriver = self.Module.PcdIsDriver\r
276         Info.PcdList = self.GetPcdList(Info.DependentLibraryList)\r
277         Info.GuidList = self.GetGuidList()\r
278         Info.ProtocolList = self.GetProtocolGuidList()\r
279         Info.PpiList = self.GetPpiGuidList()\r
280         Info.MacroList = self.GetMacroList()\r
281         Info.DepexList = self.GetDepexTokenList(Info)\r
282 \r
283         Info.IncludePathList = [Info.SourceDir, Info.DebugDir]\r
284         Info.IncludePathList.extend(self.GetIncludePathList(Info.DependentPackageList))\r
285 \r
286         Info.SourceFileList = self.GetBuildFileList(Info.PlatformInfo)\r
287         Info.AutoGenFileList = self.GetAutoGenFileList(Info)\r
288 \r
289         return Info\r
290 \r
291     def InitPackageBuildInfo(self, Info):\r
292         Info.SourceDir = path.dirname(Info.Package.DescFilePath)\r
293         Info.IncludePathList.append(Info.SourceDir)\r
294         for Inc in Info.Package.Includes:\r
295             Info.IncludePathList.append(os.path.join(Info.SourceDir, Inc))\r
296 \r
297     def GetPlatformBuildInfo(self, Platform, Target, Toolchain, Arch):\r
298         Key = Target, Toolchain, Platform\r
299         PlatformAutoGen = None\r
300         if Key in gAutoGenDatabase:\r
301             PlatformAutoGen = gAutoGenDatabase[Key]\r
302             if type(PlatformAutoGen.BuildInfo) == type({}):\r
303                 if Arch in PlatformAutoGen.BuildInfo:\r
304                     return PlatformAutoGen.BuildInfo[Arch]\r
305             else:\r
306                 return PlatformAutoGen.BuildInfo\r
307 \r
308         Info = PlatformBuildInfo(Platform)\r
309 \r
310         Info.Arch = Arch\r
311         Info.ToolChain = self.ToolChain\r
312         Info.BuildTarget = self.BuildTarget\r
313 \r
314         Info.WorkspaceDir = gWorkspace.WorkspaceDir\r
315         Info.SourceDir = path.dirname(Platform.DescFilePath)\r
316         Info.OutputDir = Platform.OutputDirectory\r
317         Info.BuildDir = path.join(Info.OutputDir, self.BuildTarget + "_" + self.ToolChain)\r
318         Info.MakefileDir = Info.BuildDir\r
319         if gWorkspace.Fdf != "":\r
320             Info.FdfFile= path.join(gWorkspaceDir, gWorkspace.Fdf)\r
321 \r
322         Info.DynamicPcdList = self.GetDynamicPcdList(Platform, Arch)\r
323         Info.PcdTokenNumber = self.GeneratePcdTokenNumber(Platform, Info.DynamicPcdList)\r
324         Info.PackageList = gPackageDatabase[Arch].values()\r
325 \r
326         self.ProcessToolDefinition(Info)\r
327         Info.BuildRule = self.GetBuildRule()\r
328         Info.FdTargetList = gWorkspace.FdTargetList\r
329         Info.FvTargetList = gWorkspace.FvTargetList\r
330 \r
331         if PlatformAutoGen != None:\r
332             if type(PlatformAutoGen.BuildInfo) == type({}):\r
333                 PlatformAutoGen.BuildInfo[Arch] = Info\r
334             else:\r
335                 PlatformAutoGen.BuildInfo = Info\r
336         return Info\r
337 \r
338     def GetMakefileDir(self):\r
339         if self.IsPlatformAutoGen:\r
340             return self.BuildInfo[self.Arch[0]].MakefileDir\r
341         else:\r
342             return self.BuildInfo.MakefileDir\r
343 \r
344     def GetBuildRule(self):\r
345         return BuildRule(gWorkspace.WorkspaceFile(gBuildRuleFile))\r
346 \r
347     def GetDerivedPackageList(self):\r
348         PackageList = []\r
349         for M in [self.Module] + self.BuildInfo.DependentLibraryList:\r
350             for Package in M.Packages:\r
351                 if Package not in PackageList:\r
352                     PackageList.append(gPackageDatabase[self.Arch][Package])\r
353         return PackageList\r
354 \r
355     def GetDepexTokenList(self, Info):\r
356         Dxs = self.Module.Depex\r
357         if Dxs == None or Dxs == "":\r
358             return []\r
359 \r
360         #\r
361         # Append depex from dependent libraries\r
362         #\r
363         for Lib in Info.DependentLibraryList:\r
364             if Lib.Depex != None and Lib.Depex != "":\r
365                 Dxs += " AND (" + Lib.Depex + ")"\r
366                 EdkLogger.verbose("DEPEX string (+%s) = %s" % (Lib.BaseName, Dxs))\r
367         if Dxs == "":\r
368             return []\r
369 \r
370         TokenList = gDepexTokenPattern.findall(Dxs)\r
371         EdkLogger.debug(EdkLogger.DEBUG_8, "TokenList(raw) = %s" % (TokenList))\r
372         for I in range(0, len(TokenList)):\r
373             Token = TokenList[I].strip()\r
374             if Token.endswith(".inf"):  # module file name\r
375                 ModuleFile = os.path.normpath(Token)\r
376                 Token = gModuleDatabase[ModuleFile].Guid\r
377             elif Token.upper() in GenDepex.DependencyExpression.SupportedOpcode: # Opcode name\r
378                 Token = Token.upper()\r
379             elif Token not in ['(', ')']:   # GUID C Name\r
380                 GuidCName = Token\r
381                 for P in Info.DerivedPackageList:\r
382                     if GuidCName in P.Protocols:\r
383                         Token = P.Protocols[GuidCName]\r
384                         break\r
385                     elif GuidCName in P.Ppis:\r
386                         Token = P.Ppis[GuidCName]\r
387                         break\r
388                     elif GuidCName in P.Guids:\r
389                         Token = P.Guids[GuidCName]\r
390                         break\r
391                 else:\r
392                     PackageListString = "\n\t".join([str(P) for P in self.BuildInfo.DerivedPackageList])\r
393                     raise AutoGenError(msg="GUID [%s] used in module [%s] cannot be found in dependent packages!\n\t%s"\r
394                                        % (GuidCName, self.Module, PackageListString))\r
395             TokenList[I] = Token\r
396         EdkLogger.debug(EdkLogger.DEBUG_8, "TokenList(guid) = %s" % " ".join(TokenList))\r
397         return TokenList\r
398 \r
399     def GetMacroList(self):\r
400         return ["%s %s" % (Name, self.Module.Specification[Name]) for Name in self.Module.Specification]\r
401 \r
402     def ProcessToolDefinition(self, Info):\r
403         ToolDefinition = gWorkspace.ToolDef.ToolsDefTxtDictionary\r
404         ToolCodeList = gWorkspace.ToolDef.ToolsDefTxtDatabase["COMMAND_TYPE"]\r
405         for Tool in ToolCodeList:\r
406             KeyBaseString = "%s_%s_%s_%s" % (Info.BuildTarget, Info.ToolChain, Info.Arch, Tool)\r
407 \r
408             Key = "%s_PATH" % KeyBaseString\r
409             if Key not in ToolDefinition:\r
410                 continue\r
411             Path = ToolDefinition[Key]\r
412 \r
413             Key = "%s_FAMILY" % KeyBaseString\r
414             if Key in ToolDefinition:\r
415                 Family = ToolDefinition[Key]\r
416             else:\r
417                 Family = ""\r
418 \r
419             Key = "%s_FLAGS" % KeyBaseString\r
420             if Key in ToolDefinition:\r
421                 Option = ToolDefinition[Key]\r
422             else:\r
423                 Option = ""\r
424 \r
425             Key = "%s_DLL" % KeyBaseString\r
426             if Key in ToolDefinition:\r
427                 Dll = ToolDefinition[Key]\r
428                 os.environ["PATH"] = Dll + os.pathsep + os.environ["PATH"]\r
429             else:\r
430                 Dll = ""\r
431 \r
432             Key = KeyBaseString + "_OUTPUT"\r
433             if Key in ToolDefinition:\r
434                 OutputFlag = ToolDefinition[Key]\r
435             elif (Family, Tool, "OUTPUT") in gOutputFlag:\r
436                 OutputFlag = gOutputFlag[Family, Tool, "OUTPUT"]\r
437                 if OutputFlag[0] == '"' and OutputFlag[-1] == '"':\r
438                     OutputFlag = OutputFlag[1:-1]\r
439             else:\r
440                 OutputFlag = gDefaultOutputFlag\r
441 \r
442             InputFlag = gIncludeFlag[Family]\r
443 \r
444             Info.ToolPath[Tool] = Path\r
445             Info.ToolDynamicLib[Tool] = Dll\r
446             Info.ToolChainFamily[Tool] = Family\r
447             Info.DefaultToolOption[Tool] = Option\r
448             Info.OutputFlag[Tool] = OutputFlag\r
449             Info.IncludeFlag[Tool] = InputFlag\r
450 \r
451         self.ToolChainFamily = Info.ToolChainFamily["CC"]\r
452         if self.IsPlatformAutoGen:\r
453             BuildOptions = self.Platform[Info.Arch].BuildOptions\r
454         else:\r
455             BuildOptions = self.Platform.BuildOptions\r
456 \r
457         for Key in BuildOptions:\r
458             Family = Key[0]\r
459             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
460             if Tool not in Info.ToolPath:\r
461                 continue\r
462             if Family != None and Family != "" and Family != Info.ToolChainFamily[Tool]:\r
463                 continue\r
464             if Target == "*" or Target == Info.BuildTarget:\r
465                 if Tag == "*" or Tag == Info.ToolChain:\r
466                     if Arch == "*" or Arch == Info.Arch:\r
467                         Info.BuildOption[Tool] = BuildOptions[Key]\r
468         for Tool in Info.DefaultToolOption:\r
469             if Tool not in Info.BuildOption:\r
470                 Info.BuildOption[Tool] = ""\r
471 \r
472     def GetModuleBuildOption(self, PlatformInfo):\r
473         BuildOption = self.Module.BuildOptions\r
474         OptionList = {}\r
475         for Key in BuildOption:\r
476             Family = Key[0]\r
477             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
478             if Tool not in PlatformInfo.ToolPath:\r
479                 continue\r
480             if Family != None and Family != "" and Family != PlatformInfo.ToolChainFamily[Tool]:\r
481                 continue\r
482             if Target == "*" or Target == self.BuildTarget:\r
483                 if Tag == "*" or Tag == self.ToolChain:\r
484                     if Arch == "*" or Arch == self.Arch:\r
485                         OptionList[Tool] = BuildOption[Key]\r
486         for Tool in PlatformInfo.DefaultToolOption:\r
487             if Tool not in OptionList:\r
488                 OptionList[Tool] = ""\r
489 \r
490         return OptionList\r
491 \r
492     def GetBuildFileList(self, PlatformInfo):\r
493         ToolChainFamily = PlatformInfo.ToolChainFamily["CC"]\r
494         BuildRule = PlatformInfo.BuildRule\r
495         BuildFileList = []\r
496         for F in self.Module.Sources:\r
497             SourceFile = F.SourceFile\r
498             # ToolCode = F.ToolCode\r
499             if F.TagName != "" and F.TagName != self.ToolChain:\r
500                 EdkLogger.verbose("The toolchain [%s] for processing file [%s] is found, "\r
501                                   "but [%s] is needed" % (F.TagName, F.SourceFile, self.ToolChain))\r
502                 continue\r
503             if F.ToolChainFamily != "" and F.ToolChainFamily != ToolChainFamily:\r
504                 EdkLogger.verbose("The file [%s] must be built by tools of [%s], "\r
505                                   "but current toolchain family is [%s]" % (SourceFile, F.ToolChainFamily, ToolChainFamily))\r
506                 continue\r
507 \r
508             Dir = path.dirname(SourceFile)\r
509             if Dir != "":\r
510                 Dir = path.join(self.BuildInfo.SourceDir, Dir)\r
511                 if Dir not in self.BuildInfo.IncludePathList:\r
512                     self.BuildInfo.IncludePathList.insert(0, Dir)\r
513 \r
514             # skip unknown file\r
515             Base, Ext = path.splitext(SourceFile)\r
516 \r
517             # skip file which needs a tool having no matching toolchain family\r
518             FileType, RuleObject = BuildRule.Get(Ext, ToolChainFamily)\r
519             if FileType == None:\r
520                 EdkLogger.verbose("Don't know how to process file [%s]." % SourceFile)\r
521                 continue\r
522 \r
523             # unicode must be processed by AutoGen\r
524             if FileType == "Unicode-Text-File":\r
525                 self.BuildInfo.UnicodeFileList.append(os.path.join(gWorkspaceDir, self.BuildInfo.SourceDir, SourceFile))\r
526                 continue\r
527 \r
528             # no command, no build\r
529             if RuleObject == None or RuleObject.CommandList == []:\r
530                 Buildable = False\r
531                 EdkLogger.warn("No rule or command defined for building [%s], ignore file [%s]" % (FileType, SourceFile))\r
532                 continue\r
533 \r
534             BuildFileList.append([SourceFile, FileType, RuleObject])\r
535 \r
536         return BuildFileList\r
537 \r
538     def GetToolChainFamily(self, FileType):\r
539         PlatformInfo = self.BuildInfo.PlatformInfo\r
540         ToolChainFamily = PlatformInfo.ToolChainFamily\r
541         if FileType not in gBuildRuleDatabase[ToolChainFamily]:\r
542             for Family in gBuildRuleDatabase:\r
543                 if FileType in gBuildRuleDatabase[Family]:\r
544                     ToolChainFamily = Family\r
545                     break\r
546             else:\r
547                 return ""\r
548         FileBuildRule = gBuildRuleDatabase[ToolChainFamily][FileType]\r
549         ToolCodeList = FileBuildRule.ToolList\r
550 \r
551         ToolChainFamily = ""\r
552         for ToolCode in ToolCodeList:\r
553             # if one tool is not defined in current toolchain, break the build\r
554             if ToolCode in PlatformInfo.ToolChainFamily:\r
555                 ToolChainFamily = PlatformInfo.ToolChainFamily[ToolCode]\r
556                 break\r
557 \r
558         return ToolChainFamily\r
559 \r
560     def GetDependentPackageList(self):\r
561         #if self.Package != None and self.Package not in self.Module.Packages:\r
562         #    self.Module.Packages.insert(0, str(self.Package))\r
563 \r
564         if self.Arch not in gPackageDatabase:\r
565             raise AutoGenError(msg="[%s] is not supported!")\r
566         PackageDatabase = gPackageDatabase[self.Arch]\r
567 \r
568         PackageList = []\r
569         for PackageFile in self.Module.Packages:\r
570             if PackageFile in PackageList:\r
571                 continue\r
572             if PackageFile not in PackageDatabase:\r
573                 raise AutoGenError(FILE_NOT_FOUND, name=PackageFile)\r
574             PackageList.append(PackageDatabase[PackageFile])\r
575         return PackageList\r
576 \r
577     def GetAutoGenFileList(self, BuildInfo):\r
578         GenC.CreateCode(BuildInfo, self.AutoGenC, self.AutoGenH)\r
579         FileList = []\r
580         if self.AutoGenC.String != "":\r
581             FileList.append("AutoGen.c")\r
582         if self.AutoGenH.String != "":\r
583             FileList.append("AutoGen.h")\r
584         return FileList\r
585 \r
586     def GetSortedLibraryList(self):\r
587         LibraryList = []\r
588         ModuleDatabase = gModuleDatabase[self.Arch]\r
589         for Key in self.Module.LibraryClasses:\r
590             Library = ModuleDatabase[self.Module.LibraryClasses[Key]]\r
591             if Library not in LibraryList:\r
592                 LibraryList.append(Library)\r
593         return LibraryList\r
594 \r
595     def GetDynamicPcdList(self, Platform, Arch):\r
596         PcdList = []\r
597         NotFoundPcdList = set()\r
598         NoDatumTypePcdList = set()\r
599         PcdConsumerList = set()\r
600         for F in Platform.Modules:\r
601             M = gModuleDatabase[Arch][F]\r
602             for Key in M.Pcds:\r
603                 PcdFromModule = M.Pcds[Key]\r
604                 if not PcdFromModule.IsOverrided:\r
605                     NotFoundPcdList.add(" | ".join(Key))\r
606                     PcdConsumerList.add(str(M))\r
607                     continue\r
608 \r
609                 if Key not in Platform.Pcds:\r
610                     PcdFromPlatform = PcdFromModule\r
611                 else:\r
612                     PcdFromPlatform = Platform.Pcds[Key]\r
613 \r
614                 if PcdFromModule.DatumType == "VOID*" and PcdFromPlatform.MaxDatumSize == None:\r
615                     NoDatumTypePcdList.add(" | ".join(Key))\r
616                     PcdConsumerList.add(str(M))\r
617 \r
618                 if PcdFromPlatform.Type in GenC.gDynamicPcd + GenC.gDynamicExPcd:\r
619                     if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
620                         PcdFromPlatform.Phase = "PEI"\r
621                     if PcdFromPlatform not in PcdList:\r
622                         PcdFromPlatform.DatumType = PcdFromModule.DatumType\r
623                         PcdList.append(PcdFromPlatform)\r
624 \r
625         if len(NotFoundPcdList) > 0 or len(NoDatumTypePcdList) > 0:\r
626             NotFoundPcdListString = "\n\t\t".join(NotFoundPcdList)\r
627             NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)\r
628             ModuleListString = "\n\t\t".join(PcdConsumerList)\r
629             raise AutoGenError(msg="\n\tPCD(s) not found in platform:\n\t\t%s"\r
630                                    "\n\tPCD(s) without MaxDatumSize:\n\t\t%s"\r
631                                    "\n\tUsed by:\n\t\t%s\n"\r
632                                    % (NotFoundPcdListString, NoDatumTypePcdListString, ModuleListString))\r
633         return PcdList\r
634 \r
635     def GeneratePcdTokenNumber(self, Platform, DynamicPcdList):\r
636         PcdTokenNumber = sdict()\r
637         TokenNumber = 1\r
638         for Pcd in DynamicPcdList:\r
639             if Pcd.Phase == "PEI":\r
640                 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
641                 PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
642                 TokenNumber += 1\r
643 \r
644         for Pcd in DynamicPcdList:\r
645             if Pcd.Phase == "DXE":\r
646                 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
647                 PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
648                 TokenNumber += 1\r
649 \r
650         PlatformPcds = Platform.Pcds\r
651         for Key in PlatformPcds:\r
652             Pcd = PlatformPcds[Key]\r
653             if Key not in PcdTokenNumber:\r
654                 PcdTokenNumber[Key] = TokenNumber\r
655                 TokenNumber += 1\r
656         return PcdTokenNumber\r
657 \r
658     def GetPcdList(self, DependentLibraryList):\r
659         PlatformPcds = self.Platform.Pcds\r
660 \r
661         PcdList = []\r
662         for PcdKey in self.Module.Pcds:\r
663             Pcd = self.Module.Pcds[PcdKey]\r
664             #if pcdKey not in platformPcds:\r
665             #    EdkLogger.info("%s / %s not in current platform" % pcdKey)\r
666             if (Pcd.Type in GenC.gDynamicPcd + GenC.gDynamicExPcd) and self.Module.ModuleType in ["PEIM", "PEI_CORE"]:\r
667                 Pcd.Phase = "PEI"\r
668             PcdList.append(Pcd)\r
669         return PcdList\r
670 \r
671     def GetGuidList(self):\r
672         Guid = {}\r
673         Key = ""\r
674         for Key in self.Module.Guids:\r
675             for P in self.BuildInfo.DerivedPackageList:\r
676                 if Key in P.Guids:\r
677                     Guid[Key] = P.Guids[Key]\r
678                     break\r
679                 if Key in P.Protocols:\r
680                     Guid[Key] = P.Protocols[Key]\r
681                     break\r
682                 if Key in P.Ppis:\r
683                     Guid[Key] = P.Ppis[Key]\r
684                     break\r
685             else:\r
686                 PackageListString = "\n\t".join([str(P) for P in self.BuildInfo.DerivedPackageList])\r
687                 raise AutoGenError(msg='GUID [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, self.Module, PackageListString))\r
688         return Guid\r
689 \r
690     def GetProtocolGuidList(self):\r
691         Guid = {}\r
692         Key = ""\r
693         for Key in self.Module.Protocols:\r
694             for P in self.BuildInfo.DerivedPackageList:\r
695                 if Key in P.Guids:\r
696                     Guid[Key] = P.Guids[Key]\r
697                     break\r
698                 if Key in P.Protocols:\r
699                     Guid[Key] = P.Protocols[Key]\r
700                     break\r
701                 if Key in P.Ppis:\r
702                     Guid[Key] = P.Ppis[Key]\r
703                     break\r
704             else:\r
705                 PackageListString = "\n\t".join([str(P) for P in self.BuildInfo.DerivedPackageList])\r
706                 raise AutoGenError(msg='Protocol [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, self.Module, PackageListString))\r
707         return Guid\r
708 \r
709     def GetPpiGuidList(self):\r
710         Guid = {}\r
711         Key = ""\r
712         for Key in self.Module.Ppis:\r
713             for P in self.BuildInfo.DerivedPackageList:\r
714                 if Key in P.Guids:\r
715                     Guid[Key] = P.Guids[Key]\r
716                     break\r
717                 if Key in P.Protocols:\r
718                     Guid[Key] = P.Protocols[Key]\r
719                     break\r
720                 if Key in P.Ppis:\r
721                     Guid[Key] = P.Ppis[Key]\r
722                     break\r
723             else:\r
724                 PackageListString = "\n\t".join([str(P) for P in self.BuildInfo.DerivedPackageList])\r
725                 raise AutoGenError(msg='PPI [%s] used by [%s] cannot be found in dependent packages:\n\t%s' % (Key, self.Module, PackageListString))\r
726         return Guid\r
727 \r
728     def GetIncludePathList(self, DependentPackageList):\r
729         IncludePathList = []\r
730         for Inc in self.Module.Includes:\r
731             IncludePathList.append(Inc)\r
732 \r
733         for Package in DependentPackageList:\r
734             PackageDir = path.dirname(Package.DescFilePath)\r
735             IncludePathList.append(PackageDir)\r
736             for Inc in Package.Includes:\r
737                 Inc = os.path.join(PackageDir, Inc)\r
738                 if Inc not in IncludePathList:\r
739                     IncludePathList.append(Inc)\r
740         return IncludePathList\r
741 \r
742     def CreateMakefile(self, FilePath=None):\r
743         myBuildOption = {\r
744             "ENABLE_PCH"        :   False,\r
745             "ENABLE_LOCAL_LIB"  :   True,\r
746         }\r
747         if self.IsMakefileCreated:\r
748             return\r
749 \r
750         if self.IsPlatformAutoGen:\r
751             for Arch in self.BuildInfo:\r
752                 Info = self.BuildInfo[Arch]\r
753                 for ModuleFile in Info.Platform.Modules:\r
754                     Key = (Info.BuildTarget, Info.ToolChain, Arch, ModuleFile)\r
755                     ModuleAutoGen = None\r
756                     if Key not in gAutoGenDatabase:\r
757                         ModuleAutoGen = AutoGen(ModuleFile, Info.Platform, gWorkspace,\r
758                                                 Info.BuildTarget, Info.ToolChain, Info.Arch)\r
759                     else:\r
760                         ModuleAutoGen = gAutoGenDatabase[Key]\r
761                     ModuleAutoGen.CreateMakefile()\r
762         else:\r
763             PlatformInfo = self.BuildInfo.PlatformInfo\r
764             if not self.BuildInfo.IsLibrary:\r
765                 if self not in PlatformInfo.ModuleAutoGenList:\r
766                     PlatformInfo.ModuleAutoGenList.append(self)\r
767             elif self not in PlatformInfo.LibraryAutoGenList:\r
768                 PlatformInfo.LibraryAutoGenList.append(self)\r
769 \r
770             for Lib in self.BuildInfo.DependentLibraryList:\r
771                 EdkLogger.debug(EdkLogger.DEBUG_1, "###" + str(Lib))\r
772                 Key = (self.BuildTarget, self.ToolChain, self.Arch, Lib)\r
773                 LibraryAutoGen = None\r
774                 if Key not in gAutoGenDatabase:\r
775                     LibraryAutoGen = AutoGen(Lib, self.Platform, gWorkspace,\r
776                                              self.BuildTarget, self.ToolChain, self.Arch)\r
777                 else:\r
778                     LibraryAutoGen = gAutoGenDatabase[Key]\r
779                 if LibraryAutoGen not in self.BuildInfo.LibraryAutoGenList:\r
780                     self.BuildInfo.LibraryAutoGenList.append(LibraryAutoGen)\r
781                 LibraryAutoGen.CreateMakefile()\r
782 \r
783             Makefile = GenMake.Makefile(self.BuildInfo, myBuildOption)\r
784             if Makefile.Generate():\r
785                 EdkLogger.info("Generated makefile for module %s [%s]" %\r
786                                (self.BuildInfo.Name, self.BuildInfo.Arch))\r
787             else:\r
788                 EdkLogger.info("Skipped the generation of makefile for module %s [%s]" %\r
789                                (self.BuildInfo.Name, self.BuildInfo.Arch))\r
790             self.IsMakefileCreated = True\r
791             return\r
792 \r
793         Makefile = GenMake.Makefile(self.BuildInfo, myBuildOption)\r
794         if Makefile.Generate():\r
795             EdkLogger.info("Generated makefile for platform %s [%s]\n" %\r
796                            (self.BuildInfo[self.Arch[0]].Name, " ".join(self.Arch)))\r
797         else:\r
798             EdkLogger.info("Skipped the generation of makefile for platform %s [%s]\n" %\r
799                            (self.BuildInfo[self.Arch[0]].Name, " ".join(self.Arch)))\r
800         self.IsMakefileCreated = True\r
801 \r
802     def CreateAutoGenFile(self, FilePath=None):\r
803         if self.IsAutoGenCodeCreated:\r
804             return\r
805 \r
806         if self.IsPlatformAutoGen:\r
807             for Arch in self.BuildInfo:\r
808                 Info = self.BuildInfo[Arch]\r
809                 for ModuleFile in Info.Platform.Modules:\r
810                     Key = (Info.BuildTarget, Info.ToolChain, Arch, ModuleFile)\r
811                     ModuleAutoGen = None\r
812                     if Key not in gAutoGenDatabase:\r
813                         ModuleAutoGen = AutoGen(ModuleFile, Info.Platform, gWorkspace,\r
814                                                 Info.BuildTarget, Info.ToolChain, Info.Arch)\r
815                     else:\r
816                         ModuleAutoGen = gAutoGenDatabase[Key]\r
817                     ModuleAutoGen.CreateAutoGenFile()\r
818             EdkLogger.info("")\r
819         else:\r
820             PlatformInfo = self.BuildInfo.PlatformInfo\r
821             if not self.BuildInfo.IsLibrary and self not in PlatformInfo.ModuleAutoGenList:\r
822                 PlatformInfo.ModuleAutoGenList.append(self)\r
823             elif self.BuildInfo.IsLibrary and self not in PlatformInfo.LibraryAutoGenList:\r
824                 PlatformInfo.LibraryAutoGenList.append(self)\r
825 \r
826             for Lib in self.BuildInfo.DependentLibraryList:\r
827                 Key = (self.BuildTarget, self.ToolChain, self.Arch, Lib)\r
828                 LibraryAutoGen = None\r
829                 if Key not in gAutoGenDatabase:\r
830                     LibraryAutoGen = AutoGen(Lib, self.Platform, gWorkspace,\r
831                                              self.BuildTarget, self.ToolChain, self.Arch)\r
832                 else:\r
833                     LibraryAutoGen = gAutoGenDatabase[Key]\r
834                 if LibraryAutoGen not in self.BuildInfo.LibraryAutoGenList:\r
835                     self.BuildInfo.LibraryAutoGenList.append(LibraryAutoGen)\r
836                 LibraryAutoGen.CreateAutoGenFile()\r
837 \r
838             AutoGenList = []\r
839             IgoredAutoGenList = []\r
840             if self.AutoGenC.String != "":\r
841                 if GenC.Generate(os.path.join(self.BuildInfo.WorkspaceDir, self.BuildInfo.DebugDir, gAutoGenCodeFileName),\r
842                                  self.AutoGenC.String):\r
843                     AutoGenList.append(gAutoGenCodeFileName)\r
844                 else:\r
845                     IgoredAutoGenList.append(gAutoGenCodeFileName)\r
846 \r
847             if self.AutoGenH.String != "":\r
848                 if GenC.Generate(os.path.join(self.BuildInfo.WorkspaceDir, self.BuildInfo.DebugDir, gAutoGenHeaderFileName),\r
849                                  self.AutoGenH.String):\r
850                     AutoGenList.append(gAutoGenHeaderFileName)\r
851                 else:\r
852                     IgoredAutoGenList.append(gAutoGenHeaderFileName)\r
853 \r
854             if self.BuildInfo.DepexList != []:\r
855                 Dpx = GenDepex.DependencyExpression(self.BuildInfo.DepexList, self.BuildInfo.ModuleType)\r
856                 DpxFile = gAutoGenDepexFileName % {"module_name" : self.BuildInfo.Name}\r
857                 if Dpx.Generate(os.path.join(gWorkspaceDir, self.BuildInfo.OutputDir, DpxFile)):\r
858                     AutoGenList.append(DpxFile)\r
859                 else:\r
860                     IgoredAutoGenList.append(DpxFile)\r
861 \r
862             if IgoredAutoGenList == []:\r
863                 EdkLogger.info("Generated [%s] files for module %s [%s]" %\r
864                                (" ".join(AutoGenList), self.BuildInfo.Name, self.BuildInfo.Arch))\r
865             elif AutoGenList == []:\r
866                 EdkLogger.info("Skipped the generation of [%s] files for module %s [%s]" %\r
867                                (" ".join(IgoredAutoGenList), self.BuildInfo.Name, self.BuildInfo.Arch))\r
868             else:\r
869                 EdkLogger.info("Generated [%s] (skipped %s) files for module %s [%s]" %\r
870                                (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.BuildInfo.Name, self.BuildInfo.Arch))\r
871 \r
872             self.IsAutoGenCodeCreated = True\r
873             return AutoGenList\r
874 \r
875 # Version and Copyright\r
876 __version_number__ = "0.01"\r
877 __version__ = "%prog Version " + __version_number__\r
878 __copyright__ = "Copyright (c) 2007, Intel Corporation. All rights reserved."\r
879 \r
880 ## Parse command line options\r
881 #\r
882 # Using standard Python module optparse to parse command line option of this tool.\r
883 #\r
884 # @retval Options   A optparse.Values object containing the parsed options\r
885 # @retval InputFile Path of file to be trimmed\r
886 #\r
887 def GetOptions():\r
888     OptionList = [\r
889         make_option("-a", "--arch", dest="Arch",\r
890                           help="The input file is preprocessed source code, including C or assembly code"),\r
891         make_option("-p", "--platform", dest="ActivePlatform",\r
892                           help="The input file is preprocessed VFR file"),\r
893         make_option("-m", "--module", dest="ActiveModule",\r
894                           help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),\r
895         make_option("-f", "--FDF-file", dest="FdfFile",\r
896                           help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),\r
897         make_option("-o", "--output", dest="OutputDirectory",\r
898                           help="File to store the trimmed content"),\r
899         make_option("-t", "--toolchain-tag", dest="ToolChain",\r
900                           help=""),\r
901         make_option("-k", "--msft", dest="MakefileType", action="store_const", const="nmake",\r
902                           help=""),\r
903         make_option("-g", "--gcc", dest="MakefileType", action="store_const", const="gmake",\r
904                           help=""),\r
905         make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE,\r
906                           help="Run verbosely"),\r
907         make_option("-d", "--debug", dest="LogLevel", type="int",\r
908                           help="Run with debug information"),\r
909         make_option("-q", "--quiet", dest="LogLevel", action="store_const", const=EdkLogger.QUIET,\r
910                           help="Run quietly"),\r
911         make_option("-?", action="help", help="show this help message and exit"),\r
912     ]\r
913 \r
914     # use clearer usage to override default usage message\r
915     UsageString = "%prog [-a ARCH] [-p PLATFORM] [-m MODULE] [-t TOOLCHAIN_TAG] [-k] [-g] [-v|-d <debug_level>|-q] [-o <output_directory>] [GenC|GenMake]"\r
916 \r
917     Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString)\r
918     Parser.set_defaults(Arch=[])\r
919     Parser.set_defaults(ActivePlatform=None)\r
920     Parser.set_defaults(ActiveModule=None)\r
921     Parser.set_defaults(OutputDirectory="build")\r
922     Parser.set_defaults(FdfFile=None)\r
923     Parser.set_defaults(ToolChain="MYTOOLS")\r
924     if sys.platform == "win32":\r
925         Parser.set_defaults(MakefileType="nmake")\r
926     else:\r
927         Parser.set_defaults(MakefileType="gmake")\r
928     Parser.set_defaults(LogLevel=EdkLogger.INFO)\r
929 \r
930     Options, Args = Parser.parse_args()\r
931 \r
932     # error check\r
933     if len(Args) == 0:\r
934         Options.Target = "genmake"\r
935         sys.argv.append("genmake")\r
936     elif len(Args) == 1:\r
937         Options.Target = Args[0].lower()\r
938         if Options.Target not in ["genc", "genmake"]:\r
939             raise AutoGenError(OPTION_NOT_SUPPORTED, name="Not supported target", usage=Parser.get_usage())\r
940     else:\r
941         raise AutoGenError(OPTION_NOT_SUPPORTED, name="Too many targets", usage=Parser.get_usage())\r
942 \r
943     return Options\r
944 \r
945 ## Entrance method\r
946 #\r
947 # This method mainly dispatch specific methods per the command line options.\r
948 # If no error found, return zero value so the caller of this tool can know\r
949 # if it's executed successfully or not.\r
950 #\r
951 # @retval 0     Tool was successful\r
952 # @retval 1     Tool failed\r
953 #\r
954 def Main():\r
955     from build import build\r
956     try:\r
957         Option = GetOptions()\r
958         build.main()\r
959     except Exception, e:\r
960         print e\r
961         return 1\r
962 \r
963     return 0\r
964 \r
965 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
966 if __name__ == '__main__':\r
967     sys.exit(Main())\r