a. Added doxygen comments
[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 StrGather import *\r
30 from BuildEngine import *\r
31 \r
32 from Common.BuildToolError import *\r
33 from Common.EdkIIWorkspaceBuild import *\r
34 from Common.EdkIIWorkspace import *\r
35 from Common.DataType import *\r
36 from Common.Misc import *\r
37 from Common.String import *\r
38 from GenFds.FdfParser import *\r
39 \r
40 ## Regular expression for splitting Dependency Expression stirng into tokens\r
41 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
42 \r
43 ## Mapping Makefile type\r
44 gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}\r
45 \r
46 ## Default output flag for all tools\r
47 gDefaultOutputFlag = "-o "\r
48 \r
49 ## Output flags for specific tools\r
50 gOutputFlag = {\r
51     ("MSFT", "CC", "OUTPUT")      :   "/Fo",\r
52     ("MSFT", "SLINK", "OUTPUT")   :   "/OUT:",\r
53     ("MSFT", "DLINK", "OUTPUT")   :   "/OUT:",\r
54     ("MSFT", "ASMLINK", "OUTPUT") :   "/OUT:",\r
55     ("MSFT", "PCH", "OUTPUT")     :   "/Fp",\r
56     ("MSFT", "ASM", "OUTPUT")     :   "/Fo",\r
57 \r
58     ("INTEL", "CC", "OUTPUT")          :   "/Fo",\r
59     ("INTEL", "SLINK", "OUTPUT")       :   "/OUT:",\r
60     ("INTEL", "DLINK", "OUTPUT")       :   "/OUT:",\r
61     ("INTEL", "ASMLINK", "OUTPUT")     :   "/OUT:",\r
62     ("INTEL", "PCH", "OUTPUT")         :   "/Fp",\r
63     ("INTEL", "ASM", "OUTPUT")         :   "/Fo",\r
64 \r
65     ("GCC", "CC", "OUTPUT")        :   "-o ",\r
66     ("GCC", "SLINK", "OUTPUT")     :   "-cr ",\r
67     ("GCC", "DLINK", "OUTPUT")     :   "-o ",\r
68     ("GCC", "ASMLINK", "OUTPUT")   :   "-o ",\r
69     ("GCC", "PCH", "OUTPUT")       :   "-o ",\r
70     ("GCC", "ASM", "OUTPUT")       :   "-o ",\r
71 }\r
72 \r
73 ## Flag for include file search path\r
74 gIncludeFlag = {"MSFT" : "/I", "GCC" : "-I", "INTEL" : "-I"}\r
75 \r
76 ## Build rule configuration file\r
77 gBuildRuleFile = 'Conf/build_rule.txt'\r
78 \r
79 ## default file name for AutoGen\r
80 gAutoGenCodeFileName = "AutoGen.c"\r
81 gAutoGenHeaderFileName = "AutoGen.h"\r
82 gAutoGenDepexFileName = "%(module_name)s.depex"\r
83 \r
84 ## Base class for AutoGen\r
85 #\r
86 #   This class just implements the cache mechanism of AutoGen objects.\r
87\r
88 class AutoGen(object):\r
89     # database to maintain the objects of xxxAutoGen\r
90     _CACHE_ = {}    # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}\r
91 \r
92     ## Factory method\r
93     #\r
94     #   @param  Class           class object of real AutoGen class\r
95     #                           (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)\r
96     #   @param  Workspace       Workspace directory or WorkspaceAutoGen object\r
97     #   @param  MetaFile        The path of meta file\r
98     #   @param  Target          Build target\r
99     #   @param  Toolchain       Tool chain name\r
100     #   @param  Arch            Target arch\r
101     #   @param  *args           The specific class related parameters\r
102     #   @param  **kwargs        The specific class related dict parameters\r
103     # \r
104     def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
105         # check if the object has been created\r
106         Key = (Target, Toolchain)\r
107         if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \\r
108            or MetaFile not in Class._CACHE_[Key][Arch]:\r
109             AutoGenObject = super(AutoGen, Class).__new__(Class)\r
110             # call real constructor\r
111             if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
112                 return None\r
113             if Key not in Class._CACHE_:\r
114                 Class._CACHE_[Key] = {}\r
115             if Arch not in Class._CACHE_[Key]:\r
116                 Class._CACHE_[Key][Arch] = {}\r
117             Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject\r
118         else:\r
119             AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]\r
120 \r
121         return AutoGenObject\r
122 \r
123     ## hash() operator\r
124     #\r
125     #  The file path of platform file will be used to represent hash value of this object\r
126     #\r
127     #   @retval int     Hash value of the file path of platform file\r
128     #\r
129     def __hash__(self):\r
130         return hash(self._MetaFile)\r
131 \r
132     ## str() operator\r
133     #\r
134     #  The file path of platform file will be used to represent this object\r
135     #\r
136     #   @retval string  String of platform file path\r
137     #\r
138     def __str__(self):\r
139         return self._MetaFile\r
140 \r
141     ## "==" operator\r
142     def __eq__(self, Other):\r
143         return Other != None and self._MetaFile == str(Other)\r
144 \r
145 ## Workspace AutoGen class\r
146 #\r
147 #   This class is used mainly to control the whole platform build for different\r
148 # architecture. This class will generate top level makefile.\r
149\r
150 class WorkspaceAutoGen(AutoGen):\r
151     ## Real constructor of WorkspaceAutoGen\r
152     # \r
153     # This method behaves the same as __init__ except that it needs explict invoke\r
154     # (in super class's __new__ method)\r
155     #\r
156     #   @param  WorkspaceDir            Root directory of workspace\r
157     #   @param  ActivePlatform          Meta-file of active platform\r
158     #   @param  Target                  Build target\r
159     #   @param  Toolchain               Tool chain name\r
160     #   @param  ArchList                List of architecture of current build\r
161     #   @param  MetaFileDb              Database containing meta-files\r
162     #   @param  BuildConfig             Configuration of build\r
163     #   @param  ToolDefinition          Tool chain definitions\r
164     #   @param  FlashDefinitionFile     File of flash definition\r
165     #   @param  Fds                     FD list to be generated\r
166     #   @param  Fvs                     FV list to be generated\r
167     #   @param  SkuId                   SKU id from command line\r
168     # \r
169     def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r
170               BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId=''):\r
171         self._MetaFile      = str(ActivePlatform)\r
172         self.WorkspaceDir   = WorkspaceDir\r
173         self.Platform       = ActivePlatform\r
174         self.BuildTarget    = Target\r
175         self.ToolChain      = Toolchain\r
176         self.ArchList       = ArchList\r
177         self.SkuId          = SkuId\r
178 \r
179         self.BuildDatabase  = MetaFileDb\r
180         self.TargetTxt      = BuildConfig\r
181         self.ToolDef        = ToolDefinition\r
182         self.FdfFile        = FlashDefinitionFile\r
183         self.FdTargetList   = Fds\r
184         self.FvTargetList   = Fvs\r
185         self.AutoGenObjectList = []\r
186 \r
187         # there's many relative directory operations, so ...\r
188         os.chdir(self.WorkspaceDir)\r
189 \r
190         # parse FDF file to get PCDs in it, if any\r
191         if self.FdfFile != None and self.FdfFile != '':\r
192             Fdf = FdfParser(os.path.join(self.WorkspaceDir, self.FdfFile))\r
193             Fdf.ParseFile()\r
194             PcdSet = Fdf.Profile.PcdDict\r
195             ModuleList = Fdf.Profile.InfList\r
196         else:\r
197             PcdSet = {}\r
198             ModuleList = []\r
199 \r
200         # apply SKU and inject PCDs from Flash Definition file\r
201         for Arch in self.ArchList:\r
202             Platform = self.BuildDatabase[self._MetaFile, Arch]\r
203             Platform.SkuName = self.SkuId\r
204             for Name, Guid in PcdSet:\r
205                 Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])\r
206 \r
207             Pa = PlatformAutoGen(self, self._MetaFile, Target, Toolchain, Arch)\r
208             self.AutoGenObjectList.append(Pa)\r
209 \r
210         self._BuildDir = None\r
211         self._FvDir = None\r
212         self._MakeFileDir = None\r
213         self._BuildCommand = None\r
214 \r
215         return True\r
216 \r
217     ## Return the directory to store FV files\r
218     def _GetFvDir(self):\r
219         if self._FvDir == None:\r
220             self._FvDir = path.join(self.BuildDir, 'FV')\r
221         return self._FvDir\r
222             \r
223     ## Return the directory to store all intermediate and final files built\r
224     def _GetBuildDir(self):\r
225         return self.AutoGenObjectList[0].BuildDir\r
226 \r
227     ## Return the build output directory platform specifies\r
228     def _GetOutputDir(self):\r
229         return self.Platform.OutputDirectory\r
230 \r
231     ## Return platform name\r
232     def _GetName(self):\r
233         return self.Platform.PlatformName\r
234 \r
235     ## Return meta-file GUID\r
236     def _GetGuid(self):\r
237         return self.Platform.Guid\r
238 \r
239     ## Return platform version\r
240     def _GetVersion(self):\r
241         return self.Platform.Version\r
242 \r
243     ## Return paths of tools\r
244     def _GetToolPaths(self):\r
245         return self.AutoGenObjectList[0].ToolPath\r
246 \r
247     ## Return options of tools\r
248     def _GetToolOptions(self):\r
249         return self.AutoGenObjectList[0].ToolOption\r
250 \r
251     ## Return directory of platform makefile\r
252     #\r
253     #   @retval     string  Makefile directory\r
254     #\r
255     def _GetMakeFileDir(self):\r
256         if self._MakeFileDir == None:\r
257             self._MakeFileDir = self.BuildDir\r
258         return self._MakeFileDir\r
259 \r
260     ## Return build command string\r
261     #\r
262     #   @retval     string  Build command string\r
263     #\r
264     def _GetBuildCommand(self):\r
265         if self._BuildCommand == None:\r
266             # BuildCommand should be all the same. So just get one from platform AutoGen\r
267             self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
268         return self._BuildCommand\r
269 \r
270     ## Create makefile for the platform and mdoules in it\r
271     #\r
272     #   @param      CreateDepsMakeFile      Flag indicating if the makefile for\r
273     #                                       modules will be created as well\r
274     #\r
275     def CreateMakeFile(self, CreateDepsMakeFile=False):\r
276         # create makefile for platform\r
277         Makefile = GenMake.TopLevelMakefile(self)\r
278         if Makefile.Generate():\r
279             EdkLogger.verbose("Generated makefile for platform [%s] %s\n" %\r
280                            (self._MetaFile, self.ArchList))\r
281         else:\r
282             EdkLogger.verbose("Skipped the generation of makefile for platform [%s] %s\n" %\r
283                            (self._MetaFile, self.ArchList))\r
284 \r
285         if CreateDepsMakeFile:\r
286             for Pa in self.AutoGenObjectList:\r
287                 Pa.CreateMakeFile(CreateDepsMakeFile)\r
288 \r
289     ## Create autogen code for platform and modules\r
290     #\r
291     #  Since there's no autogen code for platform, this method will do nothing\r
292     #  if CreateModuleCodeFile is set to False.\r
293     #\r
294     #   @param      CreateDepsCodeFile      Flag indicating if creating module's\r
295     #                                       autogen code file or not\r
296     #\r
297     def CreateCodeFile(self, CreateDepsCodeFile=False):\r
298         if not CreateDepsCodeFile:\r
299             return\r
300         for Pa in self.AutoGenObjectList:\r
301             Pa.CreateCodeFile(CreateDepsCodeFile)\r
302 \r
303     Name                = property(_GetName)\r
304     Guid                = property(_GetGuid)\r
305     Version             = property(_GetVersion)                       \r
306     OutputDir           = property(_GetOutputDir)\r
307 \r
308     ToolPath            = property(_GetToolPaths)       # toolcode : tool path\r
309     ToolOption          = property(_GetToolOptions)     # toolcode : tool option string\r
310 \r
311     BuildDir            = property(_GetBuildDir)\r
312     FvDir               = property(_GetFvDir)\r
313     MakeFileDir         = property(_GetMakeFileDir)\r
314     BuildCommand        = property(_GetBuildCommand)\r
315 \r
316 ## AutoGen class for platform\r
317 #\r
318 #  PlatformAutoGen class will process the original information in platform\r
319 #  file in order to generate makefile for platform.\r
320 #\r
321 class PlatformAutoGen(AutoGen):\r
322     ## The real constructor of PlatformAutoGen\r
323     #\r
324     #  This method is not supposed to be called by users of PlatformAutoGen. It's\r
325     #  only used by factory method __new__() to do real initialization work for an\r
326     #  object of PlatformAutoGen\r
327     #\r
328     #   @param      Workspace       EdkIIWorkspaceBuild object\r
329     #   @param      PlatformFile    Platform file (DSC file)\r
330     #   @param      Target          Build target (DEBUG, RELEASE)\r
331     #   @param      Toolchain       Name of tool chain\r
332     #   @param      Arch            arch of the platform supports\r
333     #\r
334     def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
335         EdkLogger.verbose("\nAutoGen platform [%s] [%s]" % (PlatformFile, Arch))\r
336 \r
337         self._MetaFile = str(PlatformFile)\r
338         self.Workspace = Workspace\r
339         self.WorkspaceDir = Workspace.WorkspaceDir\r
340         self.ToolChain = Toolchain\r
341         self.BuildTarget = Target\r
342         self.Arch = Arch\r
343         self.SourceDir = path.dirname(PlatformFile)\r
344         self.FdTargetList = self.Workspace.FdTargetList\r
345         self.FvTargetList = self.Workspace.FvTargetList\r
346 \r
347         # flag indicating if the makefile/C-code file has been created or not\r
348         self.IsMakeFileCreated  = False\r
349         self.IsCodeFileCreated  = False\r
350 \r
351         self._Platform   = None\r
352         self._Name       = None\r
353         self._Guid       = None\r
354         self._Version    = None\r
355 \r
356         self._BuildRule = None\r
357         self._SourceDir = None\r
358         self._BuildDir = None\r
359         self._OutputDir = None\r
360         self._FvDir = None\r
361         self._MakeFileDir = None\r
362         self._FdfFile = None\r
363 \r
364         self._PcdTokenNumber = None    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
365         self._DynamicPcdList = None    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
366         self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
367 \r
368         self._ToolPath = None          # toolcode : tool path\r
369         self._ToolDllPath = None       # toolcode : lib path\r
370         self._ToolStaticLib = None     # toolcode : lib path\r
371         self._ToolChainFamily = None   # toolcode : tool chain family\r
372         self._BuildOption = None       # toolcode : option\r
373         self._OutputFlag = None        # toolcode : output flag\r
374         self._IncludeFlag = None       # toolcode : include flag\r
375         self._ToolOption = None        # toolcode : tool option string\r
376         self._PackageList = None\r
377         self._ModuleAutoGenList  = None\r
378         self._LibraryAutoGenList = None\r
379         self._BuildCommand = None\r
380 \r
381         # get the original module/package/platform objects\r
382         self.BuildDatabase = Workspace.BuildDatabase\r
383         return True\r
384 \r
385     ## Create autogen code for platform and modules\r
386     #\r
387     #  Since there's no autogen code for platform, this method will do nothing\r
388     #  if CreateModuleCodeFile is set to False.\r
389     #\r
390     #   @param      CreateModuleCodeFile    Flag indicating if creating module's\r
391     #                                       autogen code file or not\r
392     #\r
393     def CreateCodeFile(self, CreateModuleCodeFile=False):\r
394         # only module has code to be greated, so do nothing if CreateModuleCodeFile is False\r
395         if self.IsCodeFileCreated or not CreateModuleCodeFile:\r
396             return\r
397 \r
398         for Ma in self.ModuleAutoGenList:\r
399             Ma.CreateCodeFile(True)\r
400 \r
401         # don't do this twice\r
402         self.IsCodeFileCreated = True\r
403 \r
404     ## Create makefile for the platform and mdoules in it\r
405     #\r
406     #   @param      CreateModuleMakeFile    Flag indicating if the makefile for\r
407     #                                       modules will be created as well\r
408     #\r
409     def CreateMakeFile(self, CreateModuleMakeFile=False):\r
410         if CreateModuleMakeFile:\r
411             for ModuleFile in self.Platform.Modules:\r
412                 Ma = ModuleAutoGen(self.Workspace, ModuleFile, \r
413                                               self.BuildTarget, self.ToolChain,\r
414                                               self.Arch, self._MetaFile)\r
415                 Ma.CreateMakeFile(True)\r
416 \r
417         # no need to create makefile for the platform more than once\r
418         if self.IsMakeFileCreated:\r
419             return\r
420 \r
421         # create makefile for platform\r
422         Makefile = GenMake.PlatformMakefile(self)\r
423         if Makefile.Generate():\r
424             EdkLogger.verbose("Generated makefile for platform [%s] [%s]\n" %\r
425                            (self._MetaFile, self.Arch))\r
426         else:\r
427             EdkLogger.verbose("Skipped the generation of makefile for platform [%s] [%s]\n" %\r
428                            (self._MetaFile, self.Arch))\r
429         self.IsMakeFileCreated = True\r
430 \r
431     ## Return the platform build data object\r
432     def _GetPlatform(self):\r
433         if self._Platform == None:\r
434             self._Platform = self.BuildDatabase[self._MetaFile, self.Arch]\r
435         return self._Platform\r
436 \r
437     ## Return platform name\r
438     def _GetName(self):\r
439         return self.Platform.PlatformName\r
440 \r
441     ## Return the meta file GUID\r
442     def _GetGuid(self):\r
443         return self.Platform.Guid\r
444 \r
445     ## Return the platform version\r
446     def _GetVersion(self):\r
447         return self.Platform.Version\r
448 \r
449     ## Return the FDF file name\r
450     def _GetFdfFile(self):\r
451         if self._FdfFile == None:\r
452             if self.Workspace.FdfFile != "":\r
453                 self._FdfFile= path.join(self.WorkspaceDir, self.Workspace.FdfFile)\r
454             else:\r
455                 self._FdfFile = ''\r
456         return self._FdfFile\r
457 \r
458     ## Return the build output directory platform specifies\r
459     def _GetOutputDir(self):\r
460         return self.Platform.OutputDirectory\r
461 \r
462     ## Return the directory to store all intermediate and final files built\r
463     def _GetBuildDir(self):\r
464         if self._BuildDir == None:\r
465             if os.path.isabs(self.OutputDir):\r
466                 self._BuildDir = path.join(\r
467                                             path.abspath(self.OutputDir), \r
468                                             self.BuildTarget + "_" + self.ToolChain,\r
469                                             )\r
470             else:\r
471                 self._BuildDir = path.join(\r
472                                             self.WorkspaceDir,\r
473                                             self.OutputDir,\r
474                                             self.BuildTarget + "_" + self.ToolChain,\r
475                                             )\r
476         return self._BuildDir\r
477 \r
478     ## Return directory of platform makefile\r
479     #\r
480     #   @retval     string  Makefile directory\r
481     #\r
482     def _GetMakeFileDir(self):\r
483         if self._MakeFileDir == None:\r
484             self._MakeFileDir = path.join(self.BuildDir, self.Arch)\r
485         return self._MakeFileDir\r
486 \r
487     ## Return build command string\r
488     #\r
489     #   @retval     string  Build command string\r
490     #\r
491     def _GetBuildCommand(self):\r
492         if self._BuildCommand == None:\r
493             self._BuildCommand = tuple()\r
494             if "MAKE" in self.ToolPath:\r
495                 self._BuildCommand += (self.ToolPath["MAKE"],)\r
496                 if "MAKE" in self.ToolOption:\r
497                     NewOption = self.ToolOption["MAKE"].strip()\r
498                     if NewOption != '':\r
499                       self._BuildCommand += (NewOption,)\r
500         return self._BuildCommand\r
501 \r
502     ## Get tool chain definition\r
503     #\r
504     #  Get each tool defition for given tool chain from tools_def.txt and platform\r
505     #\r
506     def _GetToolDefinition(self):\r
507         ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary\r
508         ToolCodeList = self.Workspace.ToolDef.ToolsDefTxtDatabase["COMMAND_TYPE"]\r
509         self._ToolPath = {}\r
510         self._ToolDllPath = {}\r
511         self._ToolChainFamily = {}\r
512         self._ToolOption = {}\r
513         self._OutputFlag = {}\r
514         self._IncludeFlag = {}\r
515         for Tool in ToolCodeList:\r
516             KeyBaseString = "%s_%s_%s_%s" % (self.BuildTarget, self.ToolChain, self.Arch, Tool)\r
517 \r
518             Key = "%s_PATH" % KeyBaseString\r
519             if Key not in ToolDefinition:\r
520                 continue\r
521             Path = ToolDefinition[Key]\r
522 \r
523             Key = "%s_FAMILY" % KeyBaseString\r
524             if Key in ToolDefinition:\r
525                 Family = ToolDefinition[Key]\r
526             else:\r
527                 Family = ""\r
528 \r
529             Key = "%s_FLAGS" % KeyBaseString\r
530             if Key in ToolDefinition:\r
531                 Option = ToolDefinition[Key]\r
532             else:\r
533                 Option = ""\r
534 \r
535             Key = "%s_DLL" % KeyBaseString\r
536             if Key in ToolDefinition:\r
537                 Dll = ToolDefinition[Key]\r
538                 # set the DLL path in system's PATH environment\r
539                 os.environ["PATH"] = Dll + os.pathsep + os.environ["PATH"]\r
540             else:\r
541                 Dll = ""\r
542 \r
543             Key = KeyBaseString + "_OUTPUT"\r
544             if Key in ToolDefinition:\r
545                 OutputFlag = ToolDefinition[Key]\r
546             elif (Family, Tool, "OUTPUT") in gOutputFlag:\r
547                 OutputFlag = gOutputFlag[Family, Tool, "OUTPUT"]\r
548                 if OutputFlag[0] == '"' and OutputFlag[-1] == '"':\r
549                     OutputFlag = OutputFlag[1:-1]\r
550             else:\r
551                 OutputFlag = gDefaultOutputFlag\r
552 \r
553             InputFlag = gIncludeFlag[Family]\r
554 \r
555             self._ToolPath[Tool] = Path\r
556             self._ToolDllPath[Tool] = Dll\r
557             self._ToolChainFamily[Tool] = Family\r
558             self._ToolOption[Tool] = Option\r
559             self._OutputFlag[Tool] = OutputFlag\r
560             self._IncludeFlag[Tool] = InputFlag\r
561 \r
562     ## Return the paths of tools\r
563     def _GetToolPaths(self):\r
564         if self._ToolPath == None:\r
565             self._GetToolDefinition()\r
566         return self._ToolPath\r
567 \r
568     ## Return the dll paths of tools\r
569     def _GetToolDllPaths(self):\r
570         if self._ToolDllPath == None:\r
571             self._GetToolDefinition()\r
572         return self._ToolDllPath\r
573 \r
574     ## Return the static libraries of tools\r
575     def _GetToolStaticLibs(self):\r
576         if self._ToolStaticLib == None:\r
577             self._GetToolDefinition()\r
578         return self._ToolStaticLib\r
579 \r
580     ## Return the families of tools\r
581     def _GetToolChainFamilies(self):\r
582         if self._ToolChainFamily == None:\r
583             self._GetToolDefinition()\r
584         return self._ToolChainFamily\r
585 \r
586     ## Return the build options specific to this platform\r
587     def _GetBuildOptions(self):\r
588         if self._BuildOption == None:\r
589             self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)\r
590         return self._BuildOption\r
591 \r
592     ## Return the output flag of tools\r
593     def _GetOuputFlags(self):\r
594         if self._OutputFlag == None:\r
595             self._GetToolDefinition()\r
596         return self._OutputFlag\r
597 \r
598     ## Return the include flags of tools\r
599     def _GetIncludeFlags(self):\r
600         if self._IncludeFlag == None:\r
601             self._GetToolDefinition()\r
602         return self._IncludeFlag\r
603 \r
604     ## Return the default options of tools\r
605     def _GetToolOptions(self):\r
606         if self._ToolOption == None:\r
607             self._GetToolDefinition()\r
608         return self._ToolOption\r
609 \r
610     ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt\r
611     #\r
612     #   @retval     BuildRule object\r
613     #\r
614     def _GetBuildRule(self):\r
615         if self._BuildRule == None:\r
616             BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
617             if BuildRuleFile in [None, '']:\r
618                 BuildRuleFile = gBuildRuleFile\r
619             self._BuildRule = BuildRule(BuildRuleFile)\r
620         return self._BuildRule\r
621 \r
622     ## Summarize the packages used by modules in this platform\r
623     def _GetPackageList(self):\r
624         if self._PackageList == None:\r
625             self._PackageList = set()\r
626             for La in self.LibraryAutoGenList:\r
627                 self._PackageList.update(La.DependentPackageList)\r
628             for Ma in self.ModuleAutoGenList:\r
629                 self._PackageList.update(Ma.DependentPackageList)\r
630         return self._PackageList\r
631 \r
632     ## Collect dynamic PCDs\r
633     #\r
634     #  Gather dynamic PCDs list from each module and their settings from platform\r
635     #\r
636     def _GetPcdList(self):\r
637         self._NonDynamicPcdList = []\r
638         self._DynamicPcdList = []\r
639 \r
640         # for gathering error information\r
641         NotFoundPcdList = set()\r
642         NoDatumTypePcdList = set()\r
643 \r
644         self._GuidValue = {}\r
645         for F in self.Platform.Modules:\r
646             M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self._MetaFile)\r
647             #GuidValue.update(M.Guids)\r
648             for PcdFromModule in M.PcdList:\r
649                 # check if the setting of the PCD is found in platform\r
650                 #if not PcdFromModule.IsOverrided:\r
651                 #    NotFoundPcdList.add("%s [%s]" % (" | ".join(Key), F))\r
652                 #    continue\r
653 \r
654                 # make sure that the "VOID*" kind of datum has MaxDatumSize set\r
655                 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None:\r
656                     NoDatumTypePcdList.add("%s [%s]" % (" | ".join(Key), F))\r
657 \r
658                 if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:\r
659                     # for autogen code purpose\r
660                     if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
661                         PcdFromModule.Phase = "PEI"\r
662                     if PcdFromModule not in self._DynamicPcdList:\r
663                         self._DynamicPcdList.append(PcdFromModule)\r
664                 elif PcdFromModule not in self._NonDynamicPcdList:\r
665                     self._NonDynamicPcdList.append(PcdFromModule)\r
666 \r
667         # print out error information and break the build, if error found\r
668         if len(NoDatumTypePcdList) > 0:\r
669             NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)\r
670             EdkLogger.error("AutoGen", AUTOGEN_ERROR, "PCD setting error",\r
671                             ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
672                                       % NoDatumTypePcdListString)\r
673 \r
674     ## Get list of non-dynamic PCDs\r
675     def _GetNonDynamicPcdList(self):\r
676         if self._NonDynamicPcdList == None:\r
677             self._GetPcdList()\r
678         return self._NonDynamicPcdList\r
679 \r
680     ## Get list of dynamic PCDs\r
681     def _GetDynamicPcdList(self):\r
682         if self._DynamicPcdList == None:\r
683             self._GetPcdList()\r
684         return self._DynamicPcdList\r
685 \r
686     ## Generate Token Number for all PCD\r
687     def _GetPcdTokenNumbers(self):\r
688         if self._PcdTokenNumber == None:\r
689             self._PcdTokenNumber = sdict()\r
690             TokenNumber = 1\r
691             for Pcd in self.DynamicPcdList:\r
692                 if Pcd.Phase == "PEI":\r
693                     EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
694                     self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
695                     TokenNumber += 1\r
696         \r
697             for Pcd in self.DynamicPcdList:\r
698                 if Pcd.Phase == "DXE":\r
699                     EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
700                     self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
701                     TokenNumber += 1\r
702         \r
703             for Pcd in self.NonDynamicPcdList:\r
704                 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
705                 TokenNumber += 1\r
706         return self._PcdTokenNumber\r
707 \r
708     ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform\r
709     def _GetAutoGenObjectList(self):\r
710         self._ModuleAutoGenList = []\r
711         self._LibraryAutoGenList = []\r
712         for ModuleFile in self.Platform.Modules:\r
713             Ma = ModuleAutoGen(\r
714                     self.Workspace,\r
715                     ModuleFile,\r
716                     self.BuildTarget,\r
717                     self.ToolChain, \r
718                     self.Arch, \r
719                     self._MetaFile\r
720                     )\r
721             if Ma not in self._ModuleAutoGenList:\r
722                 self._ModuleAutoGenList.append(Ma)\r
723             for La in Ma.LibraryAutoGenList:\r
724                 if La not in self._LibraryAutoGenList:\r
725                     self._LibraryAutoGenList.append(La)\r
726 \r
727     ## Summarize ModuleAutoGen objects of all modules to be built for this platform\r
728     def _GetModuleAutoGenList(self):\r
729         if self._ModuleAutoGenList == None:\r
730             self._GetAutoGenObjectList()\r
731         return self._ModuleAutoGenList\r
732 \r
733     ## Summarize ModuleAutoGen objects of all libraries to be built for this platform\r
734     def _GetLibraryAutoGenList(self):\r
735         if self._LibraryAutoGenList == None:\r
736             self._GetAutoGenObjectList()\r
737         return self._LibraryAutoGenList\r
738 \r
739     ## Test if a module is supported by the platform\r
740     #\r
741     #  An error will be raised directly if the module or its arch is not supported\r
742     #  by the platform or current configuration\r
743     #\r
744     def ValidModule(self, Module):\r
745         return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances\r
746 \r
747     ## Resolve the library classes in a module to library instances\r
748     #\r
749     # This method will not only resolve library classes but also sort the library\r
750     # instances according to the dependency-ship.\r
751     # \r
752     #   @param  Module      The module from which the library classes will be resolved\r
753     # \r
754     #   @retval library_list    List of library instances sorted\r
755     # \r
756     def ApplyLibraryInstance(self, Module):\r
757         ModuleType = Module.ModuleType\r
758         # apply library instances from platform\r
759         for LibraryClass in Module.LibraryClasses:\r
760             LibraryInstance = self.Platform.LibraryClasses[LibraryClass, ModuleType]\r
761             if LibraryInstance == None:\r
762                 continue\r
763             Module.LibraryClasses[LibraryClass] = LibraryInstance\r
764 \r
765         # override library instances with module specific setting\r
766         PlatformModule = self.Platform.Modules[str(Module)]\r
767         for LibraryClass in PlatformModule.LibraryClasses:\r
768             Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]\r
769 \r
770         # R9 module\r
771         LibraryConsumerList = [Module]\r
772         Constructor         = []\r
773         ConsumedByList      = sdict()\r
774         LibraryInstance     = sdict()\r
775 \r
776         EdkLogger.verbose("")\r
777         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
778         while len(LibraryConsumerList) > 0:\r
779             M = LibraryConsumerList.pop()\r
780             for LibraryClassName in M.LibraryClasses:\r
781                 LibraryPath = M.LibraryClasses[LibraryClassName]\r
782                 if LibraryPath == None or LibraryPath == "":\r
783                     LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]\r
784                     if LibraryPath == None and LibraryClassName not in LibraryInstance:\r
785                         LibraryInstance[LibraryClassName] = None\r
786                         continue\r
787                 if LibraryClassName not in LibraryInstance:\r
788                     LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]\r
789                     # for those forced library instance (NULL library), add a fake library class\r
790                     if LibraryClassName.startswith("NULL"):\r
791                         LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))\r
792                     elif ModuleType not in LibraryModule.LibraryClass[0].SupModList:\r
793                         EdkLogger.error("build", OPTION_MISSING,\r
794                                         "Module type [%s] is not supported by library instance [%s]" \\r
795                                         % (ModuleType, LibraryPath), File=self._MetaFile, \r
796                                         ExtraData="\tconsumed by [%s]" % str(Module))\r
797 \r
798                     LibraryInstance[LibraryClassName] = LibraryModule\r
799                     LibraryConsumerList.append(LibraryModule)\r
800                     EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
801                 else:\r
802                     LibraryModule = LibraryInstance[LibraryClassName]\r
803 \r
804                 if LibraryModule == None:\r
805                     continue\r
806 \r
807                 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
808                     Constructor.append(LibraryModule)\r
809 \r
810                 if LibraryModule not in ConsumedByList:\r
811                     ConsumedByList[LibraryModule] = []\r
812                 # don't add current module itself to consumer list\r
813                 if M != Module:\r
814                     if M in ConsumedByList[LibraryModule]:\r
815                         continue\r
816                     ConsumedByList[LibraryModule].append(M)\r
817         #\r
818         # Initialize the sorted output list to the empty set\r
819         #\r
820         SortedLibraryList = []\r
821         #\r
822         # Q <- Set of all nodes with no incoming edges\r
823         #\r
824         LibraryList = [] #LibraryInstance.values()\r
825         Q = []\r
826         for LibraryClassName in LibraryInstance:\r
827             M = LibraryInstance[LibraryClassName]\r
828             if M == None:\r
829                 EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
830                                 "Library instance of library class [%s] is not found" % LibraryClassName,\r
831                                 File=self._MetaFile, ExtraData="consumed by [%s] [%s]" % (str(Module), self.Arch))\r
832             LibraryList.append(M)\r
833             #\r
834             # check if there're library classes\r
835             #\r
836             #for Lc in M.LibraryClass:\r
837             #    if Lc.SupModList != None and ModuleType not in Lc.SupModList:\r
838             #        EdkLogger.error("build", OPTION_MISSING,\r
839             #                        "Module type [%s] is not supported by library instance [%s]" % (ModuleType, str(M)),\r
840             #                        File=self._MetaFile, ExtraData="\tconsumed by [%s]" % str(Module))\r
841 \r
842                 #if Lc.LibraryClass in LibraryInstance and str(M) != str(LibraryInstance[Lc.LibraryClass]):\r
843                 #    EdkLogger.error("build", OPTION_CONFLICT,\r
844                 #                    "More than one library instance found for library class [%s] in module [%s]" % (Lc.LibraryClass, str(Module)),\r
845                 #                    ExtraData="\t%s\n\t%s" % (LibraryInstance[Lc.LibraryClass], str(M))\r
846                 #                    )\r
847             if ConsumedByList[M] == []:\r
848                 Q.insert(0, M)\r
849 \r
850         #\r
851         # start the  DAG algorithm\r
852         #\r
853         while True:\r
854             EdgeRemoved = True\r
855             while Q == [] and EdgeRemoved:\r
856                 EdgeRemoved = False\r
857                 # for each node Item with a Constructor\r
858                 for Item in LibraryList:\r
859                     if Item not in Constructor:\r
860                         continue\r
861                     # for each Node without a constructor with an edge e from Item to Node\r
862                     for Node in ConsumedByList[Item]:\r
863                         if Node in Constructor:\r
864                             continue\r
865                         # remove edge e from the graph if Node has no constructor\r
866                         ConsumedByList[Item].remove(Node)\r
867                         EdgeRemoved = True\r
868                         if ConsumedByList[Item] == []:\r
869                             # insert Item into Q\r
870                             Q.insert(0, Item)\r
871                             break\r
872                     if Q != []:\r
873                         break\r
874             # DAG is done if there's no more incoming edge for all nodes\r
875             if Q == []:\r
876                 break\r
877 \r
878             # remove node from Q\r
879             Node = Q.pop()\r
880             # output Node\r
881             SortedLibraryList.append(Node)\r
882 \r
883             # for each node Item with an edge e from Node to Item do\r
884             for Item in LibraryList:\r
885                 if Node not in ConsumedByList[Item]:\r
886                     continue\r
887                 # remove edge e from the graph\r
888                 ConsumedByList[Item].remove(Node)\r
889 \r
890                 if ConsumedByList[Item] != []:\r
891                     continue\r
892                 # insert Item into Q, if Item has no other incoming edges\r
893                 Q.insert(0, Item)\r
894 \r
895         #\r
896         # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
897         #\r
898         for Item in LibraryList:\r
899             if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
900                 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])\r
901                 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),\r
902                                 ExtraData=ErrorMessage, File=self._MetaFile)\r
903             if Item not in SortedLibraryList:\r
904                 SortedLibraryList.append(Item)\r
905 \r
906         #\r
907         # Build the list of constructor and destructir names\r
908         # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
909         #                \r
910         SortedLibraryList.reverse()\r
911         return SortedLibraryList\r
912     \r
913 \r
914     ## Override PCD setting (type, value, ...)\r
915     #\r
916     #   @param  ToPcd       The PCD to be overrided\r
917     #   @param  FromPcd     The PCD overrideing from\r
918     # \r
919     def _OverridePcd(self, ToPcd, FromPcd):\r
920         # \r
921         # in case there's PCDs coming from FDF file, which have no type given.\r
922         # at this point, PcdInModule.Type has the type found from dependent\r
923         # package\r
924         # \r
925         if FromPcd != None:\r
926             if FromPcd.Type not in [None, '']:\r
927                 ToPcd.Type = FromPcd.Type\r
928             if FromPcd.MaxDatumSize not in [None, '']:\r
929                 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
930             if FromPcd.DefaultValue not in [None, '']:\r
931                 ToPcd.DefaultValue = FromPcd.DefaultValue\r
932             if FromPcd.TokenValue not in [None, '']:\r
933                 ToPcd.TokenValue = FromPcd.TokenValue\r
934             if FromPcd.MaxDatumSize not in [None, '']:\r
935                 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
936             if FromPcd.DatumType not in [None, '']:\r
937                 ToPcd.DatumType = FromPcd.DatumType\r
938             if FromPcd.SkuInfoList not in [None, '', []]:\r
939                 ToPcd.SkuInfoList = FromPcd.SkuInfoList\r
940 \r
941         if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
942             EdkLogger.verbose("No MaxDatumSize specified for PCD %s.%s" \\r
943                               % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))\r
944             Value = ToPcd.DefaultValue\r
945             if Value[0] == 'L':\r
946                 ToPcd.MaxDatumSize = str(len(Value) * 2)\r
947             elif Value[0] == '{':\r
948                 ToPcd.MaxDatumSize = str(len(Value.split(',')))\r
949             else:\r
950                 ToPcd.MaxDatumSize = str(len(Value))\r
951 \r
952         # apply default SKU for dynamic PCDS if specified one is not available\r
953         if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \\r
954             and ToPcd.SkuInfoList in [None, {}, '']:\r
955             if self.Platform.SkuName in self.Platform.SkuIds:\r
956                 SkuName = self.Platform.SkuName\r
957             else:\r
958                 SkuName = 'DEFAULT'\r
959             ToPcd.SkuInfoList = {\r
960                 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)\r
961             }\r
962 \r
963     ## Apply PCD setting defined platform to a module\r
964     #\r
965     #   @param  Module  The module from which the PCD setting will be overrided\r
966     # \r
967     #   @retval PCD_list    The list PCDs with settings from platform\r
968     # \r
969     def ApplyPcdSetting(self, Module):\r
970         # for each PCD in module\r
971         for Name,Guid in Module.Pcds:\r
972             PcdInModule = Module.Pcds[Name,Guid]\r
973             # find out the PCD setting in platform\r
974             if (Name,Guid) in self.Platform.Pcds:\r
975                 PcdInPlatform = self.Platform.Pcds[Name,Guid]\r
976             else:\r
977                 PcdInPlatform = None\r
978             # then override the settings if any\r
979             self._OverridePcd(PcdInModule, PcdInPlatform)\r
980             # resolve the VariableGuid value\r
981             for SkuId in PcdInModule.SkuInfoList:\r
982                 Sku = PcdInModule.SkuInfoList[SkuId]\r
983                 if Sku.VariableGuid == '': continue\r
984                 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)\r
985                 if Sku.VariableGuidValue == None:\r
986                     PackageList = '\t' + "\n\t".join([str(P) for P in Module.Packages])\r
987                     EdkLogger.error(\r
988                                 'build',\r
989                                 RESOURCE_NOT_AVAILABLE,\r
990                                 "Value of [%s] is not found in" % Sku.VariableGuid,\r
991                                 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \\r
992                                                         % (Guid, Name, str(Module)),\r
993                                 File=self._MetaFile\r
994                                 )\r
995 \r
996         # override PCD settings with module specific setting\r
997         if Module in self.Platform.Modules:\r
998             PlatformModule = self.Platform.Modules[str(Module)]\r
999             for Key  in PlatformModule.Pcds:\r
1000                 if Key in Module.Pcds:\r
1001                     self._OverridePcd(Module.Pcds[Key], PlatformModule.Pcds[Key])\r
1002         return Module.Pcds.values()\r
1003 \r
1004     ## Resolve library names to library modules\r
1005     # \r
1006     # (for R8.x modules)\r
1007     # \r
1008     #   @param  Module  The module from which the library names will be resolved\r
1009     # \r
1010     #   @retval library_list    The list of library modules\r
1011     # \r
1012     def ResolveLibraryReference(self, Module):\r
1013         EdkLogger.verbose("")\r
1014         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
1015         LibraryConsumerList = [Module]\r
1016 \r
1017         # "CompilerStub" is a must for R8 modules\r
1018         Module.Libraries.append("CompilerStub")\r
1019         LibraryList = []\r
1020         while len(LibraryConsumerList) > 0:\r
1021             M = LibraryConsumerList.pop()\r
1022             for LibraryName in M.Libraries:\r
1023                 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']\r
1024                 if Library == None:\r
1025                     EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),\r
1026                                     ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
1027                     continue\r
1028 \r
1029                 if Library not in LibraryList:\r
1030                     LibraryList.append(Library)\r
1031                     LibraryConsumerList.append(Library)\r
1032                     EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))\r
1033         return LibraryList\r
1034 \r
1035     ## Expand * in build option key\r
1036     #\r
1037     #   @param  Options     Options to be expanded\r
1038     # \r
1039     #   @retval options     Options expanded\r
1040     # \r
1041     def _ExpandBuildOption(self, Options):\r
1042         BuildOptions = {}\r
1043         for Key in Options:\r
1044             Family = Key[0]\r
1045             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
1046             # if no tool defined for the option, skip it\r
1047             if Tool not in self.Workspace.ToolPath:\r
1048                 continue\r
1049             # if tool chain family doesn't match, skip it\r
1050             if Family != None and Family != "" and Family != self.ToolChainFamily[Tool]:\r
1051                 continue\r
1052             # expand any wildcard\r
1053             if Target == "*" or Target == self.BuildTarget:\r
1054                 if Tag == "*" or Tag == self.ToolChain:\r
1055                     if Arch == "*" or Arch == self.Arch:\r
1056                         if Tool not in BuildOptions:\r
1057                             BuildOptions[Tool] = Options[Key]\r
1058                         else:\r
1059                             # append options for the same tool\r
1060                             BuildOptions[Tool] += " " + Options[Key]\r
1061         return BuildOptions\r
1062 \r
1063     ## Append build options in platform to a module\r
1064     # \r
1065     #   @param  Module  The module to which the build options will be appened\r
1066     # \r
1067     #   @retval options     The options appended with build options in platform\r
1068     # \r
1069     def ApplyBuildOption(self, Module):\r
1070         PlatformOptions = self.BuildOption\r
1071         ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)\r
1072         if Module in self.Platform.Modules:\r
1073             PlatformModule = self.Platform.Modules[str(Module)]\r
1074             PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)\r
1075         else:\r
1076             PlatformModuleOptions = {}\r
1077 \r
1078         BuildOptions = {}\r
1079         # for those tools that have no option in module file, give it a empty string\r
1080         for Tool in self.Workspace.ToolPath:\r
1081             if Tool in self.ToolOption and Module.ModuleType != 'USER_DEFINED':\r
1082                 BuildOptions[Tool] = self.ToolOption[Tool]\r
1083             else:\r
1084                 BuildOptions[Tool] = ''\r
1085             if Tool in ModuleOptions:\r
1086                 BuildOptions[Tool] += " " + ModuleOptions[Tool]\r
1087             if Tool in PlatformOptions:\r
1088                 BuildOptions[Tool] += " " + PlatformOptions[Tool]\r
1089             if Tool in PlatformModuleOptions:\r
1090                 BuildOptions[Tool] += " " + PlatformModuleOptions[Tool]\r
1091         return BuildOptions\r
1092 \r
1093     Platform            = property(_GetPlatform)\r
1094     Name                = property(_GetName)\r
1095     Guid                = property(_GetGuid)\r
1096     Version             = property(_GetVersion)\r
1097                        \r
1098     OutputDir           = property(_GetOutputDir)\r
1099     BuildDir            = property(_GetBuildDir)\r
1100     MakeFileDir         = property(_GetMakeFileDir)\r
1101     FdfFile             = property(_GetFdfFile)\r
1102     \r
1103     PcdTokenNumber      = property(_GetPcdTokenNumbers)    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
1104     DynamicPcdList      = property(_GetDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
1105     NonDynamicPcdList   = property(_GetNonDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
1106     PackageList         = property(_GetPackageList)\r
1107 \r
1108     ToolPath            = property(_GetToolPaths)    # toolcode : tool path\r
1109     ToolDllPath         = property(_GetToolDllPaths)    # toolcode : lib path\r
1110     ToolStaticLib       = property(_GetToolStaticLibs)    # toolcode : lib path\r
1111     ToolChainFamily     = property(_GetToolChainFamilies)    # toolcode : tool chain family\r
1112     BuildOption         = property(_GetBuildOptions)    # toolcode : option\r
1113     OutputFlag          = property(_GetOuputFlags)    # toolcode : output flag\r
1114     IncludeFlag         = property(_GetIncludeFlags)    # toolcode : include flag\r
1115     ToolOption          = property(_GetToolOptions)    # toolcode : tool option string\r
1116 \r
1117     BuildCommand        = property(_GetBuildCommand)\r
1118     BuildRule           = property(_GetBuildRule)\r
1119     ModuleAutoGenList   = property(_GetModuleAutoGenList)\r
1120     LibraryAutoGenList  = property(_GetLibraryAutoGenList)\r
1121 \r
1122 ## ModuleAutoGen class\r
1123 #\r
1124 # This class encapsules the AutoGen behaviors for the build tools. In addition to\r
1125 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according\r
1126 # to the [depex] section in module's inf file.\r
1127 #\r
1128 class ModuleAutoGen(AutoGen):\r
1129     ## The real constructor of ModuleAutoGen\r
1130     #\r
1131     #  This method is not supposed to be called by users of ModuleAutoGen. It's\r
1132     #  only used by factory method __new__() to do real initialization work for an\r
1133     #  object of ModuleAutoGen\r
1134     #\r
1135     #   @param      Workspace           EdkIIWorkspaceBuild object\r
1136     #   @param      ModuleFile          The path of module file\r
1137     #   @param      Target              Build target (DEBUG, RELEASE)\r
1138     #   @param      Toolchain           Name of tool chain\r
1139     #   @param      Arch                The arch the module supports\r
1140     #   @param      PlatformFile        Platform meta-file\r
1141     #\r
1142     def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):\r
1143         EdkLogger.verbose("\nAutoGen module [%s] [%s]" % (ModuleFile, Arch))\r
1144 \r
1145         self.Workspace = Workspace\r
1146         self.WorkspaceDir = Workspace.WorkspaceDir\r
1147 \r
1148         self._MetaFile = str(ModuleFile)\r
1149         self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)\r
1150         # check if this module is employed by active platform\r
1151         if not self.PlatformInfo.ValidModule(self._MetaFile):\r
1152             EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \\r
1153                               % (self._MetaFile, Arch))\r
1154             return False\r
1155 \r
1156         self.SourceDir = path.dirname(self._MetaFile)\r
1157         self.FileBase, self.FileExt = path.splitext(path.basename(self._MetaFile))\r
1158 \r
1159         self.ToolChain = Toolchain\r
1160         self.ToolChainFamily = "MSFT"\r
1161         self.BuildTarget = Target\r
1162         self.Arch = Arch\r
1163 \r
1164         self.IsMakeFileCreated = False\r
1165         self.IsCodeFileCreated = False\r
1166 \r
1167         self.BuildDatabase = self.Workspace.BuildDatabase\r
1168 \r
1169         self._Module          = None\r
1170         self._Name            = None\r
1171         self._Guid            = None\r
1172         self._Version         = None\r
1173         self._ModuleType      = None\r
1174         self._ComponentType   = None\r
1175         self._PcdIsDriver     = None\r
1176         self._AutoGenVersion  = None\r
1177         self._LibraryFlag     = None\r
1178         self._CustomMakefile  = None\r
1179         self._Macro           = None\r
1180 \r
1181         self._BuildDir        = None\r
1182         self._OutputDir       = None\r
1183         self._DebugDir        = None\r
1184         self._MakeFileDir     = None\r
1185 \r
1186         self._IncludePathList = None\r
1187         self._AutoGenFileList = None\r
1188         self._UnicodeFileList = None\r
1189         self._SourceFileList  = None\r
1190         self._ObjectFileList  = None\r
1191         self._BinaryFileDict  = None\r
1192 \r
1193         self._DependentPackageList    = None\r
1194         self._DependentLibraryList    = None\r
1195         self._LibraryAutoGenList      = None\r
1196         self._DerivedPackageList      = None\r
1197         self._PcdList                 = None\r
1198         self._GuidList                = None\r
1199         self._ProtocolList            = None\r
1200         self._PpiList                 = None\r
1201         self._DepexList               = None\r
1202         self._BuildOption             = None\r
1203 \r
1204         return True\r
1205 \r
1206 \r
1207     ## Return the module build data object\r
1208     def _GetModule(self):\r
1209         if self._Module == None:\r
1210             self._Module = self.Workspace.BuildDatabase[self._MetaFile, self.Arch]\r
1211         return self._Module\r
1212 \r
1213     ## Return the module name\r
1214     def _GetBaseName(self):\r
1215         return self.Module.BaseName\r
1216 \r
1217     ## Return the module meta-file GUID\r
1218     def _GetGuid(self):\r
1219         return self.Module.Guid\r
1220 \r
1221     ## Return the module version\r
1222     def _GetVersion(self):\r
1223         return self.Module.Version\r
1224 \r
1225     ## Return the module type\r
1226     def _GetModuleType(self):\r
1227         return self.Module.ModuleType\r
1228 \r
1229     ## Return the component type (for R8.x style of module)\r
1230     def _GetComponentType(self):\r
1231         return self.Module.ComponentType\r
1232 \r
1233     ## Return the PCD_IS_DRIVER setting\r
1234     def _GetPcdIsDriver(self):\r
1235         return self.Module.PcdIsDriver\r
1236 \r
1237     ## Return the autogen version, i.e. module meta-file version\r
1238     def _GetAutoGenVersion(self):\r
1239         return self.Module.AutoGenVersion\r
1240 \r
1241     ## Check if the module is library or not\r
1242     def _IsLibrary(self):\r
1243         if self._LibraryFlag == None:\r
1244             if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
1245                 self._LibraryFlag = True\r
1246             else:\r
1247                 self._LibraryFlag = False\r
1248         return self._LibraryFlag\r
1249 \r
1250     ## Return the directory to store intermediate files of the module\r
1251     def _GetBuildDir(self):\r
1252         if self._BuildDir == None:\r
1253             self._BuildDir = path.join(\r
1254                                     self.PlatformInfo.BuildDir,\r
1255                                     self.Arch,\r
1256                                     self.SourceDir,\r
1257                                     self.FileBase\r
1258                                     )\r
1259         return self._BuildDir\r
1260 \r
1261     ## Return the directory to store the intermediate object files of the mdoule\r
1262     def _GetOutputDir(self):\r
1263         if self._OutputDir == None:\r
1264             self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
1265         return self._OutputDir\r
1266 \r
1267     ## Return the directory to store auto-gened source files of the mdoule\r
1268     def _GetDebugDir(self):\r
1269         if self._DebugDir == None:\r
1270             self._DebugDir = path.join(self.BuildDir, "DEBUG")\r
1271         return self._DebugDir\r
1272 \r
1273     ## Return the path of custom file\r
1274     def _GetCustomMakefile(self):\r
1275         if self._CustomMakefile == None:\r
1276             self._CustomMakefile = {}\r
1277             for Type in self.Module.CustomMakefile:\r
1278                 MakeType = gMakeTypeMap[Type]\r
1279                 self._CustomMakefile[MakeType] = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])    \r
1280         return self._CustomMakefile\r
1281 \r
1282     ## Return the directory of the makefile\r
1283     #\r
1284     #   @retval     string  The directory string of module's makefile\r
1285     #\r
1286     def _GetMakeFileDir(self):\r
1287         return self.BuildDir\r
1288 \r
1289     ## Return build command string\r
1290     #\r
1291     #   @retval     string  Build command string\r
1292     #\r
1293     def _GetBuildCommand(self):\r
1294         return self.PlatformInfo.BuildCommand\r
1295 \r
1296     ## Get object list of all packages the module and its dependent libraries belong to\r
1297     #\r
1298     #   @retval     list    The list of package object\r
1299     #\r
1300     def _GetDerivedPackageList(self):\r
1301         PackageList = []\r
1302         for M in [self.Module] + self.DependentLibraryList:\r
1303             for Package in M.Packages:\r
1304                 if Package in PackageList:\r
1305                     continue\r
1306                 PackageList.append(Package)\r
1307         return PackageList\r
1308 \r
1309     ## Merge dependency expression\r
1310     #\r
1311     #   @retval     list    The token list of the dependency expression after parsed\r
1312     #\r
1313     def _GetDepexTokenList(self):\r
1314         if self._DepexList == None:\r
1315             self._DepexList = self.Module.Depex\r
1316             EdkLogger.verbose("DEPEX = %s" % self._DepexList)\r
1317             #\r
1318             # Append depex from dependent libraries\r
1319             #\r
1320             for Lib in self.DependentLibraryList:\r
1321                 if Lib.Depex != None and Lib.Depex != []:\r
1322                     if self._DepexList != []:\r
1323                         self._DepexList.append('AND')\r
1324                     self._DepexList.append('(')\r
1325                     self._DepexList.extend(Lib.Depex)\r
1326                     self._DepexList.append(')')\r
1327                     EdkLogger.verbose("DEPEX (+%s) = %s" % (Lib.BaseName, self._DepexList))\r
1328 \r
1329             for I in range(0, len(self._DepexList)):\r
1330                 Token = self._DepexList[I]\r
1331                 if Token.endswith(".inf"):  # module file name\r
1332                     ModuleFile = os.path.normpath(Token)\r
1333                     self._DepexList[I] = self.BuildDatabase[ModuleFile].Guid\r
1334         return self._DepexList\r
1335 \r
1336     ## Return the list of macro in module\r
1337     #\r
1338     #   @retval     list    The list of macro defined in module file\r
1339     #\r
1340     def _GetMacroList(self):\r
1341         return self.Module.Specification\r
1342 \r
1343     ## Tool option for the module build\r
1344     #\r
1345     #   @param      PlatformInfo    The object of PlatformBuildInfo\r
1346     #   @retval     dict            The dict containing valid options\r
1347     #\r
1348     def _GetModuleBuildOption(self):\r
1349         if self._BuildOption == None:\r
1350             self._BuildOption = self.PlatformInfo.ApplyBuildOption(self.Module)\r
1351         return self._BuildOption\r
1352 \r
1353     ## Return a list of files which can be built from source\r
1354     #\r
1355     #  What kind of files can be built is determined by build rules in\r
1356     #  $(WORKSPACE)/Conf/build_rule.txt and toolchain family.\r
1357     #\r
1358     def _GetSourceFileList(self):\r
1359         if self._SourceFileList != None:\r
1360             return self._SourceFileList\r
1361 \r
1362         self._SourceFileList = []\r
1363         self._UnicodeFileList = []\r
1364         # use toolchain family of CC as the primary toolchain family\r
1365         if "CC" not in self.PlatformInfo.ToolChainFamily:\r
1366             EdkLogger.error("AutoGen", AUTOGEN_ERROR, "Tool [CC] is not defined for %s [%s, %s]" \\r
1367                              % (self.ToolChain, self.BuildTarget, self.Arch))\r
1368         ToolChainFamily = self.PlatformInfo.ToolChainFamily["CC"]\r
1369         BuildRule = self.PlatformInfo.BuildRule\r
1370         for F in self.Module.Sources:\r
1371             SourceFile = F.SourceFile\r
1372             # match tool chain\r
1373             if F.TagName != "" and F.TagName != self.ToolChain:\r
1374                 EdkLogger.verbose("The toolchain [%s] for processing file [%s] is found, "\r
1375                                   "but [%s] is needed" % (F.TagName, F.SourceFile, self.ToolChain))\r
1376                 continue\r
1377             # match tool chain family\r
1378             if F.ToolChainFamily != "" and F.ToolChainFamily != ToolChainFamily:\r
1379                 EdkLogger.verbose("The file [%s] must be built by tools of [%s], "\r
1380                                   "but current toolchain family is [%s]" % (SourceFile, F.ToolChainFamily, ToolChainFamily))\r
1381                 continue\r
1382 \r
1383             # add the file path into search path list for file including\r
1384             Dir = path.dirname(SourceFile)\r
1385             if Dir != "":\r
1386                 Dir = path.join(self.WorkspaceDir, self.SourceDir, Dir)\r
1387                 if Dir not in self.IncludePathList:\r
1388                     self.IncludePathList.insert(0, Dir)\r
1389 \r
1390             # skip unknown file\r
1391             Base, Ext = path.splitext(SourceFile)\r
1392 \r
1393             # skip file which needs a tool having no matching toolchain family\r
1394             FileType, RuleObject = BuildRule.Get(Ext, ToolChainFamily)\r
1395             # unicode must be processed by AutoGen\r
1396             if FileType == "Unicode-Text-File":\r
1397                 self._UnicodeFileList.append(os.path.join(self.WorkspaceDir, self.SourceDir, SourceFile))\r
1398 \r
1399             # if there's dxs file, don't use content in [depex] section to generate .depex file\r
1400             if FileType == "Dependency-Expression-File":\r
1401                 self._DepexList = []\r
1402 \r
1403             # no command, no build\r
1404             if RuleObject != None and RuleObject.CommandList == []:\r
1405                 RuleObject = None\r
1406             if [SourceFile, FileType, RuleObject] not in self._SourceFileList:\r
1407                 self._SourceFileList.append([SourceFile, FileType, RuleObject])\r
1408 \r
1409         return self._SourceFileList\r
1410 \r
1411     ## Return the list of unicode files\r
1412     def _GetUnicodeFileList(self):\r
1413         if self._UnicodeFileList == None:\r
1414             self._GetSourceFileList()\r
1415         return self._UnicodeFileList\r
1416 \r
1417     ## Return a list of files which can be built from binary\r
1418     #\r
1419     #  "Build" binary files are just to copy them to build directory.\r
1420     #\r
1421     #   @retval     list            The list of files which can be built later\r
1422     #\r
1423     def _GetBinaryFiles(self):\r
1424         if self._BinaryFileDict == None:\r
1425             self._BinaryFileDict = sdict()\r
1426             for F in self.Module.Binaries:\r
1427                 if F.Target != '*' and F.Target != self.BuildTarget:\r
1428                     continue\r
1429                 if F.FileType not in self._BinaryFileDict:\r
1430                     self._BinaryFileDict[F.FileType] = []\r
1431                 self._BinaryFileDict[F.FileType].append(F.BinaryFile)\r
1432         return self._BinaryFileDict\r
1433 \r
1434     ## Get the list of package object the module depends on\r
1435     #\r
1436     #   @retval     list    The package object list\r
1437     #\r
1438     def _GetDependentPackageList(self):\r
1439         return self.Module.Packages\r
1440 \r
1441     ## Return the list of auto-generated code file\r
1442     #\r
1443     #   @retval     list        The list of auto-generated file\r
1444     #\r
1445     def _GetAutoGenFileList(self):\r
1446         if self._AutoGenFileList == None:\r
1447             self._AutoGenFileList = {}\r
1448             AutoGenC = TemplateString()\r
1449             AutoGenH = TemplateString()\r
1450             GenC.CreateCode(self, AutoGenC, AutoGenH)\r
1451             if str(AutoGenC) != "":\r
1452                 self._AutoGenFileList[gAutoGenCodeFileName] = AutoGenC\r
1453             if str(AutoGenH) != "":\r
1454                 self._AutoGenFileList[gAutoGenHeaderFileName] = AutoGenH\r
1455         return self._AutoGenFileList\r
1456 \r
1457     ## Return the list of library modules explicitly or implicityly used by this module\r
1458     def _GetLibraryList(self):\r
1459         if self._DependentLibraryList == None:\r
1460             # only merge library classes and PCD for non-library module\r
1461             if self.IsLibrary:\r
1462                 self._DependentLibraryList = []\r
1463             else:\r
1464                 if self.AutoGenVersion < 0x00010005:\r
1465                     self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)\r
1466                 else:\r
1467                     self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)\r
1468         return self._DependentLibraryList\r
1469 \r
1470     ## Get the list of PCD\r
1471     #\r
1472     #   @retval     list                    The list of PCD\r
1473     #\r
1474     def _GetPcdList(self):\r
1475         if self._PcdList == None:\r
1476             if not self.IsLibrary:\r
1477                 # derive PCDs from libraries first\r
1478                 for Library in self.DependentLibraryList:\r
1479                     for Key in Library.Pcds:\r
1480                         if Key in self.Module.Pcds:\r
1481                             continue\r
1482                         self.Module.Pcds[Key] = Library.Pcds[Key]\r
1483                 # apply PCD settings from platform            \r
1484             self._PcdList = self.PlatformInfo.ApplyPcdSetting(self.Module)\r
1485         return self._PcdList\r
1486 \r
1487     ## Get the GUID value mapping\r
1488     #\r
1489     #   @retval     dict    The mapping between GUID cname and its value\r
1490     #\r
1491     def _GetGuidList(self):\r
1492         if self._GuidList == None:\r
1493             self._GuidList = self.Module.Guids\r
1494             for Library in self.DependentLibraryList:\r
1495                 self._GuidList.update(Library.Guids)\r
1496         return self._GuidList\r
1497 \r
1498     ## Get the protocol value mapping\r
1499     #\r
1500     #   @retval     dict    The mapping between protocol cname and its value\r
1501     #\r
1502     def _GetProtocolList(self):\r
1503         if self._ProtocolList == None:\r
1504             self._ProtocolList = self.Module.Protocols\r
1505             for Library in self.DependentLibraryList:\r
1506                 self._ProtocolList.update(Library.Protocols)\r
1507         return self._ProtocolList\r
1508 \r
1509     ## Get the PPI value mapping\r
1510     #\r
1511     #   @retval     dict    The mapping between PPI cname and its value\r
1512     #\r
1513     def _GetPpiList(self):\r
1514         if self._PpiList == None:\r
1515             self._PpiList = self.Module.Ppis\r
1516             for Library in self.DependentLibraryList:\r
1517                 self._PpiList.update(Library.Ppis)\r
1518         return self._PpiList\r
1519 \r
1520     ## Get the list of include search path\r
1521     #\r
1522     #   @retval     list                    The list path\r
1523     #\r
1524     def _GetIncludePathList(self):\r
1525         if self._IncludePathList == None:\r
1526             self._IncludePathList = []\r
1527             if self.AutoGenVersion < 0x00010005:\r
1528                 for Inc in self.Module.Includes:\r
1529                     # '.' means "relative to module directory".\r
1530                     if Inc[0] == ".":\r
1531                         Inc = path.join(self.WorkspaceDir, self.SourceDir, Inc)\r
1532                     else:\r
1533                         Inc = path.join(self.WorkspaceDir, Inc)\r
1534                     if Inc in self._IncludePathList:\r
1535                         continue\r
1536                     self._IncludePathList.append(Inc)\r
1537                     # for r8 modules\r
1538                     self._IncludePathList.append(path.join(Inc, self.Arch.capitalize()))\r
1539                 # r8 module needs to put DEBUG_DIR at the end search path and not to use SOURCE_DIR all the time\r
1540                 self._IncludePathList.append(self.DebugDir)\r
1541             else:\r
1542                 self._IncludePathList.append(os.path.join(self.WorkspaceDir, self.SourceDir))\r
1543                 self._IncludePathList.append(self.DebugDir)\r
1544 \r
1545             for Package in self.Module.Packages:\r
1546                 PackageDir = path.join(self.WorkspaceDir, path.dirname(str(Package)))\r
1547                 if PackageDir not in self._IncludePathList:\r
1548                     self._IncludePathList.append(PackageDir)\r
1549                 for Inc in Package.Includes:\r
1550                     Inc = path.join(PackageDir, Inc)\r
1551                     if Inc not in self._IncludePathList:\r
1552                         self._IncludePathList.append(Inc)\r
1553         return self._IncludePathList\r
1554 \r
1555     ## Create makefile for the module and its dependent libraries\r
1556     #\r
1557     #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of\r
1558     #                                       dependent libraries will be created\r
1559     #\r
1560     def CreateMakeFile(self, CreateLibraryMakeFile=True):\r
1561         if self.IsMakeFileCreated:\r
1562             return\r
1563 \r
1564         PlatformInfo = self.PlatformInfo\r
1565         if not self.IsLibrary and CreateLibraryMakeFile:\r
1566             for LibraryAutoGen in self.LibraryAutoGenList:\r
1567                 LibraryAutoGen.CreateMakeFile()\r
1568 \r
1569         if len(self.CustomMakefile) == 0:\r
1570             Makefile = GenMake.ModuleMakefile(self)\r
1571         else:\r
1572             Makefile = GenMake.CustomMakefile(self)\r
1573         if Makefile.Generate():\r
1574             EdkLogger.verbose("Generated makefile for module %s [%s]" %\r
1575                            (self.Name, self.Arch))\r
1576         else:\r
1577             EdkLogger.verbose("Skipped the generation of makefile for module %s [%s]" %\r
1578                               (self.Name, self.Arch))\r
1579 \r
1580         self.IsMakeFileCreated = True\r
1581 \r
1582     ## Create autogen code for the module and its dependent libraries\r
1583     #\r
1584     #   @param      CreateLibraryCodeFile   Flag indicating if or not the code of\r
1585     #                                       dependent libraries will be created\r
1586     #\r
1587     def CreateCodeFile(self, CreateLibraryCodeFile=True):\r
1588         if self.IsCodeFileCreated:\r
1589             return\r
1590 \r
1591         PlatformInfo = self.PlatformInfo\r
1592         if not self.IsLibrary and CreateLibraryCodeFile:\r
1593             for LibraryAutoGen in self.LibraryAutoGenList:\r
1594                 LibraryAutoGen.CreateCodeFile()\r
1595 \r
1596         AutoGenList = []\r
1597         IgoredAutoGenList = []\r
1598         for File in self.AutoGenFileList:\r
1599             if GenC.Generate(path.join(self.DebugDir, File), str(self.AutoGenFileList[File])):\r
1600                 AutoGenList.append(File)\r
1601             else:\r
1602                 IgoredAutoGenList.append(File)\r
1603 \r
1604         if self.DepexList != []:\r
1605             Dpx = GenDepex.DependencyExpression(self.DepexList, self.ModuleType, True)\r
1606             DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}\r
1607 \r
1608             if Dpx.Generate(path.join(self.OutputDir, DpxFile)):\r
1609                 AutoGenList.append(DpxFile)\r
1610             else:\r
1611                 IgoredAutoGenList.append(DpxFile)\r
1612 \r
1613         if IgoredAutoGenList == []:\r
1614             EdkLogger.verbose("Generated [%s] files for module %s [%s]" %\r
1615                            (" ".join(AutoGenList), self.Name, self.Arch))\r
1616         elif AutoGenList == []:\r
1617             EdkLogger.verbose("Skipped the generation of [%s] files for module %s [%s]" %\r
1618                            (" ".join(IgoredAutoGenList), self.Name, self.Arch))\r
1619         else:\r
1620             EdkLogger.verbose("Generated [%s] (skipped %s) files for module %s [%s]" %\r
1621                            (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))\r
1622 \r
1623         self.IsCodeFileCreated = True\r
1624         return AutoGenList\r
1625 \r
1626     ## Summarize the ModuleAutoGen objects of all libraries used by this module\r
1627     def _GetLibraryAutoGenList(self):\r
1628         if self._LibraryAutoGenList == None:\r
1629             self._LibraryAutoGenList = []\r
1630             for Library in self.DependentLibraryList:\r
1631                 La = ModuleAutoGen(\r
1632                         self.Workspace,\r
1633                         str(Library),\r
1634                         self.BuildTarget,\r
1635                         self.ToolChain,\r
1636                         self.Arch,\r
1637                         str(self.PlatformInfo)\r
1638                         )\r
1639                 if La not in self._LibraryAutoGenList:\r
1640                     self._LibraryAutoGenList.append(La)\r
1641         return self._LibraryAutoGenList\r
1642 \r
1643     ## Return build command string\r
1644     #\r
1645     #   @retval     string  Build command string\r
1646     #\r
1647     def _GetBuildCommand(self):\r
1648         return self.PlatformInfo.BuildCommand\r
1649 \r
1650 \r
1651     Module          = property(_GetModule)\r
1652     Name            = property(_GetBaseName)\r
1653     Guid            = property(_GetGuid)\r
1654     Version         = property(_GetVersion)\r
1655     ModuleType      = property(_GetModuleType)\r
1656     ComponentType   = property(_GetComponentType)\r
1657     PcdIsDriver     = property(_GetPcdIsDriver)\r
1658     AutoGenVersion  = property(_GetAutoGenVersion)\r
1659     Macro           = property(_GetMacroList)\r
1660 \r
1661     IsLibrary       = property(_IsLibrary)\r
1662 \r
1663     BuildDir        = property(_GetBuildDir)\r
1664     OutputDir       = property(_GetOutputDir)\r
1665     DebugDir        = property(_GetDebugDir)\r
1666     MakeFileDir     = property(_GetMakeFileDir)\r
1667     CustomMakefile  = property(_GetCustomMakefile)\r
1668 \r
1669     IncludePathList = property(_GetIncludePathList)\r
1670     AutoGenFileList = property(_GetAutoGenFileList)\r
1671     UnicodeFileList = property(_GetUnicodeFileList)\r
1672     SourceFileList  = property(_GetSourceFileList)\r
1673     BinaryFileDict  = property(_GetBinaryFiles) # FileType : [File List]\r
1674 \r
1675     DependentPackageList    = property(_GetDependentPackageList)\r
1676     DependentLibraryList    = property(_GetLibraryList)\r
1677     LibraryAutoGenList      = property(_GetLibraryAutoGenList)\r
1678     DerivedPackageList      = property(_GetDerivedPackageList)\r
1679 \r
1680     PcdList                 = property(_GetPcdList)\r
1681     GuidList                = property(_GetGuidList)\r
1682     ProtocolList            = property(_GetProtocolList)\r
1683     PpiList                 = property(_GetPpiList)\r
1684     DepexList               = property(_GetDepexTokenList)\r
1685     BuildOption             = property(_GetModuleBuildOption)\r
1686     BuildCommand            = property(_GetBuildCommand)\r
1687 \r
1688 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
1689 if __name__ == '__main__':\r
1690     pass\r
1691 \r