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