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