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