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