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