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