Sync EDKII BaseTools to BaseTools project r1903.
[efi/edk2/.git] / edk2 / BaseTools / Source / Python / AutoGen / AutoGen.py
1 ## @file\r
2 # Generate AutoGen.h, AutoGen.c and *.depex files\r
3 #\r
4 # Copyright (c) 2007 - 2010, 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 os\r
17 import re\r
18 import os.path as path\r
19 import copy\r
20 \r
21 import GenC\r
22 import GenMake\r
23 import GenDepex\r
24 from StringIO import StringIO\r
25 \r
26 from StrGather import *\r
27 from BuildEngine import BuildRule\r
28 \r
29 from Common.BuildToolError import *\r
30 from Common.DataType import *\r
31 from Common.Misc import *\r
32 from Common.String import *\r
33 import Common.GlobalData as GlobalData\r
34 from GenFds.FdfParser import *\r
35 from CommonDataClass.CommonClass import SkuInfoClass\r
36 from Workspace.BuildClassObject import *\r
37 \r
38 ## Regular expression for splitting Dependency Expression stirng into tokens\r
39 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
40 \r
41 ## Mapping Makefile type\r
42 gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}\r
43 \r
44 \r
45 ## Build rule configuration file\r
46 gBuildRuleFile = 'Conf/build_rule.txt'\r
47 \r
48 ## default file name for AutoGen\r
49 gAutoGenCodeFileName = "AutoGen.c"\r
50 gAutoGenHeaderFileName = "AutoGen.h"\r
51 gAutoGenStringFileName = "%(module_name)sStrDefs.h"\r
52 gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"\r
53 gAutoGenDepexFileName = "%(module_name)s.depex"\r
54 \r
55 ## Base class for AutoGen\r
56 #\r
57 #   This class just implements the cache mechanism of AutoGen objects.\r
58 #\r
59 class AutoGen(object):\r
60     # database to maintain the objects of xxxAutoGen\r
61     _CACHE_ = {}    # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}\r
62 \r
63     ## Factory method\r
64     #\r
65     #   @param  Class           class object of real AutoGen class\r
66     #                           (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)\r
67     #   @param  Workspace       Workspace directory or WorkspaceAutoGen object\r
68     #   @param  MetaFile        The path of meta file\r
69     #   @param  Target          Build target\r
70     #   @param  Toolchain       Tool chain name\r
71     #   @param  Arch            Target arch\r
72     #   @param  *args           The specific class related parameters\r
73     #   @param  **kwargs        The specific class related dict parameters\r
74     #\r
75     def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
76         # check if the object has been created\r
77         Key = (Target, Toolchain)\r
78         if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \\r
79            or MetaFile not in Class._CACHE_[Key][Arch]:\r
80             AutoGenObject = super(AutoGen, Class).__new__(Class)\r
81             # call real constructor\r
82             if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):\r
83                 return None\r
84             if Key not in Class._CACHE_:\r
85                 Class._CACHE_[Key] = {}\r
86             if Arch not in Class._CACHE_[Key]:\r
87                 Class._CACHE_[Key][Arch] = {}\r
88             Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject\r
89         else:\r
90             AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]\r
91 \r
92         return AutoGenObject\r
93 \r
94     ## hash() operator\r
95     #\r
96     #  The file path of platform file will be used to represent hash value of this object\r
97     #\r
98     #   @retval int     Hash value of the file path of platform file\r
99     #\r
100     def __hash__(self):\r
101         return hash(self.MetaFile)\r
102 \r
103     ## str() operator\r
104     #\r
105     #  The file path of platform file will be used to represent this object\r
106     #\r
107     #   @retval string  String of platform file path\r
108     #\r
109     def __str__(self):\r
110         return str(self.MetaFile)\r
111 \r
112     ## "==" operator\r
113     def __eq__(self, Other):\r
114         return Other and self.MetaFile == Other\r
115 \r
116 ## Workspace AutoGen class\r
117 #\r
118 #   This class is used mainly to control the whole platform build for different\r
119 # architecture. This class will generate top level makefile.\r
120 #\r
121 class WorkspaceAutoGen(AutoGen):\r
122     ## Real constructor of WorkspaceAutoGen\r
123     #\r
124     # This method behaves the same as __init__ except that it needs explict invoke\r
125     # (in super class's __new__ method)\r
126     #\r
127     #   @param  WorkspaceDir            Root directory of workspace\r
128     #   @param  ActivePlatform          Meta-file of active platform\r
129     #   @param  Target                  Build target\r
130     #   @param  Toolchain               Tool chain name\r
131     #   @param  ArchList                List of architecture of current build\r
132     #   @param  MetaFileDb              Database containing meta-files\r
133     #   @param  BuildConfig             Configuration of build\r
134     #   @param  ToolDefinition          Tool chain definitions\r
135     #   @param  FlashDefinitionFile     File of flash definition\r
136     #   @param  Fds                     FD list to be generated\r
137     #   @param  Fvs                     FV list to be generated\r
138     #   @param  SkuId                   SKU id from command line\r
139     #\r
140     def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,\r
141               BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=[], Fvs=[], SkuId=''):\r
142         self.MetaFile       = ActivePlatform.MetaFile\r
143         self.WorkspaceDir   = WorkspaceDir\r
144         self.Platform       = ActivePlatform\r
145         self.BuildTarget    = Target\r
146         self.ToolChain      = Toolchain\r
147         self.ArchList       = ArchList\r
148         self.SkuId          = SkuId\r
149 \r
150         self.BuildDatabase  = MetaFileDb\r
151         self.TargetTxt      = BuildConfig\r
152         self.ToolDef        = ToolDefinition\r
153         self.FdfFile        = FlashDefinitionFile\r
154         self.FdTargetList   = Fds\r
155         self.FvTargetList   = Fvs\r
156         self.AutoGenObjectList = []\r
157 \r
158         # there's many relative directory operations, so ...\r
159         os.chdir(self.WorkspaceDir)\r
160 \r
161         # parse FDF file to get PCDs in it, if any\r
162         if self.FdfFile != None and self.FdfFile != '':\r
163             Fdf = FdfParser(self.FdfFile.Path)\r
164             Fdf.ParseFile()\r
165             PcdSet = Fdf.Profile.PcdDict\r
166             ModuleList = Fdf.Profile.InfList\r
167             self.FdfProfile = Fdf.Profile\r
168         else:\r
169             PcdSet = {}\r
170             ModuleList = []\r
171             self.FdfProfile = None\r
172         \r
173         # apply SKU and inject PCDs from Flash Definition file\r
174         for Arch in self.ArchList:\r
175             Platform = self.BuildDatabase[self.MetaFile, Arch]\r
176             Platform.SkuName = self.SkuId\r
177             for Name, Guid in PcdSet:\r
178                 Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])\r
179 \r
180             Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
181             #\r
182             # Explicitly collect platform's dynamic PCDs\r
183             #\r
184             Pa.CollectPlatformDynamicPcds()\r
185             self.AutoGenObjectList.append(Pa)\r
186 \r
187         self._BuildDir = None\r
188         self._FvDir = None\r
189         self._MakeFileDir = None\r
190         self._BuildCommand = None\r
191 \r
192         return True\r
193 \r
194     def __repr__(self):\r
195         return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))\r
196 \r
197     ## Return the directory to store FV files\r
198     def _GetFvDir(self):\r
199         if self._FvDir == None:\r
200             self._FvDir = path.join(self.BuildDir, 'FV')\r
201         return self._FvDir\r
202 \r
203     ## Return the directory to store all intermediate and final files built\r
204     def _GetBuildDir(self):\r
205         return self.AutoGenObjectList[0].BuildDir\r
206 \r
207     ## Return the build output directory platform specifies\r
208     def _GetOutputDir(self):\r
209         return self.Platform.OutputDirectory\r
210 \r
211     ## Return platform name\r
212     def _GetName(self):\r
213         return self.Platform.PlatformName\r
214 \r
215     ## Return meta-file GUID\r
216     def _GetGuid(self):\r
217         return self.Platform.Guid\r
218 \r
219     ## Return platform version\r
220     def _GetVersion(self):\r
221         return self.Platform.Version\r
222 \r
223     ## Return paths of tools\r
224     def _GetToolDefinition(self):\r
225         return self.AutoGenObjectList[0].ToolDefinition\r
226 \r
227     ## Return directory of platform makefile\r
228     #\r
229     #   @retval     string  Makefile directory\r
230     #\r
231     def _GetMakeFileDir(self):\r
232         if self._MakeFileDir == None:\r
233             self._MakeFileDir = self.BuildDir\r
234         return self._MakeFileDir\r
235 \r
236     ## Return build command string\r
237     #\r
238     #   @retval     string  Build command string\r
239     #\r
240     def _GetBuildCommand(self):\r
241         if self._BuildCommand == None:\r
242             # BuildCommand should be all the same. So just get one from platform AutoGen\r
243             self._BuildCommand = self.AutoGenObjectList[0].BuildCommand\r
244         return self._BuildCommand\r
245 \r
246     ## Create makefile for the platform and mdoules in it\r
247     #\r
248     #   @param      CreateDepsMakeFile      Flag indicating if the makefile for\r
249     #                                       modules will be created as well\r
250     #\r
251     def CreateMakeFile(self, CreateDepsMakeFile=False):\r
252         # create makefile for platform\r
253         Makefile = GenMake.TopLevelMakefile(self)\r
254         if Makefile.Generate():\r
255             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] %s\n" %\r
256                             (self.MetaFile, self.ArchList))\r
257         else:\r
258             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] %s\n" %\r
259                             (self.MetaFile, self.ArchList))\r
260 \r
261         if CreateDepsMakeFile:\r
262             for Pa in self.AutoGenObjectList:\r
263                 Pa.CreateMakeFile(CreateDepsMakeFile)\r
264 \r
265     ## Create autogen code for platform and modules\r
266     #\r
267     #  Since there's no autogen code for platform, this method will do nothing\r
268     #  if CreateModuleCodeFile is set to False.\r
269     #\r
270     #   @param      CreateDepsCodeFile      Flag indicating if creating module's\r
271     #                                       autogen code file or not\r
272     #\r
273     def CreateCodeFile(self, CreateDepsCodeFile=False):\r
274         if not CreateDepsCodeFile:\r
275             return\r
276         for Pa in self.AutoGenObjectList:\r
277             Pa.CreateCodeFile(CreateDepsCodeFile)\r
278 \r
279     Name                = property(_GetName)\r
280     Guid                = property(_GetGuid)\r
281     Version             = property(_GetVersion)\r
282     OutputDir           = property(_GetOutputDir)\r
283 \r
284     ToolDefinition      = property(_GetToolDefinition)       # toolcode : tool path\r
285 \r
286     BuildDir            = property(_GetBuildDir)\r
287     FvDir               = property(_GetFvDir)\r
288     MakeFileDir         = property(_GetMakeFileDir)\r
289     BuildCommand        = property(_GetBuildCommand)\r
290 \r
291 ## AutoGen class for platform\r
292 #\r
293 #  PlatformAutoGen class will process the original information in platform\r
294 #  file in order to generate makefile for platform.\r
295 #\r
296 class PlatformAutoGen(AutoGen):\r
297     #\r
298     # Used to store all PCDs for both PEI and DXE phase, in order to generate \r
299     # correct PCD database\r
300     # \r
301     _DynaPcdList_ = []\r
302     _NonDynaPcdList_ = []\r
303 \r
304     ## The real constructor of PlatformAutoGen\r
305     #\r
306     #  This method is not supposed to be called by users of PlatformAutoGen. It's\r
307     #  only used by factory method __new__() to do real initialization work for an\r
308     #  object of PlatformAutoGen\r
309     #\r
310     #   @param      Workspace       WorkspaceAutoGen object\r
311     #   @param      PlatformFile    Platform file (DSC file)\r
312     #   @param      Target          Build target (DEBUG, RELEASE)\r
313     #   @param      Toolchain       Name of tool chain\r
314     #   @param      Arch            arch of the platform supports\r
315     #\r
316     def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):\r
317         EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))\r
318         GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)\r
319 \r
320         self.MetaFile = PlatformFile\r
321         self.Workspace = Workspace\r
322         self.WorkspaceDir = Workspace.WorkspaceDir\r
323         self.ToolChain = Toolchain\r
324         self.BuildTarget = Target\r
325         self.Arch = Arch\r
326         self.SourceDir = PlatformFile.SubDir\r
327         self.SourceOverrideDir = None\r
328         self.FdTargetList = self.Workspace.FdTargetList\r
329         self.FvTargetList = self.Workspace.FvTargetList\r
330         self.AllPcdList = []\r
331 \r
332         # flag indicating if the makefile/C-code file has been created or not\r
333         self.IsMakeFileCreated  = False\r
334         self.IsCodeFileCreated  = False\r
335 \r
336         self._Platform   = None\r
337         self._Name       = None\r
338         self._Guid       = None\r
339         self._Version    = None\r
340 \r
341         self._BuildRule = None\r
342         self._SourceDir = None\r
343         self._BuildDir = None\r
344         self._OutputDir = None\r
345         self._FvDir = None\r
346         self._MakeFileDir = None\r
347         self._FdfFile = None\r
348 \r
349         self._PcdTokenNumber = None    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
350         self._DynamicPcdList = None    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
351         self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
352 \r
353         self._ToolDefinitions = None\r
354         self._ToolDefFile = None          # toolcode : tool path\r
355         self._ToolChainFamily = None\r
356         self._BuildRuleFamily = None\r
357         self._BuildOption = None          # toolcode : option\r
358         self._EdkBuildOption = None       # edktoolcode : option\r
359         self._EdkIIBuildOption = None     # edkiitoolcode : option\r
360         self._PackageList = None\r
361         self._ModuleAutoGenList  = None\r
362         self._LibraryAutoGenList = None\r
363         self._BuildCommand = None\r
364 \r
365         # get the original module/package/platform objects\r
366         self.BuildDatabase = Workspace.BuildDatabase\r
367         return True\r
368 \r
369     def __repr__(self):\r
370         return "%s [%s]" % (self.MetaFile, self.Arch)\r
371 \r
372     ## Create autogen code for platform and modules\r
373     #\r
374     #  Since there's no autogen code for platform, this method will do nothing\r
375     #  if CreateModuleCodeFile is set to False.\r
376     #\r
377     #   @param      CreateModuleCodeFile    Flag indicating if creating module's\r
378     #                                       autogen code file or not\r
379     #\r
380     def CreateCodeFile(self, CreateModuleCodeFile=False):\r
381         # only module has code to be greated, so do nothing if CreateModuleCodeFile is False\r
382         if self.IsCodeFileCreated or not CreateModuleCodeFile:\r
383             return\r
384 \r
385         for Ma in self.ModuleAutoGenList:\r
386             Ma.CreateCodeFile(True)\r
387 \r
388         # don't do this twice\r
389         self.IsCodeFileCreated = True\r
390 \r
391     ## Create makefile for the platform and mdoules in it\r
392     #\r
393     #   @param      CreateModuleMakeFile    Flag indicating if the makefile for\r
394     #                                       modules will be created as well\r
395     #\r
396     def CreateMakeFile(self, CreateModuleMakeFile=False):\r
397         if CreateModuleMakeFile:\r
398             for ModuleFile in self.Platform.Modules:\r
399                 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,\r
400                                    self.ToolChain, self.Arch, self.MetaFile)\r
401                 Ma.CreateMakeFile(True)\r
402 \r
403         # no need to create makefile for the platform more than once\r
404         if self.IsMakeFileCreated:\r
405             return\r
406 \r
407         # create makefile for platform\r
408         Makefile = GenMake.PlatformMakefile(self)\r
409         if Makefile.Generate():\r
410             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for platform [%s] [%s]\n" %\r
411                             (self.MetaFile, self.Arch))\r
412         else:\r
413             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for platform [%s] [%s]\n" %\r
414                             (self.MetaFile, self.Arch))\r
415         self.IsMakeFileCreated = True\r
416 \r
417     ## Collect dynamic PCDs\r
418     #\r
419     #  Gather dynamic PCDs list from each module and their settings from platform\r
420     #  This interface should be invoked explicitly when platform action is created.\r
421     #\r
422     def CollectPlatformDynamicPcds(self):\r
423         # for gathering error information\r
424         NoDatumTypePcdList = set()\r
425 \r
426         self._GuidValue = {}\r
427         for F in self.Platform.Modules.keys():\r
428             M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)\r
429             #GuidValue.update(M.Guids)\r
430             \r
431             self.Platform.Modules[F].M = M\r
432             \r
433             for PcdFromModule in M.ModulePcdList+M.LibraryPcdList:\r
434                 # make sure that the "VOID*" kind of datum has MaxDatumSize set\r
435                 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize == None:\r
436                     NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))\r
437 \r
438                 if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:\r
439                     #\r
440                     # If a dynamic PCD used by a PEM module/PEI module & DXE module,\r
441                     # it should be stored in Pcd PEI database, If a dynamic only\r
442                     # used by DXE module, it should be stored in DXE PCD database.\r
443                     # The default Phase is DXE\r
444                     #\r
445                     if M.ModuleType in ["PEIM", "PEI_CORE"]:\r
446                         PcdFromModule.Phase = "PEI"\r
447                     if PcdFromModule not in self._DynaPcdList_:\r
448                         self._DynaPcdList_.append(PcdFromModule)\r
449                     elif PcdFromModule.Phase == 'PEI':\r
450                         # overwrite any the same PCD existing, if Phase is PEI\r
451                         Index = self._DynaPcdList_.index(PcdFromModule)\r
452                         self._DynaPcdList_[Index] = PcdFromModule\r
453                 elif PcdFromModule not in self._NonDynaPcdList_:\r
454                     self._NonDynaPcdList_.append(PcdFromModule)\r
455 \r
456         # print out error information and break the build, if error found\r
457         if len(NoDatumTypePcdList) > 0:\r
458             NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)\r
459             EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",\r
460                             File=self.MetaFile,\r
461                             ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
462                                       % NoDatumTypePcdListString)\r
463         self._NonDynamicPcdList = self._NonDynaPcdList_\r
464         self._DynamicPcdList = self._DynaPcdList_\r
465         self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList\r
466         \r
467         #\r
468         # Sort dynamic PCD list to:\r
469         # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should \r
470         #    try to be put header of dynamicd List\r
471         # 2) If PCD is HII type, the PCD item should be put after unicode type PCD\r
472         #\r
473         # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.\r
474         #\r
475         UnicodePcdArray = []\r
476         HiiPcdArray     = []\r
477         OtherPcdArray   = []\r
478         for Pcd in self._DynamicPcdList:\r
479             # just pick the a value to determine whether is unicode string type\r
480             Sku      = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]\r
481             PcdValue = Sku.DefaultValue\r
482             if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):\r
483                 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex\r
484                 UnicodePcdArray.append(Pcd)\r
485             elif len(Sku.VariableName) > 0:\r
486                 # if found HII type PCD then insert to right of UnicodeIndex\r
487                 HiiPcdArray.append(Pcd)\r
488             else:\r
489                 OtherPcdArray.append(Pcd)\r
490         del self._DynamicPcdList[:]\r
491         self._DynamicPcdList.extend(UnicodePcdArray)\r
492         self._DynamicPcdList.extend(HiiPcdArray)\r
493         self._DynamicPcdList.extend(OtherPcdArray)\r
494             \r
495         \r
496     ## Return the platform build data object\r
497     def _GetPlatform(self):\r
498         if self._Platform == None:\r
499             self._Platform = self.BuildDatabase[self.MetaFile, self.Arch]\r
500         return self._Platform\r
501 \r
502     ## Return platform name\r
503     def _GetName(self):\r
504         return self.Platform.PlatformName\r
505 \r
506     ## Return the meta file GUID\r
507     def _GetGuid(self):\r
508         return self.Platform.Guid\r
509 \r
510     ## Return the platform version\r
511     def _GetVersion(self):\r
512         return self.Platform.Version\r
513 \r
514     ## Return the FDF file name\r
515     def _GetFdfFile(self):\r
516         if self._FdfFile == None:\r
517             if self.Workspace.FdfFile != "":\r
518                 self._FdfFile= path.join(self.WorkspaceDir, self.Workspace.FdfFile)\r
519             else:\r
520                 self._FdfFile = ''\r
521         return self._FdfFile\r
522 \r
523     ## Return the build output directory platform specifies\r
524     def _GetOutputDir(self):\r
525         return self.Platform.OutputDirectory\r
526 \r
527     ## Return the directory to store all intermediate and final files built\r
528     def _GetBuildDir(self):\r
529         if self._BuildDir == None:\r
530             if os.path.isabs(self.OutputDir):\r
531                 self._BuildDir = path.join(\r
532                                             path.abspath(self.OutputDir),\r
533                                             self.BuildTarget + "_" + self.ToolChain,\r
534                                             )\r
535             else:\r
536                 self._BuildDir = path.join(\r
537                                             self.WorkspaceDir,\r
538                                             self.OutputDir,\r
539                                             self.BuildTarget + "_" + self.ToolChain,\r
540                                             )\r
541         return self._BuildDir\r
542 \r
543     ## Return directory of platform makefile\r
544     #\r
545     #   @retval     string  Makefile directory\r
546     #\r
547     def _GetMakeFileDir(self):\r
548         if self._MakeFileDir == None:\r
549             self._MakeFileDir = path.join(self.BuildDir, self.Arch)\r
550         return self._MakeFileDir\r
551 \r
552     ## Return build command string\r
553     #\r
554     #   @retval     string  Build command string\r
555     #\r
556     def _GetBuildCommand(self):\r
557         if self._BuildCommand == None:\r
558             self._BuildCommand = []\r
559             if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:\r
560                 self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])\r
561                 if "FLAGS" in self.ToolDefinition["MAKE"]:\r
562                     NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()\r
563                     if NewOption != '':\r
564                       self._BuildCommand += SplitOption(NewOption)\r
565         return self._BuildCommand\r
566 \r
567     ## Get tool chain definition\r
568     #\r
569     #  Get each tool defition for given tool chain from tools_def.txt and platform\r
570     #\r
571     def _GetToolDefinition(self):\r
572         if self._ToolDefinitions == None:\r
573             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary\r
574             if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:\r
575                 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",\r
576                                 ExtraData="[%s]" % self.MetaFile)\r
577             self._ToolDefinitions = {}\r
578             DllPathList = set()\r
579             for Def in ToolDefinition:\r
580                 Target, Tag, Arch, Tool, Attr = Def.split("_")\r
581                 if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:\r
582                     continue\r
583 \r
584                 Value = ToolDefinition[Def]\r
585                 # don't record the DLL\r
586                 if Attr == "DLL":\r
587                     DllPathList.add(Value)\r
588                     continue\r
589 \r
590                 if Tool not in self._ToolDefinitions:\r
591                     self._ToolDefinitions[Tool] = {}\r
592                 self._ToolDefinitions[Tool][Attr] = Value\r
593 \r
594             ToolsDef = ''\r
595             MakePath = ''\r
596             if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:\r
597                 if "FLAGS" not in self._ToolDefinitions["MAKE"]:\r
598                     self._ToolDefinitions["MAKE"]["FLAGS"] = ""\r
599                 self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"\r
600             MakeFlags = ''\r
601             for Tool in self._ToolDefinitions:\r
602                 for Attr in self._ToolDefinitions[Tool]:\r
603                     Value = self._ToolDefinitions[Tool][Attr]\r
604                     if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:\r
605                         # check if override is indicated\r
606                         if self.BuildOption[Tool][Attr].startswith('='):\r
607                             Value = self.BuildOption[Tool][Attr][1:]\r
608                         else:\r
609                             Value += " " + self.BuildOption[Tool][Attr]\r
610 \r
611                     if Attr == "PATH":\r
612                         # Don't put MAKE definition in the file\r
613                         if Tool == "MAKE":\r
614                             MakePath = Value\r
615                         else:\r
616                             ToolsDef += "%s = %s\n" % (Tool, Value)\r
617                     elif Attr != "DLL":\r
618                         # Don't put MAKE definition in the file\r
619                         if Tool == "MAKE":\r
620                             if Attr == "FLAGS":\r
621                                 MakeFlags = Value\r
622                         else:\r
623                             ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)\r
624                 ToolsDef += "\n"\r
625 \r
626             SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)\r
627             for DllPath in DllPathList:\r
628                 os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]\r
629             os.environ["MAKE_FLAGS"] = MakeFlags\r
630 \r
631         return self._ToolDefinitions\r
632 \r
633     ## Return the paths of tools\r
634     def _GetToolDefFile(self):\r
635         if self._ToolDefFile == None:\r
636             self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)\r
637         return self._ToolDefFile\r
638 \r
639     ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.\r
640     def _GetToolChainFamily(self):\r
641         if self._ToolChainFamily == None:\r
642             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
643             if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \\r
644                or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \\r
645                or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:\r
646                 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \\r
647                                    % self.ToolChain)\r
648                 self._ToolChainFamily = "MSFT"\r
649             else:\r
650                 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]\r
651         return self._ToolChainFamily\r
652 \r
653     def _GetBuildRuleFamily(self):\r
654         if self._BuildRuleFamily == None:\r
655             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase\r
656             if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \\r
657                or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \\r
658                or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:\r
659                 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \\r
660                                    % self.ToolChain)\r
661                 self._BuildRuleFamily = "MSFT"\r
662             else:\r
663                 self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]\r
664         return self._BuildRuleFamily\r
665 \r
666     ## Return the build options specific for all modules in this platform\r
667     def _GetBuildOptions(self):\r
668         if self._BuildOption == None:\r
669             self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)\r
670         return self._BuildOption\r
671 \r
672     ## Return the build options specific for EDK modules in this platform\r
673     def _GetEdkBuildOptions(self):\r
674         if self._EdkBuildOption == None:\r
675             self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME)\r
676         return self._EdkBuildOption\r
677 \r
678     ## Return the build options specific for EDKII modules in this platform\r
679     def _GetEdkIIBuildOptions(self):\r
680         if self._EdkIIBuildOption == None:\r
681             self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)\r
682         return self._EdkIIBuildOption\r
683 \r
684     ## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt\r
685     #\r
686     #   @retval     BuildRule object\r
687     #\r
688     def _GetBuildRule(self):\r
689         if self._BuildRule == None:\r
690             BuildRuleFile = None\r
691             if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:\r
692                 BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]\r
693             if BuildRuleFile in [None, '']:\r
694                 BuildRuleFile = gBuildRuleFile\r
695             self._BuildRule = BuildRule(BuildRuleFile)\r
696         return self._BuildRule\r
697 \r
698     ## Summarize the packages used by modules in this platform\r
699     def _GetPackageList(self):\r
700         if self._PackageList == None:\r
701             self._PackageList = set()\r
702             for La in self.LibraryAutoGenList:\r
703                 self._PackageList.update(La.DependentPackageList)\r
704             for Ma in self.ModuleAutoGenList:\r
705                 self._PackageList.update(Ma.DependentPackageList)\r
706             self._PackageList = list(self._PackageList)\r
707         return self._PackageList\r
708 \r
709     ## Get list of non-dynamic PCDs\r
710     def _GetNonDynamicPcdList(self):\r
711         return self._NonDynamicPcdList\r
712 \r
713     ## Get list of dynamic PCDs\r
714     def _GetDynamicPcdList(self):\r
715         return self._DynamicPcdList\r
716 \r
717     ## Generate Token Number for all PCD\r
718     def _GetPcdTokenNumbers(self):\r
719         if self._PcdTokenNumber == None:\r
720             self._PcdTokenNumber = sdict()\r
721             TokenNumber = 1\r
722             for Pcd in self.DynamicPcdList:\r
723                 if Pcd.Phase == "PEI":\r
724                     EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
725                     self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
726                     TokenNumber += 1\r
727 \r
728             for Pcd in self.DynamicPcdList:\r
729                 if Pcd.Phase == "DXE":\r
730                     EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))\r
731                     self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
732                     TokenNumber += 1\r
733 \r
734             for Pcd in self.NonDynamicPcdList:\r
735                 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
736                 TokenNumber += 1\r
737         return self._PcdTokenNumber\r
738 \r
739     ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform\r
740     def _GetAutoGenObjectList(self):\r
741         self._ModuleAutoGenList = []\r
742         self._LibraryAutoGenList = []\r
743         for ModuleFile in self.Platform.Modules:\r
744             Ma = ModuleAutoGen(\r
745                     self.Workspace,\r
746                     ModuleFile,\r
747                     self.BuildTarget,\r
748                     self.ToolChain,\r
749                     self.Arch,\r
750                     self.MetaFile\r
751                     )\r
752             if Ma not in self._ModuleAutoGenList:\r
753                 self._ModuleAutoGenList.append(Ma)\r
754             for La in Ma.LibraryAutoGenList:\r
755                 if La not in self._LibraryAutoGenList:\r
756                     self._LibraryAutoGenList.append(La)\r
757 \r
758     ## Summarize ModuleAutoGen objects of all modules to be built for this platform\r
759     def _GetModuleAutoGenList(self):\r
760         if self._ModuleAutoGenList == None:\r
761             self._GetAutoGenObjectList()\r
762         return self._ModuleAutoGenList\r
763 \r
764     ## Summarize ModuleAutoGen objects of all libraries to be built for this platform\r
765     def _GetLibraryAutoGenList(self):\r
766         if self._LibraryAutoGenList == None:\r
767             self._GetAutoGenObjectList()\r
768         return self._LibraryAutoGenList\r
769 \r
770     ## Test if a module is supported by the platform\r
771     #\r
772     #  An error will be raised directly if the module or its arch is not supported\r
773     #  by the platform or current configuration\r
774     #\r
775     def ValidModule(self, Module):\r
776         return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances\r
777 \r
778     ## Resolve the library classes in a module to library instances\r
779     #\r
780     # This method will not only resolve library classes but also sort the library\r
781     # instances according to the dependency-ship.\r
782     #\r
783     #   @param  Module      The module from which the library classes will be resolved\r
784     #\r
785     #   @retval library_list    List of library instances sorted\r
786     #\r
787     def ApplyLibraryInstance(self, Module):\r
788         ModuleType = Module.ModuleType\r
789 \r
790         # for overridding library instances with module specific setting\r
791         PlatformModule = self.Platform.Modules[str(Module)]\r
792 \r
793         # add forced library instances (specified under LibraryClasses sections)\r
794         for LibraryClass in self.Platform.LibraryClasses.GetKeys():\r
795             if LibraryClass.startswith("NULL"):\r
796                 Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass]\r
797 \r
798         # add forced library instances (specified in module overrides)\r
799         for LibraryClass in PlatformModule.LibraryClasses:\r
800             if LibraryClass.startswith("NULL"):\r
801                 Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]\r
802 \r
803         # R9 module\r
804         LibraryConsumerList = [Module]\r
805         Constructor         = []\r
806         ConsumedByList      = sdict()\r
807         LibraryInstance     = sdict()\r
808 \r
809         EdkLogger.verbose("")\r
810         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
811         while len(LibraryConsumerList) > 0:\r
812             M = LibraryConsumerList.pop()\r
813             for LibraryClassName in M.LibraryClasses:\r
814                 if LibraryClassName not in LibraryInstance:\r
815                     # override library instance for this module\r
816                     if LibraryClassName in PlatformModule.LibraryClasses:\r
817                         LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]\r
818                     else:\r
819                         LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]\r
820                     if LibraryPath == None or LibraryPath == "":\r
821                         LibraryPath = M.LibraryClasses[LibraryClassName]\r
822                         if LibraryPath == None or LibraryPath == "":\r
823                             EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,\r
824                                             "Instance of library class [%s] is not found" % LibraryClassName,\r
825                                             File=self.MetaFile,\r
826                                             ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))\r
827 \r
828                     LibraryModule = self.BuildDatabase[LibraryPath, self.Arch]\r
829                     # for those forced library instance (NULL library), add a fake library class\r
830                     if LibraryClassName.startswith("NULL"):\r
831                         LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))\r
832                     elif LibraryModule.LibraryClass == None \\r
833                          or len(LibraryModule.LibraryClass) == 0 \\r
834                          or (ModuleType != 'USER_DEFINED'\r
835                              and ModuleType not in LibraryModule.LibraryClass[0].SupModList):\r
836                         # only USER_DEFINED can link against any library instance despite of its SupModList\r
837                         EdkLogger.error("build", OPTION_MISSING,\r
838                                         "Module type [%s] is not supported by library instance [%s]" \\r
839                                         % (ModuleType, LibraryPath), File=self.MetaFile,\r
840                                         ExtraData="consumed by [%s]" % str(Module))\r
841 \r
842                     LibraryInstance[LibraryClassName] = LibraryModule\r
843                     LibraryConsumerList.append(LibraryModule)\r
844                     EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))\r
845                 else:\r
846                     LibraryModule = LibraryInstance[LibraryClassName]\r
847 \r
848                 if LibraryModule == None:\r
849                     continue\r
850 \r
851                 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:\r
852                     Constructor.append(LibraryModule)\r
853 \r
854                 if LibraryModule not in ConsumedByList:\r
855                     ConsumedByList[LibraryModule] = []\r
856                 # don't add current module itself to consumer list\r
857                 if M != Module:\r
858                     if M in ConsumedByList[LibraryModule]:\r
859                         continue\r
860                     ConsumedByList[LibraryModule].append(M)\r
861         #\r
862         # Initialize the sorted output list to the empty set\r
863         #\r
864         SortedLibraryList = []\r
865         #\r
866         # Q <- Set of all nodes with no incoming edges\r
867         #\r
868         LibraryList = [] #LibraryInstance.values()\r
869         Q = []\r
870         for LibraryClassName in LibraryInstance:\r
871             M = LibraryInstance[LibraryClassName]\r
872             LibraryList.append(M)\r
873             if ConsumedByList[M] == []:\r
874                 Q.append(M)\r
875 \r
876         #\r
877         # start the  DAG algorithm\r
878         #\r
879         while True:\r
880             EdgeRemoved = True\r
881             while Q == [] and EdgeRemoved:\r
882                 EdgeRemoved = False\r
883                 # for each node Item with a Constructor\r
884                 for Item in LibraryList:\r
885                     if Item not in Constructor:\r
886                         continue\r
887                     # for each Node without a constructor with an edge e from Item to Node\r
888                     for Node in ConsumedByList[Item]:\r
889                         if Node in Constructor:\r
890                             continue\r
891                         # remove edge e from the graph if Node has no constructor\r
892                         ConsumedByList[Item].remove(Node)\r
893                         EdgeRemoved = True\r
894                         if ConsumedByList[Item] == []:\r
895                             # insert Item into Q\r
896                             Q.insert(0, Item)\r
897                             break\r
898                     if Q != []:\r
899                         break\r
900             # DAG is done if there's no more incoming edge for all nodes\r
901             if Q == []:\r
902                 break\r
903 \r
904             # remove node from Q\r
905             Node = Q.pop()\r
906             # output Node\r
907             SortedLibraryList.append(Node)\r
908 \r
909             # for each node Item with an edge e from Node to Item do\r
910             for Item in LibraryList:\r
911                 if Node not in ConsumedByList[Item]:\r
912                     continue\r
913                 # remove edge e from the graph\r
914                 ConsumedByList[Item].remove(Node)\r
915 \r
916                 if ConsumedByList[Item] != []:\r
917                     continue\r
918                 # insert Item into Q, if Item has no other incoming edges\r
919                 Q.insert(0, Item)\r
920 \r
921         #\r
922         # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle\r
923         #\r
924         for Item in LibraryList:\r
925             if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:\r
926                 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])\r
927                 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),\r
928                                 ExtraData=ErrorMessage, File=self.MetaFile)\r
929             if Item not in SortedLibraryList:\r
930                 SortedLibraryList.append(Item)\r
931 \r
932         #\r
933         # Build the list of constructor and destructir names\r
934         # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order\r
935         #\r
936         SortedLibraryList.reverse()\r
937         return SortedLibraryList\r
938 \r
939 \r
940     ## Override PCD setting (type, value, ...)\r
941     #\r
942     #   @param  ToPcd       The PCD to be overrided\r
943     #   @param  FromPcd     The PCD overrideing from\r
944     #\r
945     def _OverridePcd(self, ToPcd, FromPcd, Module=""):\r
946         #\r
947         # in case there's PCDs coming from FDF file, which have no type given.\r
948         # at this point, ToPcd.Type has the type found from dependent\r
949         # package\r
950         #\r
951         if FromPcd != None:\r
952             if ToPcd.Pending and FromPcd.Type not in [None, '']:\r
953                 ToPcd.Type = FromPcd.Type\r
954             elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \\r
955                 and ToPcd.Type != FromPcd.Type:\r
956                 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",\r
957                                 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\\r
958                                           % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName,\r
959                                              ToPcd.Type, Module, FromPcd.Type),\r
960                                           File=self.MetaFile)\r
961 \r
962             if FromPcd.MaxDatumSize not in [None, '']:\r
963                 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
964             if FromPcd.DefaultValue not in [None, '']:\r
965                 ToPcd.DefaultValue = FromPcd.DefaultValue\r
966             if FromPcd.TokenValue not in [None, '']:\r
967                 ToPcd.TokenValue = FromPcd.TokenValue\r
968             if FromPcd.MaxDatumSize not in [None, '']:\r
969                 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize\r
970             if FromPcd.DatumType not in [None, '']:\r
971                 ToPcd.DatumType = FromPcd.DatumType\r
972             if FromPcd.SkuInfoList not in [None, '', []]:\r
973                 ToPcd.SkuInfoList = FromPcd.SkuInfoList\r
974 \r
975             # check the validation of datum\r
976             IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)\r
977             if not IsValid:\r
978                 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,\r
979                                 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))\r
980 \r
981         if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:\r
982             EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \\r
983                             % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))\r
984             Value = ToPcd.DefaultValue\r
985             if Value in [None, '']:\r
986                 ToPcd.MaxDatumSize = 1\r
987             elif Value[0] == 'L':\r
988                 ToPcd.MaxDatumSize = str(len(Value) * 2)\r
989             elif Value[0] == '{':\r
990                 ToPcd.MaxDatumSize = str(len(Value.split(',')))\r
991             else:\r
992                 ToPcd.MaxDatumSize = str(len(Value))\r
993 \r
994         # apply default SKU for dynamic PCDS if specified one is not available\r
995         if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \\r
996             and ToPcd.SkuInfoList in [None, {}, '']:\r
997             if self.Platform.SkuName in self.Platform.SkuIds:\r
998                 SkuName = self.Platform.SkuName\r
999             else:\r
1000                 SkuName = 'DEFAULT'\r
1001             ToPcd.SkuInfoList = {\r
1002                 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)\r
1003             }\r
1004 \r
1005     ## Apply PCD setting defined platform to a module\r
1006     #\r
1007     #   @param  Module  The module from which the PCD setting will be overrided\r
1008     #\r
1009     #   @retval PCD_list    The list PCDs with settings from platform\r
1010     #\r
1011     def ApplyPcdSetting(self, Module, Pcds):\r
1012         # for each PCD in module\r
1013         for Name,Guid in Pcds:\r
1014             PcdInModule = Pcds[Name,Guid]\r
1015             # find out the PCD setting in platform\r
1016             if (Name,Guid) in self.Platform.Pcds:\r
1017                 PcdInPlatform = self.Platform.Pcds[Name,Guid]\r
1018             else:\r
1019                 PcdInPlatform = None\r
1020             # then override the settings if any\r
1021             self._OverridePcd(PcdInModule, PcdInPlatform, Module)\r
1022             # resolve the VariableGuid value\r
1023             for SkuId in PcdInModule.SkuInfoList:\r
1024                 Sku = PcdInModule.SkuInfoList[SkuId]\r
1025                 if Sku.VariableGuid == '': continue\r
1026                 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)\r
1027                 if Sku.VariableGuidValue == None:\r
1028                     PackageList = "\n\t".join([str(P) for P in self.PackageList])\r
1029                     EdkLogger.error(\r
1030                                 'build',\r
1031                                 RESOURCE_NOT_AVAILABLE,\r
1032                                 "Value of GUID [%s] is not found in" % Sku.VariableGuid,\r
1033                                 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \\r
1034                                                         % (Guid, Name, str(Module)),\r
1035                                 File=self.MetaFile\r
1036                                 )\r
1037 \r
1038         # override PCD settings with module specific setting\r
1039         if Module in self.Platform.Modules:\r
1040             PlatformModule = self.Platform.Modules[str(Module)]\r
1041             for Key  in PlatformModule.Pcds:\r
1042                 if Key in Pcds:\r
1043                     self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)\r
1044         return Pcds.values()\r
1045 \r
1046     ## Resolve library names to library modules\r
1047     #\r
1048     # (for R8.x modules)\r
1049     #\r
1050     #   @param  Module  The module from which the library names will be resolved\r
1051     #\r
1052     #   @retval library_list    The list of library modules\r
1053     #\r
1054     def ResolveLibraryReference(self, Module):\r
1055         EdkLogger.verbose("")\r
1056         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))\r
1057         LibraryConsumerList = [Module]\r
1058 \r
1059         # "CompilerStub" is a must for R8 modules\r
1060         if Module.Libraries:\r
1061             Module.Libraries.append("CompilerStub")\r
1062         LibraryList = []\r
1063         while len(LibraryConsumerList) > 0:\r
1064             M = LibraryConsumerList.pop()\r
1065             for LibraryName in M.Libraries:\r
1066                 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']\r
1067                 if Library == None:\r
1068                     for Key in self.Platform.LibraryClasses.data.keys():\r
1069                         if LibraryName.upper() == Key.upper():\r
1070                             Library = self.Platform.LibraryClasses[Key, ':dummy:']\r
1071                             break\r
1072                     if Library == None:\r
1073                         EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),\r
1074                             ExtraData="\t%s [%s]" % (str(Module), self.Arch))\r
1075                         continue\r
1076 \r
1077                 if Library not in LibraryList:\r
1078                     LibraryList.append(Library)\r
1079                     LibraryConsumerList.append(Library)\r
1080                     EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))\r
1081         return LibraryList\r
1082 \r
1083     ## Expand * in build option key\r
1084     #\r
1085     #   @param  Options     Options to be expanded\r
1086     #\r
1087     #   @retval options     Options expanded\r
1088     #\r
1089     def _ExpandBuildOption(self, Options, ModuleStyle=None):\r
1090         BuildOptions = {}\r
1091         FamilyMatch  = False\r
1092         FamilyIsNull = True\r
1093         for Key in Options:\r
1094             if ModuleStyle != None and len (Key) > 2:\r
1095                 # Check Module style is EDK or EDKII.\r
1096                 # Only append build option for the matched style module.\r
1097                 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:\r
1098                     continue\r
1099                 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:\r
1100                     continue\r
1101             Family = Key[0]\r
1102             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
1103             # if tool chain family doesn't match, skip it\r
1104             if Tool in self.ToolDefinition and Family != "":\r
1105                 FamilyIsNull = False\r
1106                 if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":\r
1107                     if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
1108                         continue\r
1109                 elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:\r
1110                     continue\r
1111                 FamilyMatch = True\r
1112             # expand any wildcard\r
1113             if Target == "*" or Target == self.BuildTarget:\r
1114                 if Tag == "*" or Tag == self.ToolChain:\r
1115                     if Arch == "*" or Arch == self.Arch:\r
1116                         if Tool not in BuildOptions:\r
1117                             BuildOptions[Tool] = {}\r
1118                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:\r
1119                             BuildOptions[Tool][Attr] = Options[Key]\r
1120                         else:\r
1121                             # append options for the same tool\r
1122                             BuildOptions[Tool][Attr] += " " + Options[Key]\r
1123         # Build Option Family has been checked, which need't to be checked again for family.\r
1124         if FamilyMatch or FamilyIsNull:\r
1125             return BuildOptions\r
1126         \r
1127         for Key in Options:\r
1128             if ModuleStyle != None and len (Key) > 2:\r
1129                 # Check Module style is EDK or EDKII.\r
1130                 # Only append build option for the matched style module.\r
1131                 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:\r
1132                     continue\r
1133                 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:\r
1134                     continue\r
1135             Family = Key[0]\r
1136             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
1137             # if tool chain family doesn't match, skip it\r
1138             if Tool not in self.ToolDefinition or Family =="":\r
1139                 continue\r
1140             # option has been added before\r
1141             if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:\r
1142                 continue\r
1143 \r
1144             # expand any wildcard\r
1145             if Target == "*" or Target == self.BuildTarget:\r
1146                 if Tag == "*" or Tag == self.ToolChain:\r
1147                     if Arch == "*" or Arch == self.Arch:\r
1148                         if Tool not in BuildOptions:\r
1149                             BuildOptions[Tool] = {}\r
1150                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool]:\r
1151                             BuildOptions[Tool][Attr] = Options[Key]\r
1152                         else:\r
1153                             # append options for the same tool\r
1154                             BuildOptions[Tool][Attr] += " " + Options[Key]\r
1155         return BuildOptions\r
1156 \r
1157     ## Append build options in platform to a module\r
1158     #\r
1159     #   @param  Module  The module to which the build options will be appened\r
1160     #\r
1161     #   @retval options     The options appended with build options in platform\r
1162     #\r
1163     def ApplyBuildOption(self, Module):\r
1164         # Get the different options for the different style module\r
1165         if Module.AutoGenVersion < 0x00010005:\r
1166             PlatformOptions = self.EdkBuildOption\r
1167         else:\r
1168             PlatformOptions = self.EdkIIBuildOption\r
1169         ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)\r
1170         if Module in self.Platform.Modules:\r
1171             PlatformModule = self.Platform.Modules[str(Module)]\r
1172             PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)\r
1173         else:\r
1174             PlatformModuleOptions = {}\r
1175 \r
1176         AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() + PlatformModuleOptions.keys() + self.ToolDefinition.keys())\r
1177         BuildOptions = {}\r
1178         for Tool in AllTools:\r
1179             if Tool not in BuildOptions:\r
1180                 BuildOptions[Tool] = {}\r
1181 \r
1182             for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, PlatformModuleOptions]:\r
1183                 if Tool not in Options:\r
1184                     continue\r
1185                 for Attr in Options[Tool]:\r
1186                     Value = Options[Tool][Attr]\r
1187                     if Attr not in BuildOptions[Tool]:\r
1188                         BuildOptions[Tool][Attr] = ""\r
1189                     # check if override is indicated\r
1190                     if Value.startswith('='):\r
1191                         BuildOptions[Tool][Attr] = Value[1:]\r
1192                     else:\r
1193                         BuildOptions[Tool][Attr] += " " + Value\r
1194         return BuildOptions\r
1195 \r
1196     Platform            = property(_GetPlatform)\r
1197     Name                = property(_GetName)\r
1198     Guid                = property(_GetGuid)\r
1199     Version             = property(_GetVersion)\r
1200 \r
1201     OutputDir           = property(_GetOutputDir)\r
1202     BuildDir            = property(_GetBuildDir)\r
1203     MakeFileDir         = property(_GetMakeFileDir)\r
1204     FdfFile             = property(_GetFdfFile)\r
1205 \r
1206     PcdTokenNumber      = property(_GetPcdTokenNumbers)    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber\r
1207     DynamicPcdList      = property(_GetDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
1208     NonDynamicPcdList   = property(_GetNonDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
1209     PackageList         = property(_GetPackageList)\r
1210 \r
1211     ToolDefinition      = property(_GetToolDefinition)    # toolcode : tool path\r
1212     ToolDefinitionFile  = property(_GetToolDefFile)    # toolcode : lib path\r
1213     ToolChainFamily     = property(_GetToolChainFamily)\r
1214     BuildRuleFamily     = property(_GetBuildRuleFamily)\r
1215     BuildOption         = property(_GetBuildOptions)    # toolcode : option\r
1216     EdkBuildOption      = property(_GetEdkBuildOptions)   # edktoolcode : option\r
1217     EdkIIBuildOption    = property(_GetEdkIIBuildOptions) # edkiitoolcode : option\r
1218 \r
1219     BuildCommand        = property(_GetBuildCommand)\r
1220     BuildRule           = property(_GetBuildRule)\r
1221     ModuleAutoGenList   = property(_GetModuleAutoGenList)\r
1222     LibraryAutoGenList  = property(_GetLibraryAutoGenList)\r
1223 \r
1224 ## ModuleAutoGen class\r
1225 #\r
1226 # This class encapsules the AutoGen behaviors for the build tools. In addition to\r
1227 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according\r
1228 # to the [depex] section in module's inf file.\r
1229 #\r
1230 class ModuleAutoGen(AutoGen):\r
1231     ## The real constructor of ModuleAutoGen\r
1232     #\r
1233     #  This method is not supposed to be called by users of ModuleAutoGen. It's\r
1234     #  only used by factory method __new__() to do real initialization work for an\r
1235     #  object of ModuleAutoGen\r
1236     #\r
1237     #   @param      Workspace           EdkIIWorkspaceBuild object\r
1238     #   @param      ModuleFile          The path of module file\r
1239     #   @param      Target              Build target (DEBUG, RELEASE)\r
1240     #   @param      Toolchain           Name of tool chain\r
1241     #   @param      Arch                The arch the module supports\r
1242     #   @param      PlatformFile        Platform meta-file\r
1243     #\r
1244     def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):\r
1245         EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))\r
1246         GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)\r
1247 \r
1248         self.Workspace = Workspace\r
1249         self.WorkspaceDir = Workspace.WorkspaceDir\r
1250 \r
1251         self.MetaFile = ModuleFile\r
1252         self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)\r
1253         # check if this module is employed by active platform\r
1254         if not self.PlatformInfo.ValidModule(self.MetaFile):\r
1255             EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \\r
1256                               % (self.MetaFile, Arch))\r
1257             return False\r
1258 \r
1259         self.SourceDir = self.MetaFile.SubDir\r
1260         self.SourceOverrideDir = None\r
1261         # use overrided path defined in DSC file\r
1262         if self.MetaFile.Key in GlobalData.gOverrideDir:\r
1263             self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]\r
1264 \r
1265         self.ToolChain = Toolchain\r
1266         self.BuildTarget = Target\r
1267         self.Arch = Arch\r
1268         self.ToolChainFamily = self.PlatformInfo.ToolChainFamily\r
1269         self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily\r
1270 \r
1271         self.IsMakeFileCreated = False\r
1272         self.IsCodeFileCreated = False\r
1273 \r
1274         self.BuildDatabase = self.Workspace.BuildDatabase\r
1275 \r
1276         self._Module          = None\r
1277         self._Name            = None\r
1278         self._Guid            = None\r
1279         self._Version         = None\r
1280         self._ModuleType      = None\r
1281         self._ComponentType   = None\r
1282         self._PcdIsDriver     = None\r
1283         self._AutoGenVersion  = None\r
1284         self._LibraryFlag     = None\r
1285         self._CustomMakefile  = None\r
1286         self._Macro           = None\r
1287 \r
1288         self._BuildDir        = None\r
1289         self._OutputDir       = None\r
1290         self._DebugDir        = None\r
1291         self._MakeFileDir     = None\r
1292 \r
1293         self._IncludePathList = None\r
1294         self._AutoGenFileList = None\r
1295         self._UnicodeFileList = None\r
1296         self._SourceFileList  = None\r
1297         self._ObjectFileList  = None\r
1298         self._BinaryFileList  = None\r
1299 \r
1300         self._DependentPackageList    = None\r
1301         self._DependentLibraryList    = None\r
1302         self._LibraryAutoGenList      = None\r
1303         self._DerivedPackageList      = None\r
1304         self._ModulePcdList           = None\r
1305         self._LibraryPcdList          = None\r
1306         self._GuidList                = None\r
1307         self._ProtocolList            = None\r
1308         self._PpiList                 = None\r
1309         self._DepexList               = None\r
1310         self._DepexExpressionList     = None\r
1311         self._BuildOption             = None\r
1312         self._BuildTargets            = None\r
1313         self._IntroBuildTargetList    = None\r
1314         self._FinalBuildTargetList    = None\r
1315         self._FileTypes               = None\r
1316         self._BuildRules              = None\r
1317 \r
1318         return True\r
1319 \r
1320     def __repr__(self):\r
1321         return "%s [%s]" % (self.MetaFile, self.Arch)\r
1322 \r
1323     # Macros could be used in build_rule.txt (also Makefile)\r
1324     def _GetMacros(self):\r
1325         if self._Macro == None:\r
1326             self._Macro = sdict()\r
1327             self._Macro["WORKSPACE"             ] = self.WorkspaceDir\r
1328             self._Macro["MODULE_NAME"           ] = self.Name\r
1329             self._Macro["MODULE_GUID"           ] = self.Guid\r
1330             self._Macro["MODULE_VERSION"        ] = self.Version\r
1331             self._Macro["MODULE_TYPE"           ] = self.ModuleType\r
1332             self._Macro["MODULE_FILE"           ] = str(self.MetaFile)\r
1333             self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName\r
1334             self._Macro["MODULE_RELATIVE_DIR"   ] = self.SourceDir\r
1335             self._Macro["MODULE_DIR"            ] = self.SourceDir\r
1336 \r
1337             self._Macro["BASE_NAME"             ] = self.Name\r
1338 \r
1339             self._Macro["ARCH"                  ] = self.Arch\r
1340             self._Macro["TOOLCHAIN"             ] = self.ToolChain\r
1341             self._Macro["TOOLCHAIN_TAG"         ] = self.ToolChain\r
1342             self._Macro["TARGET"                ] = self.BuildTarget\r
1343 \r
1344             self._Macro["BUILD_DIR"             ] = self.PlatformInfo.BuildDir\r
1345             self._Macro["BIN_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
1346             self._Macro["LIB_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)\r
1347             self._Macro["MODULE_BUILD_DIR"      ] = self.BuildDir\r
1348             self._Macro["OUTPUT_DIR"            ] = self.OutputDir\r
1349             self._Macro["DEBUG_DIR"             ] = self.DebugDir\r
1350         return self._Macro\r
1351 \r
1352     ## Return the module build data object\r
1353     def _GetModule(self):\r
1354         if self._Module == None:\r
1355             self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch]\r
1356         return self._Module\r
1357 \r
1358     ## Return the module name\r
1359     def _GetBaseName(self):\r
1360         return self.Module.BaseName\r
1361 \r
1362     ## Return the module SourceOverridePath\r
1363     def _GetSourceOverridePath(self):\r
1364         return self.Module.SourceOverridePath\r
1365 \r
1366     ## Return the module meta-file GUID\r
1367     def _GetGuid(self):\r
1368         return self.Module.Guid\r
1369 \r
1370     ## Return the module version\r
1371     def _GetVersion(self):\r
1372         return self.Module.Version\r
1373 \r
1374     ## Return the module type\r
1375     def _GetModuleType(self):\r
1376         return self.Module.ModuleType\r
1377 \r
1378     ## Return the component type (for R8.x style of module)\r
1379     def _GetComponentType(self):\r
1380         return self.Module.ComponentType\r
1381 \r
1382     ## Return the build type\r
1383     def _GetBuildType(self):\r
1384         return self.Module.BuildType\r
1385 \r
1386     ## Return the PCD_IS_DRIVER setting\r
1387     def _GetPcdIsDriver(self):\r
1388         return self.Module.PcdIsDriver\r
1389 \r
1390     ## Return the autogen version, i.e. module meta-file version\r
1391     def _GetAutoGenVersion(self):\r
1392         return self.Module.AutoGenVersion\r
1393 \r
1394     ## Check if the module is library or not\r
1395     def _IsLibrary(self):\r
1396         if self._LibraryFlag == None:\r
1397             if self.Module.LibraryClass != None and self.Module.LibraryClass != []:\r
1398                 self._LibraryFlag = True\r
1399             else:\r
1400                 self._LibraryFlag = False\r
1401         return self._LibraryFlag\r
1402 \r
1403     ## Return the directory to store intermediate files of the module\r
1404     def _GetBuildDir(self):\r
1405         if self._BuildDir == None:\r
1406             self._BuildDir = path.join(\r
1407                                     self.PlatformInfo.BuildDir,\r
1408                                     self.Arch,\r
1409                                     self.SourceDir,\r
1410                                     self.MetaFile.BaseName\r
1411                                     )\r
1412             CreateDirectory(self._BuildDir)\r
1413         return self._BuildDir\r
1414 \r
1415     ## Return the directory to store the intermediate object files of the mdoule\r
1416     def _GetOutputDir(self):\r
1417         if self._OutputDir == None:\r
1418             self._OutputDir = path.join(self.BuildDir, "OUTPUT")\r
1419             CreateDirectory(self._OutputDir)\r
1420         return self._OutputDir\r
1421 \r
1422     ## Return the directory to store auto-gened source files of the mdoule\r
1423     def _GetDebugDir(self):\r
1424         if self._DebugDir == None:\r
1425             self._DebugDir = path.join(self.BuildDir, "DEBUG")\r
1426             CreateDirectory(self._DebugDir)\r
1427         return self._DebugDir\r
1428 \r
1429     ## Return the path of custom file\r
1430     def _GetCustomMakefile(self):\r
1431         if self._CustomMakefile == None:\r
1432             self._CustomMakefile = {}\r
1433             for Type in self.Module.CustomMakefile:\r
1434                 if Type in gMakeTypeMap:\r
1435                     MakeType = gMakeTypeMap[Type]\r
1436                 else:\r
1437                     MakeType = 'nmake'\r
1438                 if self.SourceOverrideDir != None:\r
1439                     File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])\r
1440                     if not os.path.exists(File):\r
1441                         File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
1442                 else:\r
1443                     File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])\r
1444                 self._CustomMakefile[MakeType] = File\r
1445         return self._CustomMakefile\r
1446 \r
1447     ## Return the directory of the makefile\r
1448     #\r
1449     #   @retval     string  The directory string of module's makefile\r
1450     #\r
1451     def _GetMakeFileDir(self):\r
1452         return self.BuildDir\r
1453 \r
1454     ## Return build command string\r
1455     #\r
1456     #   @retval     string  Build command string\r
1457     #\r
1458     def _GetBuildCommand(self):\r
1459         return self.PlatformInfo.BuildCommand\r
1460 \r
1461     ## Get object list of all packages the module and its dependent libraries belong to\r
1462     #\r
1463     #   @retval     list    The list of package object\r
1464     #\r
1465     def _GetDerivedPackageList(self):\r
1466         PackageList = []\r
1467         for M in [self.Module] + self.DependentLibraryList:\r
1468             for Package in M.Packages:\r
1469                 if Package in PackageList:\r
1470                     continue\r
1471                 PackageList.append(Package)\r
1472         return PackageList\r
1473 \r
1474     ## Merge dependency expression\r
1475     #\r
1476     #   @retval     list    The token list of the dependency expression after parsed\r
1477     #\r
1478     def _GetDepexTokenList(self):\r
1479         if self._DepexList == None:\r
1480             self._DepexList = {}\r
1481             if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
1482                 return self._DepexList\r
1483 \r
1484             self._DepexList[self.ModuleType] = []\r
1485 \r
1486             for ModuleType in self._DepexList:\r
1487                 DepexList = self._DepexList[ModuleType]\r
1488                 #\r
1489                 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion\r
1490                 #\r
1491                 for M in [self.Module] + self.DependentLibraryList:\r
1492                     Inherited = False\r
1493                     for D in M.Depex[self.Arch, ModuleType]:\r
1494                         if DepexList != []:\r
1495                             DepexList.append('AND')\r
1496                         DepexList.append('(')\r
1497                         DepexList.extend(D)\r
1498                         if DepexList[-1] == 'END':  # no need of a END at this time\r
1499                             DepexList.pop()\r
1500                         DepexList.append(')')\r
1501                         Inherited = True\r
1502                     if Inherited:\r
1503                         EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))\r
1504                     if 'BEFORE' in DepexList or 'AFTER' in DepexList:\r
1505                         break\r
1506                 if len(DepexList) > 0:\r
1507                     EdkLogger.verbose('')\r
1508         return self._DepexList\r
1509 \r
1510     ## Merge dependency expression\r
1511     #\r
1512     #   @retval     list    The token list of the dependency expression after parsed\r
1513     #\r
1514     def _GetDepexExpressionTokenList(self):\r
1515         if self._DepexExpressionList == None:\r
1516             self._DepexExpressionList = {}\r
1517             if self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:\r
1518                 return self._DepexExpressionList\r
1519 \r
1520             self._DepexExpressionList[self.ModuleType] = ''\r
1521 \r
1522             for ModuleType in self._DepexExpressionList:\r
1523                 DepexExpressionList = self._DepexExpressionList[ModuleType]\r
1524                 #\r
1525                 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion\r
1526                 #\r
1527                 for M in [self.Module] + self.DependentLibraryList:\r
1528                     Inherited = False\r
1529                     for D in M.DepexExpression[self.Arch, ModuleType]:\r
1530                         if DepexExpressionList != '':\r
1531                             DepexExpressionList += ' AND '\r
1532                         DepexExpressionList += '('\r
1533                         DepexExpressionList += D\r
1534                         DepexExpressionList = DepexExpressionList.rstrip('END').strip()\r
1535                         DepexExpressionList += ')'\r
1536                         Inherited = True\r
1537                     if Inherited:\r
1538                         EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))\r
1539                     if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:\r
1540                         break\r
1541                 if len(DepexExpressionList) > 0:\r
1542                     EdkLogger.verbose('')\r
1543                 self._DepexExpressionList[ModuleType] = DepexExpressionList\r
1544         return self._DepexExpressionList\r
1545 \r
1546     ## Return the list of specification version required for the module\r
1547     #\r
1548     #   @retval     list    The list of specification defined in module file\r
1549     #\r
1550     def _GetSpecification(self):\r
1551         return self.Module.Specification\r
1552 \r
1553     ## Tool option for the module build\r
1554     #\r
1555     #   @param      PlatformInfo    The object of PlatformBuildInfo\r
1556     #   @retval     dict            The dict containing valid options\r
1557     #\r
1558     def _GetModuleBuildOption(self):\r
1559         if self._BuildOption == None:\r
1560             self._BuildOption = self.PlatformInfo.ApplyBuildOption(self.Module)\r
1561         return self._BuildOption\r
1562 \r
1563     ## Return a list of files which can be built from source\r
1564     #\r
1565     #  What kind of files can be built is determined by build rules in\r
1566     #  $(WORKSPACE)/Conf/build_rule.txt and toolchain family.\r
1567     #\r
1568     def _GetSourceFileList(self):\r
1569         if self._SourceFileList == None:\r
1570             self._SourceFileList = []\r
1571             for F in self.Module.Sources:\r
1572                 # match tool chain\r
1573                 if F.TagName != "" and F.TagName != self.ToolChain:\r
1574                     EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "\r
1575                                     "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))\r
1576                     continue\r
1577                 # match tool chain family\r
1578                 if F.ToolChainFamily != "" and F.ToolChainFamily != self.ToolChainFamily:\r
1579                     EdkLogger.debug(\r
1580                                 EdkLogger.DEBUG_0,\r
1581                                 "The file [%s] must be built by tools of [%s], " \\r
1582                                 "but current toolchain family is [%s]" \\r
1583                                     % (str(F), F.ToolChainFamily, self.ToolChainFamily))\r
1584                     continue\r
1585 \r
1586                 # add the file path into search path list for file including\r
1587                 if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:\r
1588                     self.IncludePathList.insert(0, F.Dir)\r
1589                 self._SourceFileList.append(F)\r
1590                 self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)\r
1591         return self._SourceFileList\r
1592 \r
1593     ## Return the list of unicode files\r
1594     def _GetUnicodeFileList(self):\r
1595         if self._UnicodeFileList == None:\r
1596             if TAB_UNICODE_FILE in self.FileTypes:\r
1597                 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]\r
1598             else:\r
1599                 self._UnicodeFileList = []\r
1600         return self._UnicodeFileList\r
1601 \r
1602     ## Return a list of files which can be built from binary\r
1603     #\r
1604     #  "Build" binary files are just to copy them to build directory.\r
1605     #\r
1606     #   @retval     list            The list of files which can be built later\r
1607     #\r
1608     def _GetBinaryFiles(self):\r
1609         if self._BinaryFileList == None:\r
1610             self._BinaryFileList = []\r
1611             for F in self.Module.Binaries:\r
1612                 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:\r
1613                     continue\r
1614                 self._BinaryFileList.append(F)\r
1615                 self._ApplyBuildRule(F, F.Type)\r
1616         return self._BinaryFileList\r
1617 \r
1618     def _GetBuildRules(self):\r
1619         if self._BuildRules == None:\r
1620             BuildRules = {}\r
1621             BuildRuleDatabase = self.PlatformInfo.BuildRule\r
1622             for Type in BuildRuleDatabase.FileTypeList:\r
1623                 #first try getting build rule by BuildRuleFamily\r
1624                 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]\r
1625                 if not RuleObject:\r
1626                     # build type is always module type, but ...\r
1627                     if self.ModuleType != self.BuildType:\r
1628                         RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]\r
1629                 #second try getting build rule by ToolChainFamily\r
1630                 if not RuleObject:\r
1631                     RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]\r
1632                     if not RuleObject:\r
1633                         # build type is always module type, but ...\r
1634                         if self.ModuleType != self.BuildType:\r
1635                             RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]\r
1636                 if not RuleObject:\r
1637                     continue\r
1638                 RuleObject = RuleObject.Instantiate(self.Macros)\r
1639                 BuildRules[Type] = RuleObject\r
1640                 for Ext in RuleObject.SourceFileExtList:\r
1641                     BuildRules[Ext] = RuleObject\r
1642             self._BuildRules = BuildRules\r
1643         return self._BuildRules\r
1644 \r
1645     def _ApplyBuildRule(self, File, FileType):\r
1646         if self._BuildTargets == None:\r
1647             self._IntroBuildTargetList = set()\r
1648             self._FinalBuildTargetList = set()\r
1649             self._BuildTargets = {}\r
1650             self._FileTypes = {}\r
1651 \r
1652         LastTarget = None\r
1653         RuleChain = []\r
1654         SourceList = [File]\r
1655         Index = 0\r
1656         while Index < len(SourceList):\r
1657             Source = SourceList[Index]\r
1658             Index = Index + 1\r
1659 \r
1660             if Source != File:\r
1661                 CreateDirectory(Source.Dir)\r
1662 \r
1663             if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:\r
1664                 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]\r
1665             elif FileType in self.BuildRules:\r
1666                 RuleObject = self.BuildRules[FileType]\r
1667             elif Source.Ext in self.BuildRules:\r
1668                 RuleObject = self.BuildRules[Source.Ext]\r
1669             else:\r
1670                 # stop at no more rules\r
1671                 if LastTarget:\r
1672                     self._FinalBuildTargetList.add(LastTarget)\r
1673                 break\r
1674 \r
1675             FileType = RuleObject.SourceFileType\r
1676             if FileType not in self._FileTypes:\r
1677                 self._FileTypes[FileType] = set()\r
1678             self._FileTypes[FileType].add(Source)\r
1679 \r
1680             # stop at STATIC_LIBRARY for library\r
1681             if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:\r
1682                 if LastTarget:\r
1683                     self._FinalBuildTargetList.add(LastTarget)\r
1684                 break\r
1685 \r
1686             Target = RuleObject.Apply(Source)\r
1687             if not Target:\r
1688                 if LastTarget:\r
1689                     self._FinalBuildTargetList.add(LastTarget)\r
1690                 break\r
1691             elif not Target.Outputs:\r
1692                 # Only do build for target with outputs\r
1693                 self._FinalBuildTargetList.add(Target)\r
1694 \r
1695             if FileType not in self._BuildTargets:\r
1696                 self._BuildTargets[FileType] = set()\r
1697             self._BuildTargets[FileType].add(Target)\r
1698 \r
1699             if not Source.IsBinary and Source == File:\r
1700                 self._IntroBuildTargetList.add(Target)\r
1701 \r
1702             # to avoid cyclic rule\r
1703             if FileType in RuleChain:\r
1704                 break\r
1705 \r
1706             RuleChain.append(FileType)\r
1707             SourceList.extend(Target.Outputs)\r
1708             LastTarget = Target\r
1709             FileType = TAB_UNKNOWN_FILE\r
1710 \r
1711     def _GetTargets(self):\r
1712         if self._BuildTargets == None:\r
1713             self._IntroBuildTargetList = set()\r
1714             self._FinalBuildTargetList = set()\r
1715             self._BuildTargets = {}\r
1716             self._FileTypes = {}\r
1717 \r
1718         #TRICK: call _GetSourceFileList to apply build rule for binary files\r
1719         if self.SourceFileList:\r
1720             pass\r
1721 \r
1722         #TRICK: call _GetBinaryFileList to apply build rule for binary files\r
1723         if self.BinaryFileList:\r
1724             pass\r
1725 \r
1726         return self._BuildTargets\r
1727 \r
1728     def _GetIntroTargetList(self):\r
1729         self._GetTargets()\r
1730         return self._IntroBuildTargetList\r
1731 \r
1732     def _GetFinalTargetList(self):\r
1733         self._GetTargets()\r
1734         return self._FinalBuildTargetList\r
1735 \r
1736     def _GetFileTypes(self):\r
1737         self._GetTargets()\r
1738         return self._FileTypes\r
1739 \r
1740     ## Get the list of package object the module depends on\r
1741     #\r
1742     #   @retval     list    The package object list\r
1743     #\r
1744     def _GetDependentPackageList(self):\r
1745         return self.Module.Packages\r
1746 \r
1747     ## Return the list of auto-generated code file\r
1748     #\r
1749     #   @retval     list        The list of auto-generated file\r
1750     #\r
1751     def _GetAutoGenFileList(self):\r
1752         UniStringAutoGenC = True\r
1753         UniStringBinBuffer = None\r
1754         if self.BuildType == 'UEFI_HII':\r
1755             UniStringBinBuffer = StringIO()\r
1756             UniStringAutoGenC = False\r
1757         if self._AutoGenFileList == None:\r
1758             self._AutoGenFileList = {}\r
1759             AutoGenC = TemplateString()\r
1760             AutoGenH = TemplateString()\r
1761             StringH = TemplateString()\r
1762             GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer)\r
1763             if str(AutoGenC) != "" and TAB_C_CODE_FILE in self.FileTypes:\r
1764                 AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)\r
1765                 self._AutoGenFileList[AutoFile] = str(AutoGenC)\r
1766                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
1767             if str(AutoGenH) != "":\r
1768                 AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)\r
1769                 self._AutoGenFileList[AutoFile] = str(AutoGenH)\r
1770                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
1771             if str(StringH) != "":\r
1772                 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)\r
1773                 self._AutoGenFileList[AutoFile] = str(StringH)\r
1774                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
1775             if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":\r
1776                 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)\r
1777                 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()\r
1778                 AutoFile.IsBinary = True\r
1779                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)\r
1780             if UniStringBinBuffer != None:\r
1781                 UniStringBinBuffer.close()\r
1782         return self._AutoGenFileList\r
1783 \r
1784     ## Return the list of library modules explicitly or implicityly used by this module\r
1785     def _GetLibraryList(self):\r
1786         if self._DependentLibraryList == None:\r
1787             # only merge library classes and PCD for non-library module\r
1788             if self.IsLibrary:\r
1789                 self._DependentLibraryList = []\r
1790             else:\r
1791                 if self.AutoGenVersion < 0x00010005:\r
1792                     self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)\r
1793                 else:\r
1794                     self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)\r
1795         return self._DependentLibraryList\r
1796 \r
1797     ## Get the list of PCDs from current module\r
1798     #\r
1799     #   @retval     list                    The list of PCD\r
1800     #\r
1801     def _GetModulePcdList(self):\r
1802         if self._ModulePcdList == None:\r
1803             # apply PCD settings from platform\r
1804             self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)\r
1805         return self._ModulePcdList\r
1806 \r
1807     ## Get the list of PCDs from dependent libraries\r
1808     #\r
1809     #   @retval     list                    The list of PCD\r
1810     #\r
1811     def _GetLibraryPcdList(self):\r
1812         if self._LibraryPcdList == None:\r
1813             Pcds = {}\r
1814             if not self.IsLibrary:\r
1815                 # get PCDs from dependent libraries\r
1816                 for Library in self.DependentLibraryList:\r
1817                     for Key in Library.Pcds:\r
1818                         # skip duplicated PCDs\r
1819                         if Key in self.Module.Pcds or Key in Pcds:\r
1820                             continue\r
1821                         Pcds[Key] = copy.copy(Library.Pcds[Key])\r
1822                 # apply PCD settings from platform\r
1823                 self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)\r
1824             else:\r
1825                 self._LibraryPcdList = []\r
1826         return self._LibraryPcdList\r
1827 \r
1828     ## Get the GUID value mapping\r
1829     #\r
1830     #   @retval     dict    The mapping between GUID cname and its value\r
1831     #\r
1832     def _GetGuidList(self):\r
1833         if self._GuidList == None:\r
1834             self._GuidList = self.Module.Guids\r
1835             for Library in self.DependentLibraryList:\r
1836                 self._GuidList.update(Library.Guids)\r
1837         return self._GuidList\r
1838 \r
1839     ## Get the protocol value mapping\r
1840     #\r
1841     #   @retval     dict    The mapping between protocol cname and its value\r
1842     #\r
1843     def _GetProtocolList(self):\r
1844         if self._ProtocolList == None:\r
1845             self._ProtocolList = self.Module.Protocols\r
1846             for Library in self.DependentLibraryList:\r
1847                 self._ProtocolList.update(Library.Protocols)\r
1848         return self._ProtocolList\r
1849 \r
1850     ## Get the PPI value mapping\r
1851     #\r
1852     #   @retval     dict    The mapping between PPI cname and its value\r
1853     #\r
1854     def _GetPpiList(self):\r
1855         if self._PpiList == None:\r
1856             self._PpiList = self.Module.Ppis\r
1857             for Library in self.DependentLibraryList:\r
1858                 self._PpiList.update(Library.Ppis)\r
1859         return self._PpiList\r
1860 \r
1861     ## Get the list of include search path\r
1862     #\r
1863     #   @retval     list                    The list path\r
1864     #\r
1865     def _GetIncludePathList(self):\r
1866         if self._IncludePathList == None:\r
1867             self._IncludePathList = []\r
1868             if self.AutoGenVersion < 0x00010005:\r
1869                 for Inc in self.Module.Includes:\r
1870                     if Inc not in self._IncludePathList:\r
1871                         self._IncludePathList.append(Inc)\r
1872                     # for r8 modules\r
1873                     Inc = path.join(Inc, self.Arch.capitalize())\r
1874                     if os.path.exists(Inc) and Inc not in self._IncludePathList:\r
1875                         self._IncludePathList.append(Inc)\r
1876                 # r8 module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time\r
1877                 self._IncludePathList.append(self.DebugDir)\r
1878             else:\r
1879                 self._IncludePathList.append(self.MetaFile.Dir)\r
1880                 self._IncludePathList.append(self.DebugDir)\r
1881 \r
1882             for Package in self.Module.Packages:\r
1883                 PackageDir = path.join(self.WorkspaceDir, Package.MetaFile.Dir)\r
1884                 if PackageDir not in self._IncludePathList:\r
1885                     self._IncludePathList.append(PackageDir)\r
1886                 for Inc in Package.Includes:\r
1887                     if Inc not in self._IncludePathList:\r
1888                         self._IncludePathList.append(str(Inc))\r
1889         return self._IncludePathList\r
1890 \r
1891     ## Create makefile for the module and its dependent libraries\r
1892     #\r
1893     #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of\r
1894     #                                       dependent libraries will be created\r
1895     #\r
1896     def CreateMakeFile(self, CreateLibraryMakeFile=True):\r
1897         if self.IsMakeFileCreated:\r
1898             return\r
1899 \r
1900         if not self.IsLibrary and CreateLibraryMakeFile:\r
1901             for LibraryAutoGen in self.LibraryAutoGenList:\r
1902                 LibraryAutoGen.CreateMakeFile()\r
1903 \r
1904         if len(self.CustomMakefile) == 0:\r
1905             Makefile = GenMake.ModuleMakefile(self)\r
1906         else:\r
1907             Makefile = GenMake.CustomMakefile(self)\r
1908         if Makefile.Generate():\r
1909             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %\r
1910                             (self.Name, self.Arch))\r
1911         else:\r
1912             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %\r
1913                             (self.Name, self.Arch))\r
1914 \r
1915         self.IsMakeFileCreated = True\r
1916 \r
1917     ## Create autogen code for the module and its dependent libraries\r
1918     #\r
1919     #   @param      CreateLibraryCodeFile   Flag indicating if or not the code of\r
1920     #                                       dependent libraries will be created\r
1921     #\r
1922     def CreateCodeFile(self, CreateLibraryCodeFile=True):\r
1923         if self.IsCodeFileCreated:\r
1924             return\r
1925 \r
1926         if not self.IsLibrary and CreateLibraryCodeFile:\r
1927             for LibraryAutoGen in self.LibraryAutoGenList:\r
1928                 LibraryAutoGen.CreateCodeFile()\r
1929 \r
1930         AutoGenList = []\r
1931         IgoredAutoGenList = []\r
1932 \r
1933         for File in self.AutoGenFileList:\r
1934             if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):\r
1935                 #Ignore R8 AutoGen.c\r
1936                 if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':\r
1937                         continue\r
1938 \r
1939                 AutoGenList.append(str(File))\r
1940             else:\r
1941                 IgoredAutoGenList.append(str(File))\r
1942 \r
1943         # Skip the following code for EDK I inf\r
1944         if self.AutoGenVersion < 0x00010005:\r
1945             return\r
1946 \r
1947         for ModuleType in self.DepexList:\r
1948             if len(self.DepexList[ModuleType]) == 0:\r
1949                 continue\r
1950             Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)\r
1951             DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}\r
1952 \r
1953             if Dpx.Generate(path.join(self.OutputDir, DpxFile)):\r
1954                 AutoGenList.append(str(DpxFile))\r
1955             else:\r
1956                 IgoredAutoGenList.append(str(DpxFile))\r
1957 \r
1958         if IgoredAutoGenList == []:\r
1959             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %\r
1960                             (" ".join(AutoGenList), self.Name, self.Arch))\r
1961         elif AutoGenList == []:\r
1962             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %\r
1963                             (" ".join(IgoredAutoGenList), self.Name, self.Arch))\r
1964         else:\r
1965             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %\r
1966                             (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))\r
1967 \r
1968         self.IsCodeFileCreated = True\r
1969         return AutoGenList\r
1970 \r
1971     ## Summarize the ModuleAutoGen objects of all libraries used by this module\r
1972     def _GetLibraryAutoGenList(self):\r
1973         if self._LibraryAutoGenList == None:\r
1974             self._LibraryAutoGenList = []\r
1975             for Library in self.DependentLibraryList:\r
1976                 La = ModuleAutoGen(\r
1977                         self.Workspace,\r
1978                         Library.MetaFile,\r
1979                         self.BuildTarget,\r
1980                         self.ToolChain,\r
1981                         self.Arch,\r
1982                         self.PlatformInfo.MetaFile\r
1983                         )\r
1984                 if La not in self._LibraryAutoGenList:\r
1985                     self._LibraryAutoGenList.append(La)\r
1986                     for Lib in La.CodaTargetList:\r
1987                         self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)\r
1988         return self._LibraryAutoGenList\r
1989 \r
1990     ## Return build command string\r
1991     #\r
1992     #   @retval     string  Build command string\r
1993     #\r
1994     def _GetBuildCommand(self):\r
1995         return self.PlatformInfo.BuildCommand\r
1996 \r
1997 \r
1998     Module          = property(_GetModule)\r
1999     Name            = property(_GetBaseName)\r
2000     Guid            = property(_GetGuid)\r
2001     Version         = property(_GetVersion)\r
2002     ModuleType      = property(_GetModuleType)\r
2003     ComponentType   = property(_GetComponentType)\r
2004     BuildType       = property(_GetBuildType)\r
2005     PcdIsDriver     = property(_GetPcdIsDriver)\r
2006     AutoGenVersion  = property(_GetAutoGenVersion)\r
2007     Macros          = property(_GetMacros)\r
2008     Specification   = property(_GetSpecification)\r
2009 \r
2010     IsLibrary       = property(_IsLibrary)\r
2011 \r
2012     BuildDir        = property(_GetBuildDir)\r
2013     OutputDir       = property(_GetOutputDir)\r
2014     DebugDir        = property(_GetDebugDir)\r
2015     MakeFileDir     = property(_GetMakeFileDir)\r
2016     CustomMakefile  = property(_GetCustomMakefile)\r
2017 \r
2018     IncludePathList = property(_GetIncludePathList)\r
2019     AutoGenFileList = property(_GetAutoGenFileList)\r
2020     UnicodeFileList = property(_GetUnicodeFileList)\r
2021     SourceFileList  = property(_GetSourceFileList)\r
2022     BinaryFileList  = property(_GetBinaryFiles) # FileType : [File List]\r
2023     Targets         = property(_GetTargets)\r
2024     IntroTargetList = property(_GetIntroTargetList)\r
2025     CodaTargetList  = property(_GetFinalTargetList)\r
2026     FileTypes       = property(_GetFileTypes)\r
2027     BuildRules      = property(_GetBuildRules)\r
2028 \r
2029     DependentPackageList    = property(_GetDependentPackageList)\r
2030     DependentLibraryList    = property(_GetLibraryList)\r
2031     LibraryAutoGenList      = property(_GetLibraryAutoGenList)\r
2032     DerivedPackageList      = property(_GetDerivedPackageList)\r
2033 \r
2034     ModulePcdList           = property(_GetModulePcdList)\r
2035     LibraryPcdList          = property(_GetLibraryPcdList)\r
2036     GuidList                = property(_GetGuidList)\r
2037     ProtocolList            = property(_GetProtocolList)\r
2038     PpiList                 = property(_GetPpiList)\r
2039     DepexList               = property(_GetDepexTokenList)\r
2040     DepexExpressionList     = property(_GetDepexExpressionTokenList)\r
2041     BuildOption             = property(_GetModuleBuildOption)\r
2042     BuildCommand            = property(_GetBuildCommand)\r
2043 \r
2044 # This acts like the main() function for the script, unless it is 'import'ed into another script.\r
2045 if __name__ == '__main__':\r
2046     pass\r
2047 \r