1## @file 2# Generate AutoGen.h, AutoGen.c and *.depex files 3# 4# Copyright (c) 2007 - 2015, 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# 16import Common.LongFilePathOs as os 17import re 18import os.path as path 19import copy 20import uuid 21 22import GenC 23import GenMake 24import GenDepex 25from StringIO import StringIO 26 27from StrGather import * 28from BuildEngine import BuildRule 29 30from Common.LongFilePathSupport import CopyLongFilePath 31from Common.BuildToolError import * 32from Common.DataType import * 33from Common.Misc import * 34from Common.String import * 35import Common.GlobalData as GlobalData 36from GenFds.FdfParser import * 37from CommonDataClass.CommonClass import SkuInfoClass 38from Workspace.BuildClassObject import * 39from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile 40import Common.VpdInfoFile as VpdInfoFile 41from GenPcdDb import CreatePcdDatabaseCode 42from Workspace.MetaFileCommentParser import UsageList 43from Common.MultipleWorkspace import MultipleWorkspace as mws 44import InfSectionParser 45 46## Regular expression for splitting Dependency Expression string into tokens 47gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)") 48 49# 50# Match name = variable 51# 52gEfiVarStoreNamePattern = re.compile("\s*name\s*=\s*(\w+)") 53# 54# The format of guid in efivarstore statement likes following and must be correct: 55# guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}} 56# 57gEfiVarStoreGuidPattern = re.compile("\s*guid\s*=\s*({.*?{.*?}\s*})") 58 59## Mapping Makefile type 60gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"} 61 62 63## Build rule configuration file 64gDefaultBuildRuleFile = 'Conf/build_rule.txt' 65 66## Build rule default version 67AutoGenReqBuildRuleVerNum = "0.1" 68 69## default file name for AutoGen 70gAutoGenCodeFileName = "AutoGen.c" 71gAutoGenHeaderFileName = "AutoGen.h" 72gAutoGenStringFileName = "%(module_name)sStrDefs.h" 73gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk" 74gAutoGenDepexFileName = "%(module_name)s.depex" 75 76gInfSpecVersion = "0x00010017" 77 78# 79# Template string to generic AsBuilt INF 80# 81gAsBuiltInfHeaderString = TemplateString("""${header_comments} 82 83# DO NOT EDIT 84# FILE auto-generated 85 86[Defines] 87 INF_VERSION = ${module_inf_version} 88 BASE_NAME = ${module_name} 89 FILE_GUID = ${module_guid} 90 MODULE_TYPE = ${module_module_type}${BEGIN} 91 VERSION_STRING = ${module_version_string}${END}${BEGIN} 92 PCD_IS_DRIVER = ${pcd_is_driver_string}${END}${BEGIN} 93 UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN} 94 PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}${BEGIN} 95 ENTRY_POINT = ${module_entry_point}${END}${BEGIN} 96 UNLOAD_IMAGE = ${module_unload_image}${END}${BEGIN} 97 CONSTRUCTOR = ${module_constructor}${END}${BEGIN} 98 DESTRUCTOR = ${module_destructor}${END}${BEGIN} 99 SHADOW = ${module_shadow}${END}${BEGIN} 100 PCI_VENDOR_ID = ${module_pci_vendor_id}${END}${BEGIN} 101 PCI_DEVICE_ID = ${module_pci_device_id}${END}${BEGIN} 102 PCI_CLASS_CODE = ${module_pci_class_code}${END}${BEGIN} 103 PCI_REVISION = ${module_pci_revision}${END}${BEGIN} 104 BUILD_NUMBER = ${module_build_number}${END}${BEGIN} 105 SPEC = ${module_spec}${END}${BEGIN} 106 UEFI_HII_RESOURCE_SECTION = ${module_uefi_hii_resource_section}${END}${BEGIN} 107 MODULE_UNI_FILE = ${module_uni_file}${END} 108 109[Packages.${module_arch}]${BEGIN} 110 ${package_item}${END} 111 112[Binaries.${module_arch}]${BEGIN} 113 ${binary_item}${END} 114 115[PatchPcd.${module_arch}]${BEGIN} 116 ${patchablepcd_item} 117${END} 118 119[Protocols.${module_arch}]${BEGIN} 120 ${protocol_item} 121${END} 122 123[Ppis.${module_arch}]${BEGIN} 124 ${ppi_item} 125${END} 126 127[Guids.${module_arch}]${BEGIN} 128 ${guid_item} 129${END} 130 131[PcdEx.${module_arch}]${BEGIN} 132 ${pcd_item} 133${END} 134 135[LibraryClasses.${module_arch}] 136## @LIB_INSTANCES${BEGIN} 137# ${libraryclasses_item}${END} 138 139${depexsection_item} 140 141${tail_comments} 142 143[BuildOptions.${module_arch}] 144## @AsBuilt${BEGIN} 145## ${flags_item}${END} 146""") 147 148## Base class for AutoGen 149# 150# This class just implements the cache mechanism of AutoGen objects. 151# 152class AutoGen(object): 153 # database to maintain the objects of xxxAutoGen 154 _CACHE_ = {} # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}} 155 156 ## Factory method 157 # 158 # @param Class class object of real AutoGen class 159 # (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen) 160 # @param Workspace Workspace directory or WorkspaceAutoGen object 161 # @param MetaFile The path of meta file 162 # @param Target Build target 163 # @param Toolchain Tool chain name 164 # @param Arch Target arch 165 # @param *args The specific class related parameters 166 # @param **kwargs The specific class related dict parameters 167 # 168 def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs): 169 # check if the object has been created 170 Key = (Target, Toolchain) 171 if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \ 172 or MetaFile not in Class._CACHE_[Key][Arch]: 173 AutoGenObject = super(AutoGen, Class).__new__(Class) 174 # call real constructor 175 if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs): 176 return None 177 if Key not in Class._CACHE_: 178 Class._CACHE_[Key] = {} 179 if Arch not in Class._CACHE_[Key]: 180 Class._CACHE_[Key][Arch] = {} 181 Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject 182 else: 183 AutoGenObject = Class._CACHE_[Key][Arch][MetaFile] 184 185 return AutoGenObject 186 187 ## hash() operator 188 # 189 # The file path of platform file will be used to represent hash value of this object 190 # 191 # @retval int Hash value of the file path of platform file 192 # 193 def __hash__(self): 194 return hash(self.MetaFile) 195 196 ## str() operator 197 # 198 # The file path of platform file will be used to represent this object 199 # 200 # @retval string String of platform file path 201 # 202 def __str__(self): 203 return str(self.MetaFile) 204 205 ## "==" operator 206 def __eq__(self, Other): 207 return Other and self.MetaFile == Other 208 209## Workspace AutoGen class 210# 211# This class is used mainly to control the whole platform build for different 212# architecture. This class will generate top level makefile. 213# 214class WorkspaceAutoGen(AutoGen): 215 ## Real constructor of WorkspaceAutoGen 216 # 217 # This method behaves the same as __init__ except that it needs explicit invoke 218 # (in super class's __new__ method) 219 # 220 # @param WorkspaceDir Root directory of workspace 221 # @param ActivePlatform Meta-file of active platform 222 # @param Target Build target 223 # @param Toolchain Tool chain name 224 # @param ArchList List of architecture of current build 225 # @param MetaFileDb Database containing meta-files 226 # @param BuildConfig Configuration of build 227 # @param ToolDefinition Tool chain definitions 228 # @param FlashDefinitionFile File of flash definition 229 # @param Fds FD list to be generated 230 # @param Fvs FV list to be generated 231 # @param Caps Capsule list to be generated 232 # @param SkuId SKU id from command line 233 # 234 def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb, 235 BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=None, Fvs=None, Caps=None, SkuId='', UniFlag=None, 236 Progress=None, BuildModule=None): 237 if Fds is None: 238 Fds = [] 239 if Fvs is None: 240 Fvs = [] 241 if Caps is None: 242 Caps = [] 243 self.BuildDatabase = MetaFileDb 244 self.MetaFile = ActivePlatform 245 self.WorkspaceDir = WorkspaceDir 246 self.Platform = self.BuildDatabase[self.MetaFile, 'COMMON', Target, Toolchain] 247 GlobalData.gActivePlatform = self.Platform 248 self.BuildTarget = Target 249 self.ToolChain = Toolchain 250 self.ArchList = ArchList 251 self.SkuId = SkuId 252 self.UniFlag = UniFlag 253 254 self.TargetTxt = BuildConfig 255 self.ToolDef = ToolDefinition 256 self.FdfFile = FlashDefinitionFile 257 self.FdTargetList = Fds 258 self.FvTargetList = Fvs 259 self.CapTargetList = Caps 260 self.AutoGenObjectList = [] 261 262 # there's many relative directory operations, so ... 263 os.chdir(self.WorkspaceDir) 264 265 # 266 # Merge Arch 267 # 268 if not self.ArchList: 269 ArchList = set(self.Platform.SupArchList) 270 else: 271 ArchList = set(self.ArchList) & set(self.Platform.SupArchList) 272 if not ArchList: 273 EdkLogger.error("build", PARAMETER_INVALID, 274 ExtraData = "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self.Platform.SupArchList))) 275 elif self.ArchList and len(ArchList) != len(self.ArchList): 276 SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList)) 277 EdkLogger.verbose("\nArch [%s] is ignored because the platform supports [%s] only!" 278 % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList))) 279 self.ArchList = tuple(ArchList) 280 281 # Validate build target 282 if self.BuildTarget not in self.Platform.BuildTargets: 283 EdkLogger.error("build", PARAMETER_INVALID, 284 ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]" 285 % (self.BuildTarget, " ".join(self.Platform.BuildTargets))) 286 287 288 # parse FDF file to get PCDs in it, if any 289 if not self.FdfFile: 290 self.FdfFile = self.Platform.FlashDefinition 291 292 EdkLogger.info("") 293 if self.ArchList: 294 EdkLogger.info('%-16s = %s' % ("Architecture(s)", ' '.join(self.ArchList))) 295 EdkLogger.info('%-16s = %s' % ("Build target", self.BuildTarget)) 296 EdkLogger.info('%-16s = %s' % ("Toolchain", self.ToolChain)) 297 298 EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.Platform)) 299 if BuildModule: 300 EdkLogger.info('%-24s = %s' % ("Active Module", BuildModule)) 301 302 if self.FdfFile: 303 EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.FdfFile)) 304 305 EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile) 306 307 if Progress: 308 Progress.Start("\nProcessing meta-data") 309 310 if self.FdfFile: 311 # 312 # Mark now build in AutoGen Phase 313 # 314 GlobalData.gAutoGenPhase = True 315 Fdf = FdfParser(self.FdfFile.Path) 316 Fdf.ParseFile() 317 GlobalData.gFdfParser = Fdf 318 GlobalData.gAutoGenPhase = False 319 PcdSet = Fdf.Profile.PcdDict 320 ModuleList = Fdf.Profile.InfList 321 self.FdfProfile = Fdf.Profile 322 for fvname in self.FvTargetList: 323 if fvname.upper() not in self.FdfProfile.FvDict: 324 EdkLogger.error("build", OPTION_VALUE_INVALID, 325 "No such an FV in FDF file: %s" % fvname) 326 else: 327 PcdSet = {} 328 ModuleList = [] 329 self.FdfProfile = None 330 if self.FdTargetList: 331 EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdTargetList)) 332 self.FdTargetList = [] 333 if self.FvTargetList: 334 EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvTargetList)) 335 self.FvTargetList = [] 336 if self.CapTargetList: 337 EdkLogger.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self.CapTargetList)) 338 self.CapTargetList = [] 339 340 # apply SKU and inject PCDs from Flash Definition file 341 for Arch in self.ArchList: 342 Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain] 343 344 DecPcds = {} 345 DecPcdsKey = set() 346 PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch) 347 #Collect package set information from INF of FDF 348 PkgSet = set() 349 for Inf in ModuleList: 350 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch) 351 if ModuleFile in Platform.Modules: 352 continue 353 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain] 354 PkgSet.update(ModuleData.Packages) 355 Pkgs = list(PkgSet) + list(PGen.PackageList) 356 for Pkg in Pkgs: 357 for Pcd in Pkg.Pcds: 358 DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd] 359 DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2])) 360 361 Platform.SkuName = self.SkuId 362 for Name, Guid in PcdSet: 363 if (Name, Guid) not in DecPcds: 364 EdkLogger.error( 365 'build', 366 PARSER_ERROR, 367 "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid, Name), 368 File = self.FdfProfile.PcdFileLineDict[Name, Guid][0], 369 Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1] 370 ) 371 else: 372 # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message. 373 if (Name, Guid, TAB_PCDS_FIXED_AT_BUILD) in DecPcdsKey \ 374 or (Name, Guid, TAB_PCDS_PATCHABLE_IN_MODULE) in DecPcdsKey \ 375 or (Name, Guid, TAB_PCDS_FEATURE_FLAG) in DecPcdsKey: 376 Platform.AddPcd(Name, Guid, PcdSet[Name, Guid]) 377 continue 378 elif (Name, Guid, TAB_PCDS_DYNAMIC) in DecPcdsKey or (Name, Guid, TAB_PCDS_DYNAMIC_EX) in DecPcdsKey: 379 EdkLogger.error( 380 'build', 381 PARSER_ERROR, 382 "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid, Name), 383 File = self.FdfProfile.PcdFileLineDict[Name, Guid][0], 384 Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1] 385 ) 386 387 Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch) 388 # 389 # Explicitly collect platform's dynamic PCDs 390 # 391 Pa.CollectPlatformDynamicPcds() 392 Pa.CollectFixedAtBuildPcds() 393 self.AutoGenObjectList.append(Pa) 394 395 # 396 # Check PCDs token value conflict in each DEC file. 397 # 398 self._CheckAllPcdsTokenValueConflict() 399 400 # 401 # Check PCD type and definition between DSC and DEC 402 # 403 self._CheckPcdDefineAndType() 404 405# if self.FdfFile: 406# self._CheckDuplicateInFV(Fdf) 407 408 self._BuildDir = None 409 self._FvDir = None 410 self._MakeFileDir = None 411 self._BuildCommand = None 412 413 return True 414 415 ## _CheckDuplicateInFV() method 416 # 417 # Check whether there is duplicate modules/files exist in FV section. 418 # The check base on the file GUID; 419 # 420 def _CheckDuplicateInFV(self, Fdf): 421 for Fv in Fdf.Profile.FvDict: 422 _GuidDict = {} 423 for FfsFile in Fdf.Profile.FvDict[Fv].FfsList: 424 if FfsFile.InfFileName and FfsFile.NameGuid == None: 425 # 426 # Get INF file GUID 427 # 428 InfFoundFlag = False 429 for Pa in self.AutoGenObjectList: 430 if InfFoundFlag: 431 break 432 for Module in Pa.ModuleAutoGenList: 433 if path.normpath(Module.MetaFile.File) == path.normpath(FfsFile.InfFileName): 434 InfFoundFlag = True 435 if not Module.Guid.upper() in _GuidDict.keys(): 436 _GuidDict[Module.Guid.upper()] = FfsFile 437 break 438 else: 439 EdkLogger.error("build", 440 FORMAT_INVALID, 441 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum, 442 FfsFile.CurrentLineContent, 443 _GuidDict[Module.Guid.upper()].CurrentLineNum, 444 _GuidDict[Module.Guid.upper()].CurrentLineContent, 445 Module.Guid.upper()), 446 ExtraData=self.FdfFile) 447 # 448 # Some INF files not have entity in DSC file. 449 # 450 if not InfFoundFlag: 451 if FfsFile.InfFileName.find('$') == -1: 452 InfPath = NormPath(FfsFile.InfFileName) 453 if not os.path.exists(InfPath): 454 EdkLogger.error('build', GENFDS_ERROR, "Non-existant Module %s !" % (FfsFile.InfFileName)) 455 456 PathClassObj = PathClass(FfsFile.InfFileName, self.WorkspaceDir) 457 # 458 # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use 459 # BuildObject from one of AutoGenObjectList is enough. 460 # 461 InfObj = self.AutoGenObjectList[0].BuildDatabase.WorkspaceDb.BuildObject[PathClassObj, 'COMMON', self.BuildTarget, self.ToolChain] 462 if not InfObj.Guid.upper() in _GuidDict.keys(): 463 _GuidDict[InfObj.Guid.upper()] = FfsFile 464 else: 465 EdkLogger.error("build", 466 FORMAT_INVALID, 467 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum, 468 FfsFile.CurrentLineContent, 469 _GuidDict[InfObj.Guid.upper()].CurrentLineNum, 470 _GuidDict[InfObj.Guid.upper()].CurrentLineContent, 471 InfObj.Guid.upper()), 472 ExtraData=self.FdfFile) 473 InfFoundFlag = False 474 475 if FfsFile.NameGuid != None: 476 _CheckPCDAsGuidPattern = re.compile("^PCD\(.+\..+\)$") 477 478 # 479 # If the NameGuid reference a PCD name. 480 # The style must match: PCD(xxxx.yyy) 481 # 482 if _CheckPCDAsGuidPattern.match(FfsFile.NameGuid): 483 # 484 # Replace the PCD value. 485 # 486 _PcdName = FfsFile.NameGuid.lstrip("PCD(").rstrip(")") 487 PcdFoundFlag = False 488 for Pa in self.AutoGenObjectList: 489 if not PcdFoundFlag: 490 for PcdItem in Pa.AllPcdList: 491 if (PcdItem.TokenSpaceGuidCName + "." + PcdItem.TokenCName) == _PcdName: 492 # 493 # First convert from CFormatGuid to GUID string 494 # 495 _PcdGuidString = GuidStructureStringToGuidString(PcdItem.DefaultValue) 496 497 if not _PcdGuidString: 498 # 499 # Then try Byte array. 500 # 501 _PcdGuidString = GuidStructureByteArrayToGuidString(PcdItem.DefaultValue) 502 503 if not _PcdGuidString: 504 # 505 # Not Byte array or CFormat GUID, raise error. 506 # 507 EdkLogger.error("build", 508 FORMAT_INVALID, 509 "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName, PcdItem.DefaultValue), 510 ExtraData=self.FdfFile) 511 512 if not _PcdGuidString.upper() in _GuidDict.keys(): 513 _GuidDict[_PcdGuidString.upper()] = FfsFile 514 PcdFoundFlag = True 515 break 516 else: 517 EdkLogger.error("build", 518 FORMAT_INVALID, 519 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum, 520 FfsFile.CurrentLineContent, 521 _GuidDict[_PcdGuidString.upper()].CurrentLineNum, 522 _GuidDict[_PcdGuidString.upper()].CurrentLineContent, 523 FfsFile.NameGuid.upper()), 524 ExtraData=self.FdfFile) 525 526 if not FfsFile.NameGuid.upper() in _GuidDict.keys(): 527 _GuidDict[FfsFile.NameGuid.upper()] = FfsFile 528 else: 529 # 530 # Two raw file GUID conflict. 531 # 532 EdkLogger.error("build", 533 FORMAT_INVALID, 534 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum, 535 FfsFile.CurrentLineContent, 536 _GuidDict[FfsFile.NameGuid.upper()].CurrentLineNum, 537 _GuidDict[FfsFile.NameGuid.upper()].CurrentLineContent, 538 FfsFile.NameGuid.upper()), 539 ExtraData=self.FdfFile) 540 541 542 def _CheckPcdDefineAndType(self): 543 PcdTypeList = [ 544 "FixedAtBuild", "PatchableInModule", "FeatureFlag", 545 "Dynamic", #"DynamicHii", "DynamicVpd", 546 "DynamicEx", # "DynamicExHii", "DynamicExVpd" 547 ] 548 549 # This dict store PCDs which are not used by any modules with specified arches 550 UnusedPcd = sdict() 551 for Pa in self.AutoGenObjectList: 552 # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid 553 for Pcd in Pa.Platform.Pcds: 554 PcdType = Pa.Platform.Pcds[Pcd].Type 555 556 # If no PCD type, this PCD comes from FDF 557 if not PcdType: 558 continue 559 560 # Try to remove Hii and Vpd suffix 561 if PcdType.startswith("DynamicEx"): 562 PcdType = "DynamicEx" 563 elif PcdType.startswith("Dynamic"): 564 PcdType = "Dynamic" 565 566 for Package in Pa.PackageList: 567 # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType 568 if (Pcd[0], Pcd[1], PcdType) in Package.Pcds: 569 break 570 for Type in PcdTypeList: 571 if (Pcd[0], Pcd[1], Type) in Package.Pcds: 572 EdkLogger.error( 573 'build', 574 FORMAT_INVALID, 575 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \ 576 % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type), 577 ExtraData=None 578 ) 579 return 580 else: 581 UnusedPcd.setdefault(Pcd, []).append(Pa.Arch) 582 583 for Pcd in UnusedPcd: 584 EdkLogger.warn( 585 'build', 586 "The PCD was not specified by any INF module in the platform for the given architecture.\n" 587 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s" 588 % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])), 589 ExtraData=None 590 ) 591 592 def __repr__(self): 593 return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList)) 594 595 ## Return the directory to store FV files 596 def _GetFvDir(self): 597 if self._FvDir == None: 598 self._FvDir = path.join(self.BuildDir, 'FV') 599 return self._FvDir 600 601 ## Return the directory to store all intermediate and final files built 602 def _GetBuildDir(self): 603 return self.AutoGenObjectList[0].BuildDir 604 605 ## Return the build output directory platform specifies 606 def _GetOutputDir(self): 607 return self.Platform.OutputDirectory 608 609 ## Return platform name 610 def _GetName(self): 611 return self.Platform.PlatformName 612 613 ## Return meta-file GUID 614 def _GetGuid(self): 615 return self.Platform.Guid 616 617 ## Return platform version 618 def _GetVersion(self): 619 return self.Platform.Version 620 621 ## Return paths of tools 622 def _GetToolDefinition(self): 623 return self.AutoGenObjectList[0].ToolDefinition 624 625 ## Return directory of platform makefile 626 # 627 # @retval string Makefile directory 628 # 629 def _GetMakeFileDir(self): 630 if self._MakeFileDir == None: 631 self._MakeFileDir = self.BuildDir 632 return self._MakeFileDir 633 634 ## Return build command string 635 # 636 # @retval string Build command string 637 # 638 def _GetBuildCommand(self): 639 if self._BuildCommand == None: 640 # BuildCommand should be all the same. So just get one from platform AutoGen 641 self._BuildCommand = self.AutoGenObjectList[0].BuildCommand 642 return self._BuildCommand 643 644 ## Check the PCDs token value conflict in each DEC file. 645 # 646 # Will cause build break and raise error message while two PCDs conflict. 647 # 648 # @return None 649 # 650 def _CheckAllPcdsTokenValueConflict(self): 651 for Pa in self.AutoGenObjectList: 652 for Package in Pa.PackageList: 653 PcdList = Package.Pcds.values() 654 PcdList.sort(lambda x, y: cmp(int(x.TokenValue, 0), int(y.TokenValue, 0))) 655 Count = 0 656 while (Count < len(PcdList) - 1) : 657 Item = PcdList[Count] 658 ItemNext = PcdList[Count + 1] 659 # 660 # Make sure in the same token space the TokenValue should be unique 661 # 662 if (int(Item.TokenValue, 0) == int(ItemNext.TokenValue, 0)): 663 SameTokenValuePcdList = [] 664 SameTokenValuePcdList.append(Item) 665 SameTokenValuePcdList.append(ItemNext) 666 RemainPcdListLength = len(PcdList) - Count - 2 667 for ValueSameCount in range(RemainPcdListLength): 668 if int(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount].TokenValue, 0) == int(Item.TokenValue, 0): 669 SameTokenValuePcdList.append(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount]) 670 else: 671 break; 672 # 673 # Sort same token value PCD list with TokenGuid and TokenCName 674 # 675 SameTokenValuePcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName))) 676 SameTokenValuePcdListCount = 0 677 while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1): 678 TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount] 679 TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1] 680 681 if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName): 682 EdkLogger.error( 683 'build', 684 FORMAT_INVALID, 685 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\ 686 % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package), 687 ExtraData=None 688 ) 689 SameTokenValuePcdListCount += 1 690 Count += SameTokenValuePcdListCount 691 Count += 1 692 693 PcdList = Package.Pcds.values() 694 PcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName))) 695 Count = 0 696 while (Count < len(PcdList) - 1) : 697 Item = PcdList[Count] 698 ItemNext = PcdList[Count + 1] 699 # 700 # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well. 701 # 702 if (Item.TokenSpaceGuidCName == ItemNext.TokenSpaceGuidCName) and (Item.TokenCName == ItemNext.TokenCName) and (int(Item.TokenValue, 0) != int(ItemNext.TokenValue, 0)): 703 EdkLogger.error( 704 'build', 705 FORMAT_INVALID, 706 "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\ 707 % (Item.TokenValue, Item.TokenSpaceGuidCName, Item.TokenCName, Package), 708 ExtraData=None 709 ) 710 Count += 1 711 ## Generate fds command 712 def _GenFdsCommand(self): 713 return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip() 714 715 ## Create makefile for the platform and modules in it 716 # 717 # @param CreateDepsMakeFile Flag indicating if the makefile for 718 # modules will be created as well 719 # 720 def CreateMakeFile(self, CreateDepsMakeFile=False): 721 if CreateDepsMakeFile: 722 for Pa in self.AutoGenObjectList: 723 Pa.CreateMakeFile(CreateDepsMakeFile) 724 725 ## Create autogen code for platform and modules 726 # 727 # Since there's no autogen code for platform, this method will do nothing 728 # if CreateModuleCodeFile is set to False. 729 # 730 # @param CreateDepsCodeFile Flag indicating if creating module's 731 # autogen code file or not 732 # 733 def CreateCodeFile(self, CreateDepsCodeFile=False): 734 if not CreateDepsCodeFile: 735 return 736 for Pa in self.AutoGenObjectList: 737 Pa.CreateCodeFile(CreateDepsCodeFile) 738 739 ## Create AsBuilt INF file the platform 740 # 741 def CreateAsBuiltInf(self): 742 return 743 744 Name = property(_GetName) 745 Guid = property(_GetGuid) 746 Version = property(_GetVersion) 747 OutputDir = property(_GetOutputDir) 748 749 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path 750 751 BuildDir = property(_GetBuildDir) 752 FvDir = property(_GetFvDir) 753 MakeFileDir = property(_GetMakeFileDir) 754 BuildCommand = property(_GetBuildCommand) 755 GenFdsCommand = property(_GenFdsCommand) 756 757## AutoGen class for platform 758# 759# PlatformAutoGen class will process the original information in platform 760# file in order to generate makefile for platform. 761# 762class PlatformAutoGen(AutoGen): 763 # 764 # Used to store all PCDs for both PEI and DXE phase, in order to generate 765 # correct PCD database 766 # 767 _DynaPcdList_ = [] 768 _NonDynaPcdList_ = [] 769 770 # 771 # The priority list while override build option 772 # 773 PrioList = {"0x11111" : 16, # TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest) 774 "0x01111" : 15, # ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 775 "0x10111" : 14, # TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE 776 "0x00111" : 13, # ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE 777 "0x11011" : 12, # TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE 778 "0x01011" : 11, # ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE 779 "0x10011" : 10, # TARGET_*********_****_COMMANDTYPE_ATTRIBUTE 780 "0x00011" : 9, # ******_*********_****_COMMANDTYPE_ATTRIBUTE 781 "0x11101" : 8, # TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE 782 "0x01101" : 7, # ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE 783 "0x10101" : 6, # TARGET_*********_ARCH_***********_ATTRIBUTE 784 "0x00101" : 5, # ******_*********_ARCH_***********_ATTRIBUTE 785 "0x11001" : 4, # TARGET_TOOLCHAIN_****_***********_ATTRIBUTE 786 "0x01001" : 3, # ******_TOOLCHAIN_****_***********_ATTRIBUTE 787 "0x10001" : 2, # TARGET_*********_****_***********_ATTRIBUTE 788 "0x00001" : 1} # ******_*********_****_***********_ATTRIBUTE (Lowest) 789 790 ## The real constructor of PlatformAutoGen 791 # 792 # This method is not supposed to be called by users of PlatformAutoGen. It's 793 # only used by factory method __new__() to do real initialization work for an 794 # object of PlatformAutoGen 795 # 796 # @param Workspace WorkspaceAutoGen object 797 # @param PlatformFile Platform file (DSC file) 798 # @param Target Build target (DEBUG, RELEASE) 799 # @param Toolchain Name of tool chain 800 # @param Arch arch of the platform supports 801 # 802 def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch): 803 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch)) 804 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target) 805 806 self.MetaFile = PlatformFile 807 self.Workspace = Workspace 808 self.WorkspaceDir = Workspace.WorkspaceDir 809 self.ToolChain = Toolchain 810 self.BuildTarget = Target 811 self.Arch = Arch 812 self.SourceDir = PlatformFile.SubDir 813 self.SourceOverrideDir = None 814 self.FdTargetList = self.Workspace.FdTargetList 815 self.FvTargetList = self.Workspace.FvTargetList 816 self.AllPcdList = [] 817 # get the original module/package/platform objects 818 self.BuildDatabase = Workspace.BuildDatabase 819 820 # flag indicating if the makefile/C-code file has been created or not 821 self.IsMakeFileCreated = False 822 self.IsCodeFileCreated = False 823 824 self._Platform = None 825 self._Name = None 826 self._Guid = None 827 self._Version = None 828 829 self._BuildRule = None 830 self._SourceDir = None 831 self._BuildDir = None 832 self._OutputDir = None 833 self._FvDir = None 834 self._MakeFileDir = None 835 self._FdfFile = None 836 837 self._PcdTokenNumber = None # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber 838 self._DynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] 839 self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] 840 self._NonDynamicPcdDict = {} 841 842 self._ToolDefinitions = None 843 self._ToolDefFile = None # toolcode : tool path 844 self._ToolChainFamily = None 845 self._BuildRuleFamily = None 846 self._BuildOption = None # toolcode : option 847 self._EdkBuildOption = None # edktoolcode : option 848 self._EdkIIBuildOption = None # edkiitoolcode : option 849 self._PackageList = None 850 self._ModuleAutoGenList = None 851 self._LibraryAutoGenList = None 852 self._BuildCommand = None 853 self._AsBuildInfList = [] 854 self._AsBuildModuleList = [] 855 if GlobalData.gFdfParser != None: 856 self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList 857 for Inf in self._AsBuildInfList: 858 InfClass = PathClass(NormPath(Inf), GlobalData.gWorkspace, self.Arch) 859 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain] 860 if not M.IsSupportedArch: 861 continue 862 self._AsBuildModuleList.append(InfClass) 863 # get library/modules for build 864 self.LibraryBuildDirectoryList = [] 865 self.ModuleBuildDirectoryList = [] 866 return True 867 868 def __repr__(self): 869 return "%s [%s]" % (self.MetaFile, self.Arch) 870 871 ## Create autogen code for platform and modules 872 # 873 # Since there's no autogen code for platform, this method will do nothing 874 # if CreateModuleCodeFile is set to False. 875 # 876 # @param CreateModuleCodeFile Flag indicating if creating module's 877 # autogen code file or not 878 # 879 def CreateCodeFile(self, CreateModuleCodeFile=False): 880 # only module has code to be greated, so do nothing if CreateModuleCodeFile is False 881 if self.IsCodeFileCreated or not CreateModuleCodeFile: 882 return 883 884 for Ma in self.ModuleAutoGenList: 885 Ma.CreateCodeFile(True) 886 887 # don't do this twice 888 self.IsCodeFileCreated = True 889 890 ## Generate Fds Command 891 def _GenFdsCommand(self): 892 return self.Workspace.GenFdsCommand 893 894 ## Create makefile for the platform and mdoules in it 895 # 896 # @param CreateModuleMakeFile Flag indicating if the makefile for 897 # modules will be created as well 898 # 899 def CreateMakeFile(self, CreateModuleMakeFile=False): 900 if CreateModuleMakeFile: 901 for ModuleFile in self.Platform.Modules: 902 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget, 903 self.ToolChain, self.Arch, self.MetaFile) 904 Ma.CreateMakeFile(True) 905 #Ma.CreateAsBuiltInf() 906 907 # no need to create makefile for the platform more than once 908 if self.IsMakeFileCreated: 909 return 910 911 # create library/module build dirs for platform 912 Makefile = GenMake.PlatformMakefile(self) 913 self.LibraryBuildDirectoryList = Makefile.GetLibraryBuildDirectoryList() 914 self.ModuleBuildDirectoryList = Makefile.GetModuleBuildDirectoryList() 915 916 self.IsMakeFileCreated = True 917 918 ## Deal with Shared FixedAtBuild Pcds 919 # 920 def CollectFixedAtBuildPcds(self): 921 for LibAuto in self.LibraryAutoGenList: 922 FixedAtBuildPcds = {} 923 ShareFixedAtBuildPcdsSameValue = {} 924 for Module in LibAuto._ReferenceModules: 925 for Pcd in Module.FixedAtBuildPcds + LibAuto.FixedAtBuildPcds: 926 key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName)) 927 if key not in FixedAtBuildPcds: 928 ShareFixedAtBuildPcdsSameValue[key] = True 929 FixedAtBuildPcds[key] = Pcd.DefaultValue 930 else: 931 if FixedAtBuildPcds[key] != Pcd.DefaultValue: 932 ShareFixedAtBuildPcdsSameValue[key] = False 933 for Pcd in LibAuto.FixedAtBuildPcds: 934 key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName)) 935 if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) not in self.NonDynamicPcdDict: 936 continue 937 else: 938 DscPcd = self.NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)] 939 if DscPcd.Type != "FixedAtBuild": 940 continue 941 if key in ShareFixedAtBuildPcdsSameValue and ShareFixedAtBuildPcdsSameValue[key]: 942 LibAuto.ConstPcd[key] = Pcd.DefaultValue 943 944 ## Collect dynamic PCDs 945 # 946 # Gather dynamic PCDs list from each module and their settings from platform 947 # This interface should be invoked explicitly when platform action is created. 948 # 949 def CollectPlatformDynamicPcds(self): 950 # for gathering error information 951 NoDatumTypePcdList = set() 952 PcdNotInDb = [] 953 self._GuidValue = {} 954 FdfModuleList = [] 955 for InfName in self._AsBuildInfList: 956 InfName = mws.join(self.WorkspaceDir, InfName) 957 FdfModuleList.append(os.path.normpath(InfName)) 958 for F in self.Platform.Modules.keys(): 959 M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile) 960 #GuidValue.update(M.Guids) 961 962 self.Platform.Modules[F].M = M 963 964 for PcdFromModule in M.ModulePcdList + M.LibraryPcdList: 965 # make sure that the "VOID*" kind of datum has MaxDatumSize set 966 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']: 967 NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F)) 968 969 # Check the PCD from Binary INF or Source INF 970 if M.IsBinaryModule == True: 971 PcdFromModule.IsFromBinaryInf = True 972 973 # Check the PCD from DSC or not 974 if (PcdFromModule.TokenCName, PcdFromModule.TokenSpaceGuidCName) in self.Platform.Pcds.keys(): 975 PcdFromModule.IsFromDsc = True 976 else: 977 PcdFromModule.IsFromDsc = False 978 if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd: 979 if F.Path not in FdfModuleList: 980 # If one of the Source built modules listed in the DSC is not listed 981 # in FDF modules, and the INF lists a PCD can only use the PcdsDynamic 982 # access method (it is only listed in the DEC file that declares the 983 # PCD as PcdsDynamic), then build tool will report warning message 984 # notify the PI that they are attempting to build a module that must 985 # be included in a flash image in order to be functional. These Dynamic 986 # PCD will not be added into the Database unless it is used by other 987 # modules that are included in the FDF file. 988 if PcdFromModule.Type in GenC.gDynamicPcd and \ 989 PcdFromModule.IsFromBinaryInf == False: 990 # Print warning message to let the developer make a determine. 991 if PcdFromModule not in PcdNotInDb: 992 PcdNotInDb.append(PcdFromModule) 993 continue 994 # If one of the Source built modules listed in the DSC is not listed in 995 # FDF modules, and the INF lists a PCD can only use the PcdsDynamicEx 996 # access method (it is only listed in the DEC file that declares the 997 # PCD as PcdsDynamicEx), then DO NOT break the build; DO NOT add the 998 # PCD to the Platform's PCD Database. 999 if PcdFromModule.Type in GenC.gDynamicExPcd: 1000 if PcdFromModule not in PcdNotInDb: 1001 PcdNotInDb.append(PcdFromModule) 1002 continue 1003 # 1004 # If a dynamic PCD used by a PEM module/PEI module & DXE module, 1005 # it should be stored in Pcd PEI database, If a dynamic only 1006 # used by DXE module, it should be stored in DXE PCD database. 1007 # The default Phase is DXE 1008 # 1009 if M.ModuleType in ["PEIM", "PEI_CORE"]: 1010 PcdFromModule.Phase = "PEI" 1011 if PcdFromModule not in self._DynaPcdList_: 1012 self._DynaPcdList_.append(PcdFromModule) 1013 elif PcdFromModule.Phase == 'PEI': 1014 # overwrite any the same PCD existing, if Phase is PEI 1015 Index = self._DynaPcdList_.index(PcdFromModule) 1016 self._DynaPcdList_[Index] = PcdFromModule 1017 elif PcdFromModule not in self._NonDynaPcdList_: 1018 self._NonDynaPcdList_.append(PcdFromModule) 1019 elif PcdFromModule in self._NonDynaPcdList_ and PcdFromModule.IsFromBinaryInf == True: 1020 Index = self._NonDynaPcdList_.index(PcdFromModule) 1021 if self._NonDynaPcdList_[Index].IsFromBinaryInf == False: 1022 #The PCD from Binary INF will override the same one from source INF 1023 self._NonDynaPcdList_.remove (self._NonDynaPcdList_[Index]) 1024 PcdFromModule.Pending = False 1025 self._NonDynaPcdList_.append (PcdFromModule) 1026 # Parse the DynamicEx PCD from the AsBuild INF module list of FDF. 1027 DscModuleList = [] 1028 for ModuleInf in self.Platform.Modules.keys(): 1029 DscModuleList.append (os.path.normpath(ModuleInf.Path)) 1030 # add the PCD from modules that listed in FDF but not in DSC to Database 1031 for InfName in FdfModuleList: 1032 if InfName not in DscModuleList: 1033 InfClass = PathClass(InfName) 1034 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain] 1035 # If a module INF in FDF but not in current arch's DSC module list, it must be module (either binary or source) 1036 # for different Arch. PCDs in source module for different Arch is already added before, so skip the source module here. 1037 # For binary module, if in current arch, we need to list the PCDs into database. 1038 if not M.IsSupportedArch: 1039 continue 1040 # Override the module PCD setting by platform setting 1041 ModulePcdList = self.ApplyPcdSetting(M, M.Pcds) 1042 for PcdFromModule in ModulePcdList: 1043 PcdFromModule.IsFromBinaryInf = True 1044 PcdFromModule.IsFromDsc = False 1045 # Only allow the DynamicEx and Patchable PCD in AsBuild INF 1046 if PcdFromModule.Type not in GenC.gDynamicExPcd and PcdFromModule.Type not in TAB_PCDS_PATCHABLE_IN_MODULE: 1047 EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error", 1048 File=self.MetaFile, 1049 ExtraData="\n\tExisted %s PCD %s in:\n\t\t%s\n" 1050 % (PcdFromModule.Type, PcdFromModule.TokenCName, InfName)) 1051 # make sure that the "VOID*" kind of datum has MaxDatumSize set 1052 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']: 1053 NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, InfName)) 1054 if M.ModuleType in ["PEIM", "PEI_CORE"]: 1055 PcdFromModule.Phase = "PEI" 1056 if PcdFromModule not in self._DynaPcdList_ and PcdFromModule.Type in GenC.gDynamicExPcd: 1057 self._DynaPcdList_.append(PcdFromModule) 1058 elif PcdFromModule not in self._NonDynaPcdList_ and PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE: 1059 self._NonDynaPcdList_.append(PcdFromModule) 1060 if PcdFromModule in self._DynaPcdList_ and PcdFromModule.Phase == 'PEI' and PcdFromModule.Type in GenC.gDynamicExPcd: 1061 # Overwrite the phase of any the same PCD existing, if Phase is PEI. 1062 # It is to solve the case that a dynamic PCD used by a PEM module/PEI 1063 # module & DXE module at a same time. 1064 # Overwrite the type of the PCDs in source INF by the type of AsBuild 1065 # INF file as DynamicEx. 1066 Index = self._DynaPcdList_.index(PcdFromModule) 1067 self._DynaPcdList_[Index].Phase = PcdFromModule.Phase 1068 self._DynaPcdList_[Index].Type = PcdFromModule.Type 1069 for PcdFromModule in self._NonDynaPcdList_: 1070 # If a PCD is not listed in the DSC file, but binary INF files used by 1071 # this platform all (that use this PCD) list the PCD in a [PatchPcds] 1072 # section, AND all source INF files used by this platform the build 1073 # that use the PCD list the PCD in either a [Pcds] or [PatchPcds] 1074 # section, then the tools must NOT add the PCD to the Platform's PCD 1075 # Database; the build must assign the access method for this PCD as 1076 # PcdsPatchableInModule. 1077 if PcdFromModule not in self._DynaPcdList_: 1078 continue 1079 Index = self._DynaPcdList_.index(PcdFromModule) 1080 if PcdFromModule.IsFromDsc == False and \ 1081 PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE and \ 1082 PcdFromModule.IsFromBinaryInf == True and \ 1083 self._DynaPcdList_[Index].IsFromBinaryInf == False: 1084 Index = self._DynaPcdList_.index(PcdFromModule) 1085 self._DynaPcdList_.remove (self._DynaPcdList_[Index]) 1086 1087 # print out error information and break the build, if error found 1088 if len(NoDatumTypePcdList) > 0: 1089 NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList) 1090 EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error", 1091 File=self.MetaFile, 1092 ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n" 1093 % NoDatumTypePcdListString) 1094 self._NonDynamicPcdList = self._NonDynaPcdList_ 1095 self._DynamicPcdList = self._DynaPcdList_ 1096 # 1097 # Sort dynamic PCD list to: 1098 # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should 1099 # try to be put header of dynamicd List 1100 # 2) If PCD is HII type, the PCD item should be put after unicode type PCD 1101 # 1102 # The reason of sorting is make sure the unicode string is in double-byte alignment in string table. 1103 # 1104 UnicodePcdArray = [] 1105 HiiPcdArray = [] 1106 OtherPcdArray = [] 1107 VpdPcdDict = {} 1108 VpdFile = VpdInfoFile.VpdInfoFile() 1109 NeedProcessVpdMapFile = False 1110 1111 if (self.Workspace.ArchList[-1] == self.Arch): 1112 for Pcd in self._DynamicPcdList: 1113 # just pick the a value to determine whether is unicode string type 1114 Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]] 1115 Sku.VpdOffset = Sku.VpdOffset.strip() 1116 1117 PcdValue = Sku.DefaultValue 1118 if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"): 1119 # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex 1120 UnicodePcdArray.append(Pcd) 1121 elif len(Sku.VariableName) > 0: 1122 # if found HII type PCD then insert to right of UnicodeIndex 1123 HiiPcdArray.append(Pcd) 1124 else: 1125 OtherPcdArray.append(Pcd) 1126 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]: 1127 VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd 1128 1129 PlatformPcds = self.Platform.Pcds.keys() 1130 PlatformPcds.sort() 1131 # 1132 # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up. 1133 # 1134 for PcdKey in PlatformPcds: 1135 Pcd = self.Platform.Pcds[PcdKey] 1136 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \ 1137 PcdKey in VpdPcdDict: 1138 Pcd = VpdPcdDict[PcdKey] 1139 for (SkuName,Sku) in Pcd.SkuInfoList.items(): 1140 Sku.VpdOffset = Sku.VpdOffset.strip() 1141 VpdFile.Add(Pcd, Sku.VpdOffset) 1142 # if the offset of a VPD is *, then it need to be fixed up by third party tool. 1143 if not NeedProcessVpdMapFile and Sku.VpdOffset == "*": 1144 NeedProcessVpdMapFile = True 1145 if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '': 1146 EdkLogger.error("Build", FILE_NOT_FOUND, \ 1147 "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.") 1148 1149 1150 # 1151 # Fix the PCDs define in VPD PCD section that never referenced by module. 1152 # An example is PCD for signature usage. 1153 # 1154 for DscPcd in PlatformPcds: 1155 DscPcdEntry = self.Platform.Pcds[DscPcd] 1156 if DscPcdEntry.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]: 1157 if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''): 1158 FoundFlag = False 1159 for VpdPcd in VpdFile._VpdArray.keys(): 1160 # This PCD has been referenced by module 1161 if (VpdPcd.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \ 1162 (VpdPcd.TokenCName == DscPcdEntry.TokenCName): 1163 FoundFlag = True 1164 1165 # Not found, it should be signature 1166 if not FoundFlag : 1167 # just pick the a value to determine whether is unicode string type 1168 for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items(): 1169 Sku.VpdOffset = Sku.VpdOffset.strip() 1170 1171 # Need to iterate DEC pcd information to get the value & datumtype 1172 for eachDec in self.PackageList: 1173 for DecPcd in eachDec.Pcds: 1174 DecPcdEntry = eachDec.Pcds[DecPcd] 1175 if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \ 1176 (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName): 1177 # Print warning message to let the developer make a determine. 1178 EdkLogger.warn("build", "Unreferenced vpd pcd used!", 1179 File=self.MetaFile, \ 1180 ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \ 1181 %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path)) 1182 1183 DscPcdEntry.DatumType = DecPcdEntry.DatumType 1184 DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue 1185 DscPcdEntry.TokenValue = DecPcdEntry.TokenValue 1186 DscPcdEntry.TokenSpaceGuidValue = eachDec.Guids[DecPcdEntry.TokenSpaceGuidCName] 1187 # Only fix the value while no value provided in DSC file. 1188 if (Sku.DefaultValue == "" or Sku.DefaultValue==None): 1189 DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue 1190 1191 if DscPcdEntry not in self._DynamicPcdList: 1192 self._DynamicPcdList.append(DscPcdEntry) 1193# Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]] 1194 Sku.VpdOffset = Sku.VpdOffset.strip() 1195 PcdValue = Sku.DefaultValue 1196 VpdFile.Add(DscPcdEntry, Sku.VpdOffset) 1197 if not NeedProcessVpdMapFile and Sku.VpdOffset == "*": 1198 NeedProcessVpdMapFile = True 1199 if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"): 1200 UnicodePcdArray.append(DscPcdEntry) 1201 elif len(Sku.VariableName) > 0: 1202 HiiPcdArray.append(DscPcdEntry) 1203 else: 1204 OtherPcdArray.append(DscPcdEntry) 1205 1206 # if the offset of a VPD is *, then it need to be fixed up by third party tool. 1207 1208 1209 1210 if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \ 1211 VpdFile.GetCount() != 0: 1212 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, 1213 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile)) 1214 1215 if VpdFile.GetCount() != 0: 1216 DscTimeStamp = self.Platform.MetaFile.TimeStamp 1217 FvPath = os.path.join(self.BuildDir, "FV") 1218 if not os.path.exists(FvPath): 1219 try: 1220 os.makedirs(FvPath) 1221 except: 1222 EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir) 1223 1224 1225 VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid) 1226 1227 1228 if not os.path.exists(VpdFilePath) or os.path.getmtime(VpdFilePath) < DscTimeStamp: 1229 VpdFile.Write(VpdFilePath) 1230 1231 # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file. 1232 BPDGToolName = None 1233 for ToolDef in self.ToolDefinition.values(): 1234 if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid: 1235 if not ToolDef.has_key("PATH"): 1236 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid) 1237 BPDGToolName = ToolDef["PATH"] 1238 break 1239 # Call third party GUID BPDG tool. 1240 if BPDGToolName != None: 1241 VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath) 1242 else: 1243 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.") 1244 1245 # Process VPD map file generated by third party BPDG tool 1246 if NeedProcessVpdMapFile: 1247 VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid) 1248 if os.path.exists(VpdMapFilePath): 1249 VpdFile.Read(VpdMapFilePath) 1250 1251 # Fixup "*" offset 1252 for Pcd in self._DynamicPcdList: 1253 # just pick the a value to determine whether is unicode string type 1254 i = 0 1255 for (SkuName,Sku) in Pcd.SkuInfoList.items(): 1256 if Sku.VpdOffset == "*": 1257 Sku.VpdOffset = VpdFile.GetOffset(Pcd)[i].strip() 1258 i += 1 1259 else: 1260 EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath) 1261 1262 # Delete the DynamicPcdList At the last time enter into this function 1263 del self._DynamicPcdList[:] 1264 self._DynamicPcdList.extend(UnicodePcdArray) 1265 self._DynamicPcdList.extend(HiiPcdArray) 1266 self._DynamicPcdList.extend(OtherPcdArray) 1267 self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList 1268 1269 ## Return the platform build data object 1270 def _GetPlatform(self): 1271 if self._Platform == None: 1272 self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain] 1273 return self._Platform 1274 1275 ## Return platform name 1276 def _GetName(self): 1277 return self.Platform.PlatformName 1278 1279 ## Return the meta file GUID 1280 def _GetGuid(self): 1281 return self.Platform.Guid 1282 1283 ## Return the platform version 1284 def _GetVersion(self): 1285 return self.Platform.Version 1286 1287 ## Return the FDF file name 1288 def _GetFdfFile(self): 1289 if self._FdfFile == None: 1290 if self.Workspace.FdfFile != "": 1291 self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile) 1292 else: 1293 self._FdfFile = '' 1294 return self._FdfFile 1295 1296 ## Return the build output directory platform specifies 1297 def _GetOutputDir(self): 1298 return self.Platform.OutputDirectory 1299 1300 ## Return the directory to store all intermediate and final files built 1301 def _GetBuildDir(self): 1302 if self._BuildDir == None: 1303 if os.path.isabs(self.OutputDir): 1304 self._BuildDir = path.join( 1305 path.abspath(self.OutputDir), 1306 self.BuildTarget + "_" + self.ToolChain, 1307 ) 1308 else: 1309 self._BuildDir = path.join( 1310 self.WorkspaceDir, 1311 self.OutputDir, 1312 self.BuildTarget + "_" + self.ToolChain, 1313 ) 1314 return self._BuildDir 1315 1316 ## Return directory of platform makefile 1317 # 1318 # @retval string Makefile directory 1319 # 1320 def _GetMakeFileDir(self): 1321 if self._MakeFileDir == None: 1322 self._MakeFileDir = path.join(self.BuildDir, self.Arch) 1323 return self._MakeFileDir 1324 1325 ## Return build command string 1326 # 1327 # @retval string Build command string 1328 # 1329 def _GetBuildCommand(self): 1330 if self._BuildCommand == None: 1331 self._BuildCommand = [] 1332 if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]: 1333 self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"]) 1334 if "FLAGS" in self.ToolDefinition["MAKE"]: 1335 NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip() 1336 if NewOption != '': 1337 self._BuildCommand += SplitOption(NewOption) 1338 return self._BuildCommand 1339 1340 ## Get tool chain definition 1341 # 1342 # Get each tool defition for given tool chain from tools_def.txt and platform 1343 # 1344 def _GetToolDefinition(self): 1345 if self._ToolDefinitions == None: 1346 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary 1347 if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase: 1348 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration", 1349 ExtraData="[%s]" % self.MetaFile) 1350 self._ToolDefinitions = {} 1351 DllPathList = set() 1352 for Def in ToolDefinition: 1353 Target, Tag, Arch, Tool, Attr = Def.split("_") 1354 if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch: 1355 continue 1356 1357 Value = ToolDefinition[Def] 1358 # don't record the DLL 1359 if Attr == "DLL": 1360 DllPathList.add(Value) 1361 continue 1362 1363 if Tool not in self._ToolDefinitions: 1364 self._ToolDefinitions[Tool] = {} 1365 self._ToolDefinitions[Tool][Attr] = Value 1366 1367 ToolsDef = '' 1368 MakePath = '' 1369 if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions: 1370 if "FLAGS" not in self._ToolDefinitions["MAKE"]: 1371 self._ToolDefinitions["MAKE"]["FLAGS"] = "" 1372 self._ToolDefinitions["MAKE"]["FLAGS"] += " -s" 1373 MakeFlags = '' 1374 for Tool in self._ToolDefinitions: 1375 for Attr in self._ToolDefinitions[Tool]: 1376 Value = self._ToolDefinitions[Tool][Attr] 1377 if Tool in self.BuildOption and Attr in self.BuildOption[Tool]: 1378 # check if override is indicated 1379 if self.BuildOption[Tool][Attr].startswith('='): 1380 Value = self.BuildOption[Tool][Attr][1:] 1381 else: 1382 Value += " " + self.BuildOption[Tool][Attr] 1383 1384 if Attr == "PATH": 1385 # Don't put MAKE definition in the file 1386 if Tool == "MAKE": 1387 MakePath = Value 1388 else: 1389 ToolsDef += "%s = %s\n" % (Tool, Value) 1390 elif Attr != "DLL": 1391 # Don't put MAKE definition in the file 1392 if Tool == "MAKE": 1393 if Attr == "FLAGS": 1394 MakeFlags = Value 1395 else: 1396 ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value) 1397 ToolsDef += "\n" 1398 1399 SaveFileOnChange(self.ToolDefinitionFile, ToolsDef) 1400 for DllPath in DllPathList: 1401 os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"] 1402 os.environ["MAKE_FLAGS"] = MakeFlags 1403 1404 return self._ToolDefinitions 1405 1406 ## Return the paths of tools 1407 def _GetToolDefFile(self): 1408 if self._ToolDefFile == None: 1409 self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch) 1410 return self._ToolDefFile 1411 1412 ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'. 1413 def _GetToolChainFamily(self): 1414 if self._ToolChainFamily == None: 1415 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase 1416 if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \ 1417 or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \ 1418 or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]: 1419 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \ 1420 % self.ToolChain) 1421 self._ToolChainFamily = "MSFT" 1422 else: 1423 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain] 1424 return self._ToolChainFamily 1425 1426 def _GetBuildRuleFamily(self): 1427 if self._BuildRuleFamily == None: 1428 ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase 1429 if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \ 1430 or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \ 1431 or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]: 1432 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \ 1433 % self.ToolChain) 1434 self._BuildRuleFamily = "MSFT" 1435 else: 1436 self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain] 1437 return self._BuildRuleFamily 1438 1439 ## Return the build options specific for all modules in this platform 1440 def _GetBuildOptions(self): 1441 if self._BuildOption == None: 1442 self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions) 1443 return self._BuildOption 1444 1445 ## Return the build options specific for EDK modules in this platform 1446 def _GetEdkBuildOptions(self): 1447 if self._EdkBuildOption == None: 1448 self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME) 1449 return self._EdkBuildOption 1450 1451 ## Return the build options specific for EDKII modules in this platform 1452 def _GetEdkIIBuildOptions(self): 1453 if self._EdkIIBuildOption == None: 1454 self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME) 1455 return self._EdkIIBuildOption 1456 1457 ## Parse build_rule.txt in Conf Directory. 1458 # 1459 # @retval BuildRule object 1460 # 1461 def _GetBuildRule(self): 1462 if self._BuildRule == None: 1463 BuildRuleFile = None 1464 if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary: 1465 BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF] 1466 if BuildRuleFile in [None, '']: 1467 BuildRuleFile = gDefaultBuildRuleFile 1468 self._BuildRule = BuildRule(BuildRuleFile) 1469 if self._BuildRule._FileVersion == "": 1470 self._BuildRule._FileVersion = AutoGenReqBuildRuleVerNum 1471 else: 1472 if self._BuildRule._FileVersion < AutoGenReqBuildRuleVerNum : 1473 # If Build Rule's version is less than the version number required by the tools, halting the build. 1474 EdkLogger.error("build", AUTOGEN_ERROR, 1475 ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\ 1476 % (self._BuildRule._FileVersion, AutoGenReqBuildRuleVerNum)) 1477 1478 return self._BuildRule 1479 1480 ## Summarize the packages used by modules in this platform 1481 def _GetPackageList(self): 1482 if self._PackageList == None: 1483 self._PackageList = set() 1484 for La in self.LibraryAutoGenList: 1485 self._PackageList.update(La.DependentPackageList) 1486 for Ma in self.ModuleAutoGenList: 1487 self._PackageList.update(Ma.DependentPackageList) 1488 #Collect package set information from INF of FDF 1489 PkgSet = set() 1490 for ModuleFile in self._AsBuildModuleList: 1491 if ModuleFile in self.Platform.Modules: 1492 continue 1493 ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain] 1494 PkgSet.update(ModuleData.Packages) 1495 self._PackageList = list(self._PackageList) + list (PkgSet) 1496 return self._PackageList 1497 1498 def _GetNonDynamicPcdDict(self): 1499 if self._NonDynamicPcdDict: 1500 return self._NonDynamicPcdDict 1501 for Pcd in self.NonDynamicPcdList: 1502 self._NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)] = Pcd 1503 return self._NonDynamicPcdDict 1504 1505 ## Get list of non-dynamic PCDs 1506 def _GetNonDynamicPcdList(self): 1507 if self._NonDynamicPcdList == None: 1508 self.CollectPlatformDynamicPcds() 1509 return self._NonDynamicPcdList 1510 1511 ## Get list of dynamic PCDs 1512 def _GetDynamicPcdList(self): 1513 if self._DynamicPcdList == None: 1514 self.CollectPlatformDynamicPcds() 1515 return self._DynamicPcdList 1516 1517 ## Generate Token Number for all PCD 1518 def _GetPcdTokenNumbers(self): 1519 if self._PcdTokenNumber == None: 1520 self._PcdTokenNumber = sdict() 1521 TokenNumber = 1 1522 # 1523 # Make the Dynamic and DynamicEx PCD use within different TokenNumber area. 1524 # Such as: 1525 # 1526 # Dynamic PCD: 1527 # TokenNumber 0 ~ 10 1528 # DynamicEx PCD: 1529 # TokeNumber 11 ~ 20 1530 # 1531 for Pcd in self.DynamicPcdList: 1532 if Pcd.Phase == "PEI": 1533 if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]: 1534 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber)) 1535 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber 1536 TokenNumber += 1 1537 1538 for Pcd in self.DynamicPcdList: 1539 if Pcd.Phase == "PEI": 1540 if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]: 1541 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber)) 1542 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber 1543 TokenNumber += 1 1544 1545 for Pcd in self.DynamicPcdList: 1546 if Pcd.Phase == "DXE": 1547 if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]: 1548 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber)) 1549 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber 1550 TokenNumber += 1 1551 1552 for Pcd in self.DynamicPcdList: 1553 if Pcd.Phase == "DXE": 1554 if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]: 1555 EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber)) 1556 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber 1557 TokenNumber += 1 1558 1559 for Pcd in self.NonDynamicPcdList: 1560 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber 1561 TokenNumber += 1 1562 return self._PcdTokenNumber 1563 1564 ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform 1565 def _GetAutoGenObjectList(self): 1566 self._ModuleAutoGenList = [] 1567 self._LibraryAutoGenList = [] 1568 for ModuleFile in self.Platform.Modules: 1569 Ma = ModuleAutoGen( 1570 self.Workspace, 1571 ModuleFile, 1572 self.BuildTarget, 1573 self.ToolChain, 1574 self.Arch, 1575 self.MetaFile 1576 ) 1577 if Ma not in self._ModuleAutoGenList: 1578 self._ModuleAutoGenList.append(Ma) 1579 for La in Ma.LibraryAutoGenList: 1580 if La not in self._LibraryAutoGenList: 1581 self._LibraryAutoGenList.append(La) 1582 if Ma not in La._ReferenceModules: 1583 La._ReferenceModules.append(Ma) 1584 1585 ## Summarize ModuleAutoGen objects of all modules to be built for this platform 1586 def _GetModuleAutoGenList(self): 1587 if self._ModuleAutoGenList == None: 1588 self._GetAutoGenObjectList() 1589 return self._ModuleAutoGenList 1590 1591 ## Summarize ModuleAutoGen objects of all libraries to be built for this platform 1592 def _GetLibraryAutoGenList(self): 1593 if self._LibraryAutoGenList == None: 1594 self._GetAutoGenObjectList() 1595 return self._LibraryAutoGenList 1596 1597 ## Test if a module is supported by the platform 1598 # 1599 # An error will be raised directly if the module or its arch is not supported 1600 # by the platform or current configuration 1601 # 1602 def ValidModule(self, Module): 1603 return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances \ 1604 or Module in self._AsBuildModuleList 1605 1606 ## Resolve the library classes in a module to library instances 1607 # 1608 # This method will not only resolve library classes but also sort the library 1609 # instances according to the dependency-ship. 1610 # 1611 # @param Module The module from which the library classes will be resolved 1612 # 1613 # @retval library_list List of library instances sorted 1614 # 1615 def ApplyLibraryInstance(self, Module): 1616 ModuleType = Module.ModuleType 1617 1618 # for overridding library instances with module specific setting 1619 PlatformModule = self.Platform.Modules[str(Module)] 1620 1621 # add forced library instances (specified under LibraryClasses sections) 1622 # 1623 # If a module has a MODULE_TYPE of USER_DEFINED, 1624 # do not link in NULL library class instances from the global [LibraryClasses.*] sections. 1625 # 1626 if Module.ModuleType != SUP_MODULE_USER_DEFINED: 1627 for LibraryClass in self.Platform.LibraryClasses.GetKeys(): 1628 if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]: 1629 Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType] 1630 1631 # add forced library instances (specified in module overrides) 1632 for LibraryClass in PlatformModule.LibraryClasses: 1633 if LibraryClass.startswith("NULL"): 1634 Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass] 1635 1636 # EdkII module 1637 LibraryConsumerList = [Module] 1638 Constructor = [] 1639 ConsumedByList = sdict() 1640 LibraryInstance = sdict() 1641 1642 EdkLogger.verbose("") 1643 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch)) 1644 while len(LibraryConsumerList) > 0: 1645 M = LibraryConsumerList.pop() 1646 for LibraryClassName in M.LibraryClasses: 1647 if LibraryClassName not in LibraryInstance: 1648 # override library instance for this module 1649 if LibraryClassName in PlatformModule.LibraryClasses: 1650 LibraryPath = PlatformModule.LibraryClasses[LibraryClassName] 1651 else: 1652 LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType] 1653 if LibraryPath == None or LibraryPath == "": 1654 LibraryPath = M.LibraryClasses[LibraryClassName] 1655 if LibraryPath == None or LibraryPath == "": 1656 EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, 1657 "Instance of library class [%s] is not found" % LibraryClassName, 1658 File=self.MetaFile, 1659 ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module))) 1660 1661 LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain] 1662 # for those forced library instance (NULL library), add a fake library class 1663 if LibraryClassName.startswith("NULL"): 1664 LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType])) 1665 elif LibraryModule.LibraryClass == None \ 1666 or len(LibraryModule.LibraryClass) == 0 \ 1667 or (ModuleType != 'USER_DEFINED' 1668 and ModuleType not in LibraryModule.LibraryClass[0].SupModList): 1669 # only USER_DEFINED can link against any library instance despite of its SupModList 1670 EdkLogger.error("build", OPTION_MISSING, 1671 "Module type [%s] is not supported by library instance [%s]" \ 1672 % (ModuleType, LibraryPath), File=self.MetaFile, 1673 ExtraData="consumed by [%s]" % str(Module)) 1674 1675 LibraryInstance[LibraryClassName] = LibraryModule 1676 LibraryConsumerList.append(LibraryModule) 1677 EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule)) 1678 else: 1679 LibraryModule = LibraryInstance[LibraryClassName] 1680 1681 if LibraryModule == None: 1682 continue 1683 1684 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor: 1685 Constructor.append(LibraryModule) 1686 1687 if LibraryModule not in ConsumedByList: 1688 ConsumedByList[LibraryModule] = [] 1689 # don't add current module itself to consumer list 1690 if M != Module: 1691 if M in ConsumedByList[LibraryModule]: 1692 continue 1693 ConsumedByList[LibraryModule].append(M) 1694 # 1695 # Initialize the sorted output list to the empty set 1696 # 1697 SortedLibraryList = [] 1698 # 1699 # Q <- Set of all nodes with no incoming edges 1700 # 1701 LibraryList = [] #LibraryInstance.values() 1702 Q = [] 1703 for LibraryClassName in LibraryInstance: 1704 M = LibraryInstance[LibraryClassName] 1705 LibraryList.append(M) 1706 if ConsumedByList[M] == []: 1707 Q.append(M) 1708 1709 # 1710 # start the DAG algorithm 1711 # 1712 while True: 1713 EdgeRemoved = True 1714 while Q == [] and EdgeRemoved: 1715 EdgeRemoved = False 1716 # for each node Item with a Constructor 1717 for Item in LibraryList: 1718 if Item not in Constructor: 1719 continue 1720 # for each Node without a constructor with an edge e from Item to Node 1721 for Node in ConsumedByList[Item]: 1722 if Node in Constructor: 1723 continue 1724 # remove edge e from the graph if Node has no constructor 1725 ConsumedByList[Item].remove(Node) 1726 EdgeRemoved = True 1727 if ConsumedByList[Item] == []: 1728 # insert Item into Q 1729 Q.insert(0, Item) 1730 break 1731 if Q != []: 1732 break 1733 # DAG is done if there's no more incoming edge for all nodes 1734 if Q == []: 1735 break 1736 1737 # remove node from Q 1738 Node = Q.pop() 1739 # output Node 1740 SortedLibraryList.append(Node) 1741 1742 # for each node Item with an edge e from Node to Item do 1743 for Item in LibraryList: 1744 if Node not in ConsumedByList[Item]: 1745 continue 1746 # remove edge e from the graph 1747 ConsumedByList[Item].remove(Node) 1748 1749 if ConsumedByList[Item] != []: 1750 continue 1751 # insert Item into Q, if Item has no other incoming edges 1752 Q.insert(0, Item) 1753 1754 # 1755 # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle 1756 # 1757 for Item in LibraryList: 1758 if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1: 1759 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]]) 1760 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item), 1761 ExtraData=ErrorMessage, File=self.MetaFile) 1762 if Item not in SortedLibraryList: 1763 SortedLibraryList.append(Item) 1764 1765 # 1766 # Build the list of constructor and destructir names 1767 # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order 1768 # 1769 SortedLibraryList.reverse() 1770 return SortedLibraryList 1771 1772 1773 ## Override PCD setting (type, value, ...) 1774 # 1775 # @param ToPcd The PCD to be overrided 1776 # @param FromPcd The PCD overrideing from 1777 # 1778 def _OverridePcd(self, ToPcd, FromPcd, Module=""): 1779 # 1780 # in case there's PCDs coming from FDF file, which have no type given. 1781 # at this point, ToPcd.Type has the type found from dependent 1782 # package 1783 # 1784 if FromPcd != None: 1785 if ToPcd.Pending and FromPcd.Type not in [None, '']: 1786 ToPcd.Type = FromPcd.Type 1787 elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\ 1788 and (ToPcd.Type != FromPcd.Type) and (ToPcd.Type in FromPcd.Type): 1789 if ToPcd.Type.strip() == "DynamicEx": 1790 ToPcd.Type = FromPcd.Type 1791 elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \ 1792 and ToPcd.Type != FromPcd.Type: 1793 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type", 1794 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\ 1795 % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, 1796 ToPcd.Type, Module, FromPcd.Type), 1797 File=self.MetaFile) 1798 1799 if FromPcd.MaxDatumSize not in [None, '']: 1800 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize 1801 if FromPcd.DefaultValue not in [None, '']: 1802 ToPcd.DefaultValue = FromPcd.DefaultValue 1803 if FromPcd.TokenValue not in [None, '']: 1804 ToPcd.TokenValue = FromPcd.TokenValue 1805 if FromPcd.MaxDatumSize not in [None, '']: 1806 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize 1807 if FromPcd.DatumType not in [None, '']: 1808 ToPcd.DatumType = FromPcd.DatumType 1809 if FromPcd.SkuInfoList not in [None, '', []]: 1810 ToPcd.SkuInfoList = FromPcd.SkuInfoList 1811 1812 # check the validation of datum 1813 IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue) 1814 if not IsValid: 1815 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile, 1816 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName)) 1817 ToPcd.validateranges = FromPcd.validateranges 1818 ToPcd.validlists = FromPcd.validlists 1819 ToPcd.expressions = FromPcd.expressions 1820 1821 if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]: 1822 EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \ 1823 % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName)) 1824 Value = ToPcd.DefaultValue 1825 if Value in [None, '']: 1826 ToPcd.MaxDatumSize = '1' 1827 elif Value[0] == 'L': 1828 ToPcd.MaxDatumSize = str((len(Value) - 2) * 2) 1829 elif Value[0] == '{': 1830 ToPcd.MaxDatumSize = str(len(Value.split(','))) 1831 else: 1832 ToPcd.MaxDatumSize = str(len(Value) - 1) 1833 1834 # apply default SKU for dynamic PCDS if specified one is not available 1835 if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \ 1836 and ToPcd.SkuInfoList in [None, {}, '']: 1837 if self.Platform.SkuName in self.Platform.SkuIds: 1838 SkuName = self.Platform.SkuName 1839 else: 1840 SkuName = 'DEFAULT' 1841 ToPcd.SkuInfoList = { 1842 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue) 1843 } 1844 1845 ## Apply PCD setting defined platform to a module 1846 # 1847 # @param Module The module from which the PCD setting will be overrided 1848 # 1849 # @retval PCD_list The list PCDs with settings from platform 1850 # 1851 def ApplyPcdSetting(self, Module, Pcds): 1852 # for each PCD in module 1853 for Name, Guid in Pcds: 1854 PcdInModule = Pcds[Name, Guid] 1855 # find out the PCD setting in platform 1856 if (Name, Guid) in self.Platform.Pcds: 1857 PcdInPlatform = self.Platform.Pcds[Name, Guid] 1858 else: 1859 PcdInPlatform = None 1860 # then override the settings if any 1861 self._OverridePcd(PcdInModule, PcdInPlatform, Module) 1862 # resolve the VariableGuid value 1863 for SkuId in PcdInModule.SkuInfoList: 1864 Sku = PcdInModule.SkuInfoList[SkuId] 1865 if Sku.VariableGuid == '': continue 1866 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList) 1867 if Sku.VariableGuidValue == None: 1868 PackageList = "\n\t".join([str(P) for P in self.PackageList]) 1869 EdkLogger.error( 1870 'build', 1871 RESOURCE_NOT_AVAILABLE, 1872 "Value of GUID [%s] is not found in" % Sku.VariableGuid, 1873 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \ 1874 % (Guid, Name, str(Module)), 1875 File=self.MetaFile 1876 ) 1877 1878 # override PCD settings with module specific setting 1879 if Module in self.Platform.Modules: 1880 PlatformModule = self.Platform.Modules[str(Module)] 1881 for Key in PlatformModule.Pcds: 1882 if Key in Pcds: 1883 self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module) 1884 return Pcds.values() 1885 1886 ## Resolve library names to library modules 1887 # 1888 # (for Edk.x modules) 1889 # 1890 # @param Module The module from which the library names will be resolved 1891 # 1892 # @retval library_list The list of library modules 1893 # 1894 def ResolveLibraryReference(self, Module): 1895 EdkLogger.verbose("") 1896 EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch)) 1897 LibraryConsumerList = [Module] 1898 1899 # "CompilerStub" is a must for Edk modules 1900 if Module.Libraries: 1901 Module.Libraries.append("CompilerStub") 1902 LibraryList = [] 1903 while len(LibraryConsumerList) > 0: 1904 M = LibraryConsumerList.pop() 1905 for LibraryName in M.Libraries: 1906 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:'] 1907 if Library == None: 1908 for Key in self.Platform.LibraryClasses.data.keys(): 1909 if LibraryName.upper() == Key.upper(): 1910 Library = self.Platform.LibraryClasses[Key, ':dummy:'] 1911 break 1912 if Library == None: 1913 EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M), 1914 ExtraData="\t%s [%s]" % (str(Module), self.Arch)) 1915 continue 1916 1917 if Library not in LibraryList: 1918 LibraryList.append(Library) 1919 LibraryConsumerList.append(Library) 1920 EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library))) 1921 return LibraryList 1922 1923 ## Calculate the priority value of the build option 1924 # 1925 # @param Key Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 1926 # 1927 # @retval Value Priority value based on the priority list. 1928 # 1929 def CalculatePriorityValue(self, Key): 1930 Target, ToolChain, Arch, CommandType, Attr = Key.split('_') 1931 PriorityValue = 0x11111 1932 if Target == "*": 1933 PriorityValue &= 0x01111 1934 if ToolChain == "*": 1935 PriorityValue &= 0x10111 1936 if Arch == "*": 1937 PriorityValue &= 0x11011 1938 if CommandType == "*": 1939 PriorityValue &= 0x11101 1940 if Attr == "*": 1941 PriorityValue &= 0x11110 1942 1943 return self.PrioList["0x%0.5x" % PriorityValue] 1944 1945 1946 ## Expand * in build option key 1947 # 1948 # @param Options Options to be expanded 1949 # 1950 # @retval options Options expanded 1951 # 1952 def _ExpandBuildOption(self, Options, ModuleStyle=None): 1953 BuildOptions = {} 1954 FamilyMatch = False 1955 FamilyIsNull = True 1956 1957 OverrideList = {} 1958 # 1959 # Construct a list contain the build options which need override. 1960 # 1961 for Key in Options: 1962 # 1963 # Key[0] -- tool family 1964 # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE 1965 # 1966 if (Key[0] == self.BuildRuleFamily and 1967 (ModuleStyle == None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))): 1968 Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_') 1969 if Target == self.BuildTarget or Target == "*": 1970 if ToolChain == self.ToolChain or ToolChain == "*": 1971 if Arch == self.Arch or Arch == "*": 1972 if Options[Key].startswith("="): 1973 if OverrideList.get(Key[1]) != None: 1974 OverrideList.pop(Key[1]) 1975 OverrideList[Key[1]] = Options[Key] 1976 1977 # 1978 # Use the highest priority value. 1979 # 1980 if (len(OverrideList) >= 2): 1981 KeyList = OverrideList.keys() 1982 for Index in range(len(KeyList)): 1983 NowKey = KeyList[Index] 1984 Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_") 1985 for Index1 in range(len(KeyList) - Index - 1): 1986 NextKey = KeyList[Index1 + Index + 1] 1987 # 1988 # Compare two Key, if one is included by another, choose the higher priority one 1989 # 1990 Target2, ToolChain2, Arch2, CommandType2, Attr2 = NextKey.split("_") 1991 if Target1 == Target2 or Target1 == "*" or Target2 == "*": 1992 if ToolChain1 == ToolChain2 or ToolChain1 == "*" or ToolChain2 == "*": 1993 if Arch1 == Arch2 or Arch1 == "*" or Arch2 == "*": 1994 if CommandType1 == CommandType2 or CommandType1 == "*" or CommandType2 == "*": 1995 if Attr1 == Attr2 or Attr1 == "*" or Attr2 == "*": 1996 if self.CalculatePriorityValue(NowKey) > self.CalculatePriorityValue(NextKey): 1997 if Options.get((self.BuildRuleFamily, NextKey)) != None: 1998 Options.pop((self.BuildRuleFamily, NextKey)) 1999 else: 2000 if Options.get((self.BuildRuleFamily, NowKey)) != None: 2001 Options.pop((self.BuildRuleFamily, NowKey)) 2002 2003 for Key in Options: 2004 if ModuleStyle != None and len (Key) > 2: 2005 # Check Module style is EDK or EDKII. 2006 # Only append build option for the matched style module. 2007 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME: 2008 continue 2009 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME: 2010 continue 2011 Family = Key[0] 2012 Target, Tag, Arch, Tool, Attr = Key[1].split("_") 2013 # if tool chain family doesn't match, skip it 2014 if Tool in self.ToolDefinition and Family != "": 2015 FamilyIsNull = False 2016 if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "": 2017 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]: 2018 continue 2019 elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]: 2020 continue 2021 FamilyMatch = True 2022 # expand any wildcard 2023 if Target == "*" or Target == self.BuildTarget: 2024 if Tag == "*" or Tag == self.ToolChain: 2025 if Arch == "*" or Arch == self.Arch: 2026 if Tool not in BuildOptions: 2027 BuildOptions[Tool] = {} 2028 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='): 2029 BuildOptions[Tool][Attr] = Options[Key] 2030 else: 2031 # append options for the same tool 2032 BuildOptions[Tool][Attr] += " " + Options[Key] 2033 # Build Option Family has been checked, which need't to be checked again for family. 2034 if FamilyMatch or FamilyIsNull: 2035 return BuildOptions 2036 2037 for Key in Options: 2038 if ModuleStyle != None and len (Key) > 2: 2039 # Check Module style is EDK or EDKII. 2040 # Only append build option for the matched style module. 2041 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME: 2042 continue 2043 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME: 2044 continue 2045 Family = Key[0] 2046 Target, Tag, Arch, Tool, Attr = Key[1].split("_") 2047 # if tool chain family doesn't match, skip it 2048 if Tool not in self.ToolDefinition or Family == "": 2049 continue 2050 # option has been added before 2051 if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]: 2052 continue 2053 2054 # expand any wildcard 2055 if Target == "*" or Target == self.BuildTarget: 2056 if Tag == "*" or Tag == self.ToolChain: 2057 if Arch == "*" or Arch == self.Arch: 2058 if Tool not in BuildOptions: 2059 BuildOptions[Tool] = {} 2060 if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='): 2061 BuildOptions[Tool][Attr] = Options[Key] 2062 else: 2063 # append options for the same tool 2064 BuildOptions[Tool][Attr] += " " + Options[Key] 2065 return BuildOptions 2066 2067 ## Append build options in platform to a module 2068 # 2069 # @param Module The module to which the build options will be appened 2070 # 2071 # @retval options The options appended with build options in platform 2072 # 2073 def ApplyBuildOption(self, Module): 2074 # Get the different options for the different style module 2075 if Module.AutoGenVersion < 0x00010005: 2076 PlatformOptions = self.EdkBuildOption 2077 ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDK_NAME, Module.ModuleType) 2078 else: 2079 PlatformOptions = self.EdkIIBuildOption 2080 ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDKII_NAME, Module.ModuleType) 2081 ModuleTypeOptions = self._ExpandBuildOption(ModuleTypeOptions) 2082 ModuleOptions = self._ExpandBuildOption(Module.BuildOptions) 2083 if Module in self.Platform.Modules: 2084 PlatformModule = self.Platform.Modules[str(Module)] 2085 PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions) 2086 else: 2087 PlatformModuleOptions = {} 2088 2089 BuildRuleOrder = None 2090 for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]: 2091 for Tool in Options: 2092 for Attr in Options[Tool]: 2093 if Attr == TAB_TOD_DEFINES_BUILDRULEORDER: 2094 BuildRuleOrder = Options[Tool][Attr] 2095 2096 AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() + 2097 PlatformModuleOptions.keys() + ModuleTypeOptions.keys() + 2098 self.ToolDefinition.keys()) 2099 BuildOptions = {} 2100 for Tool in AllTools: 2101 if Tool not in BuildOptions: 2102 BuildOptions[Tool] = {} 2103 2104 for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]: 2105 if Tool not in Options: 2106 continue 2107 for Attr in Options[Tool]: 2108 Value = Options[Tool][Attr] 2109 # 2110 # Do not generate it in Makefile 2111 # 2112 if Attr == TAB_TOD_DEFINES_BUILDRULEORDER: 2113 continue 2114 if Attr not in BuildOptions[Tool]: 2115 BuildOptions[Tool][Attr] = "" 2116 # check if override is indicated 2117 if Value.startswith('='): 2118 ToolPath = Value[1:] 2119 ToolPath = mws.handleWsMacro(ToolPath) 2120 BuildOptions[Tool][Attr] = ToolPath 2121 else: 2122 Value = mws.handleWsMacro(Value) 2123 BuildOptions[Tool][Attr] += " " + Value 2124 if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None: 2125 # 2126 # Override UNI flag only for EDK module. 2127 # 2128 if 'BUILD' not in BuildOptions: 2129 BuildOptions['BUILD'] = {} 2130 BuildOptions['BUILD']['FLAGS'] = self.Workspace.UniFlag 2131 return BuildOptions, BuildRuleOrder 2132 2133 Platform = property(_GetPlatform) 2134 Name = property(_GetName) 2135 Guid = property(_GetGuid) 2136 Version = property(_GetVersion) 2137 2138 OutputDir = property(_GetOutputDir) 2139 BuildDir = property(_GetBuildDir) 2140 MakeFileDir = property(_GetMakeFileDir) 2141 FdfFile = property(_GetFdfFile) 2142 2143 PcdTokenNumber = property(_GetPcdTokenNumbers) # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber 2144 DynamicPcdList = property(_GetDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] 2145 NonDynamicPcdList = property(_GetNonDynamicPcdList) # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...] 2146 NonDynamicPcdDict = property(_GetNonDynamicPcdDict) 2147 PackageList = property(_GetPackageList) 2148 2149 ToolDefinition = property(_GetToolDefinition) # toolcode : tool path 2150 ToolDefinitionFile = property(_GetToolDefFile) # toolcode : lib path 2151 ToolChainFamily = property(_GetToolChainFamily) 2152 BuildRuleFamily = property(_GetBuildRuleFamily) 2153 BuildOption = property(_GetBuildOptions) # toolcode : option 2154 EdkBuildOption = property(_GetEdkBuildOptions) # edktoolcode : option 2155 EdkIIBuildOption = property(_GetEdkIIBuildOptions) # edkiitoolcode : option 2156 2157 BuildCommand = property(_GetBuildCommand) 2158 BuildRule = property(_GetBuildRule) 2159 ModuleAutoGenList = property(_GetModuleAutoGenList) 2160 LibraryAutoGenList = property(_GetLibraryAutoGenList) 2161 GenFdsCommand = property(_GenFdsCommand) 2162 2163## ModuleAutoGen class 2164# 2165# This class encapsules the AutoGen behaviors for the build tools. In addition to 2166# the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according 2167# to the [depex] section in module's inf file. 2168# 2169class ModuleAutoGen(AutoGen): 2170 ## The real constructor of ModuleAutoGen 2171 # 2172 # This method is not supposed to be called by users of ModuleAutoGen. It's 2173 # only used by factory method __new__() to do real initialization work for an 2174 # object of ModuleAutoGen 2175 # 2176 # @param Workspace EdkIIWorkspaceBuild object 2177 # @param ModuleFile The path of module file 2178 # @param Target Build target (DEBUG, RELEASE) 2179 # @param Toolchain Name of tool chain 2180 # @param Arch The arch the module supports 2181 # @param PlatformFile Platform meta-file 2182 # 2183 def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile): 2184 EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch)) 2185 GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target) 2186 2187 self.Workspace = Workspace 2188 self.WorkspaceDir = Workspace.WorkspaceDir 2189 2190 self.MetaFile = ModuleFile 2191 self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch) 2192 # check if this module is employed by active platform 2193 if not self.PlatformInfo.ValidModule(self.MetaFile): 2194 EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \ 2195 % (self.MetaFile, Arch)) 2196 return False 2197 2198 self.SourceDir = self.MetaFile.SubDir 2199 self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir) 2200 2201 self.SourceOverrideDir = None 2202 # use overrided path defined in DSC file 2203 if self.MetaFile.Key in GlobalData.gOverrideDir: 2204 self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key] 2205 2206 self.ToolChain = Toolchain 2207 self.BuildTarget = Target 2208 self.Arch = Arch 2209 self.ToolChainFamily = self.PlatformInfo.ToolChainFamily 2210 self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily 2211 2212 self.IsMakeFileCreated = False 2213 self.IsCodeFileCreated = False 2214 self.IsAsBuiltInfCreated = False 2215 self.DepexGenerated = False 2216 2217 self.BuildDatabase = self.Workspace.BuildDatabase 2218 self.BuildRuleOrder = None 2219 2220 self._Module = None 2221 self._Name = None 2222 self._Guid = None 2223 self._Version = None 2224 self._ModuleType = None 2225 self._ComponentType = None 2226 self._PcdIsDriver = None 2227 self._AutoGenVersion = None 2228 self._LibraryFlag = None 2229 self._CustomMakefile = None 2230 self._Macro = None 2231 2232 self._BuildDir = None 2233 self._OutputDir = None 2234 self._DebugDir = None 2235 self._MakeFileDir = None 2236 2237 self._IncludePathList = None 2238 self._AutoGenFileList = None 2239 self._UnicodeFileList = None 2240 self._SourceFileList = None 2241 self._ObjectFileList = None 2242 self._BinaryFileList = None 2243 2244 self._DependentPackageList = None 2245 self._DependentLibraryList = None 2246 self._LibraryAutoGenList = None 2247 self._DerivedPackageList = None 2248 self._ModulePcdList = None 2249 self._LibraryPcdList = None 2250 self._PcdComments = sdict() 2251 self._GuidList = None 2252 self._GuidsUsedByPcd = None 2253 self._GuidComments = sdict() 2254 self._ProtocolList = None 2255 self._ProtocolComments = sdict() 2256 self._PpiList = None 2257 self._PpiComments = sdict() 2258 self._DepexList = None 2259 self._DepexExpressionList = None 2260 self._BuildOption = None 2261 self._BuildOptionIncPathList = None 2262 self._BuildTargets = None 2263 self._IntroBuildTargetList = None 2264 self._FinalBuildTargetList = None 2265 self._FileTypes = None 2266 self._BuildRules = None 2267 2268 ## The Modules referenced to this Library 2269 # Only Library has this attribute 2270 self._ReferenceModules = [] 2271 2272 ## Store the FixedAtBuild Pcds 2273 # 2274 self._FixedAtBuildPcds = [] 2275 self.ConstPcd = {} 2276 return True 2277 2278 def __repr__(self): 2279 return "%s [%s]" % (self.MetaFile, self.Arch) 2280 2281 # Get FixedAtBuild Pcds of this Module 2282 def _GetFixedAtBuildPcds(self): 2283 if self._FixedAtBuildPcds: 2284 return self._FixedAtBuildPcds 2285 for Pcd in self.ModulePcdList: 2286 if self.IsLibrary: 2287 if not (Pcd.Pending == False and Pcd.Type == "FixedAtBuild"): 2288 continue 2289 elif Pcd.Type != "FixedAtBuild": 2290 continue 2291 if Pcd not in self._FixedAtBuildPcds: 2292 self._FixedAtBuildPcds.append(Pcd) 2293 2294 return self._FixedAtBuildPcds 2295 2296 def _GetUniqueBaseName(self): 2297 BaseName = self.Name 2298 for Module in self.PlatformInfo.ModuleAutoGenList: 2299 if Module.MetaFile == self.MetaFile: 2300 continue 2301 if Module.Name == self.Name: 2302 if uuid.UUID(Module.Guid) == uuid.UUID(self.Guid): 2303 EdkLogger.error("build", FILE_DUPLICATED, 'Modules have same BaseName and FILE_GUID:\n' 2304 ' %s\n %s' % (Module.MetaFile, self.MetaFile)) 2305 BaseName = '%s_%s' % (self.Name, self.Guid) 2306 return BaseName 2307 2308 # Macros could be used in build_rule.txt (also Makefile) 2309 def _GetMacros(self): 2310 if self._Macro == None: 2311 self._Macro = sdict() 2312 self._Macro["WORKSPACE" ] = self.WorkspaceDir 2313 self._Macro["MODULE_NAME" ] = self.Name 2314 self._Macro["MODULE_NAME_GUID" ] = self._GetUniqueBaseName() 2315 self._Macro["MODULE_GUID" ] = self.Guid 2316 self._Macro["MODULE_VERSION" ] = self.Version 2317 self._Macro["MODULE_TYPE" ] = self.ModuleType 2318 self._Macro["MODULE_FILE" ] = str(self.MetaFile) 2319 self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName 2320 self._Macro["MODULE_RELATIVE_DIR" ] = self.SourceDir 2321 self._Macro["MODULE_DIR" ] = self.SourceDir 2322 2323 self._Macro["BASE_NAME" ] = self.Name 2324 2325 self._Macro["ARCH" ] = self.Arch 2326 self._Macro["TOOLCHAIN" ] = self.ToolChain 2327 self._Macro["TOOLCHAIN_TAG" ] = self.ToolChain 2328 self._Macro["TOOL_CHAIN_TAG" ] = self.ToolChain 2329 self._Macro["TARGET" ] = self.BuildTarget 2330 2331 self._Macro["BUILD_DIR" ] = self.PlatformInfo.BuildDir 2332 self._Macro["BIN_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch) 2333 self._Macro["LIB_DIR" ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch) 2334 self._Macro["MODULE_BUILD_DIR" ] = self.BuildDir 2335 self._Macro["OUTPUT_DIR" ] = self.OutputDir 2336 self._Macro["DEBUG_DIR" ] = self.DebugDir 2337 return self._Macro 2338 2339 ## Return the module build data object 2340 def _GetModule(self): 2341 if self._Module == None: 2342 self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain] 2343 return self._Module 2344 2345 ## Return the module name 2346 def _GetBaseName(self): 2347 return self.Module.BaseName 2348 2349 ## Return the module DxsFile if exist 2350 def _GetDxsFile(self): 2351 return self.Module.DxsFile 2352 2353 ## Return the module SourceOverridePath 2354 def _GetSourceOverridePath(self): 2355 return self.Module.SourceOverridePath 2356 2357 ## Return the module meta-file GUID 2358 def _GetGuid(self): 2359 # 2360 # To build same module more than once, the module path with FILE_GUID overridden has 2361 # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path 2362 # in DSC. The overridden GUID can be retrieved from file name 2363 # 2364 if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path): 2365 # 2366 # Length of GUID is 36 2367 # 2368 return os.path.basename(self.MetaFile.Path)[:36] 2369 return self.Module.Guid 2370 2371 ## Return the module version 2372 def _GetVersion(self): 2373 return self.Module.Version 2374 2375 ## Return the module type 2376 def _GetModuleType(self): 2377 return self.Module.ModuleType 2378 2379 ## Return the component type (for Edk.x style of module) 2380 def _GetComponentType(self): 2381 return self.Module.ComponentType 2382 2383 ## Return the build type 2384 def _GetBuildType(self): 2385 return self.Module.BuildType 2386 2387 ## Return the PCD_IS_DRIVER setting 2388 def _GetPcdIsDriver(self): 2389 return self.Module.PcdIsDriver 2390 2391 ## Return the autogen version, i.e. module meta-file version 2392 def _GetAutoGenVersion(self): 2393 return self.Module.AutoGenVersion 2394 2395 ## Check if the module is library or not 2396 def _IsLibrary(self): 2397 if self._LibraryFlag == None: 2398 if self.Module.LibraryClass != None and self.Module.LibraryClass != []: 2399 self._LibraryFlag = True 2400 else: 2401 self._LibraryFlag = False 2402 return self._LibraryFlag 2403 2404 ## Check if the module is binary module or not 2405 def _IsBinaryModule(self): 2406 return self.Module.IsBinaryModule 2407 2408 ## Return the directory to store intermediate files of the module 2409 def _GetBuildDir(self): 2410 if self._BuildDir == None: 2411 self._BuildDir = path.join( 2412 self.PlatformInfo.BuildDir, 2413 self.Arch, 2414 self.SourceDir, 2415 self.MetaFile.BaseName 2416 ) 2417 CreateDirectory(self._BuildDir) 2418 return self._BuildDir 2419 2420 ## Return the directory to store the intermediate object files of the mdoule 2421 def _GetOutputDir(self): 2422 if self._OutputDir == None: 2423 self._OutputDir = path.join(self.BuildDir, "OUTPUT") 2424 CreateDirectory(self._OutputDir) 2425 return self._OutputDir 2426 2427 ## Return the directory to store auto-gened source files of the mdoule 2428 def _GetDebugDir(self): 2429 if self._DebugDir == None: 2430 self._DebugDir = path.join(self.BuildDir, "DEBUG") 2431 CreateDirectory(self._DebugDir) 2432 return self._DebugDir 2433 2434 ## Return the path of custom file 2435 def _GetCustomMakefile(self): 2436 if self._CustomMakefile == None: 2437 self._CustomMakefile = {} 2438 for Type in self.Module.CustomMakefile: 2439 if Type in gMakeTypeMap: 2440 MakeType = gMakeTypeMap[Type] 2441 else: 2442 MakeType = 'nmake' 2443 if self.SourceOverrideDir != None: 2444 File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type]) 2445 if not os.path.exists(File): 2446 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type]) 2447 else: 2448 File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type]) 2449 self._CustomMakefile[MakeType] = File 2450 return self._CustomMakefile 2451 2452 ## Return the directory of the makefile 2453 # 2454 # @retval string The directory string of module's makefile 2455 # 2456 def _GetMakeFileDir(self): 2457 return self.BuildDir 2458 2459 ## Return build command string 2460 # 2461 # @retval string Build command string 2462 # 2463 def _GetBuildCommand(self): 2464 return self.PlatformInfo.BuildCommand 2465 2466 ## Get object list of all packages the module and its dependent libraries belong to 2467 # 2468 # @retval list The list of package object 2469 # 2470 def _GetDerivedPackageList(self): 2471 PackageList = [] 2472 for M in [self.Module] + self.DependentLibraryList: 2473 for Package in M.Packages: 2474 if Package in PackageList: 2475 continue 2476 PackageList.append(Package) 2477 return PackageList 2478 2479 ## Get the depex string 2480 # 2481 # @return : a string contain all depex expresion. 2482 def _GetDepexExpresionString(self): 2483 DepexStr = '' 2484 DepexList = [] 2485 ## DPX_SOURCE IN Define section. 2486 if self.Module.DxsFile: 2487 return DepexStr 2488 for M in [self.Module] + self.DependentLibraryList: 2489 Filename = M.MetaFile.Path 2490 InfObj = InfSectionParser.InfSectionParser(Filename) 2491 DepexExpresionList = InfObj.GetDepexExpresionList() 2492 for DepexExpresion in DepexExpresionList: 2493 for key in DepexExpresion.keys(): 2494 Arch, ModuleType = key 2495 # the type of build module is USER_DEFINED. 2496 # All different DEPEX section tags would be copied into the As Built INF file 2497 # and there would be separate DEPEX section tags 2498 if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED: 2499 if (Arch.upper() == self.Arch.upper()) and (ModuleType.upper() != TAB_ARCH_COMMON): 2500 DepexList.append({(Arch, ModuleType): DepexExpresion[key][:]}) 2501 else: 2502 if Arch.upper() == TAB_ARCH_COMMON or \ 2503 (Arch.upper() == self.Arch.upper() and \ 2504 ModuleType.upper() in [TAB_ARCH_COMMON, self.ModuleType.upper()]): 2505 DepexList.append({(Arch, ModuleType): DepexExpresion[key][:]}) 2506 2507 #the type of build module is USER_DEFINED. 2508 if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED: 2509 for Depex in DepexList: 2510 for key in Depex.keys(): 2511 DepexStr += '[Depex.%s.%s]\n' % key 2512 DepexStr += '\n'.join(['# '+ val for val in Depex[key]]) 2513 DepexStr += '\n\n' 2514 if not DepexStr: 2515 return '[Depex.%s]\n' % self.Arch 2516 return DepexStr 2517 2518 #the type of build module not is USER_DEFINED. 2519 Count = 0 2520 for Depex in DepexList: 2521 Count += 1 2522 if DepexStr != '': 2523 DepexStr += ' AND ' 2524 DepexStr += '(' 2525 for D in Depex.values(): 2526 DepexStr += ' '.join([val for val in D]) 2527 Index = DepexStr.find('END') 2528 if Index > -1 and Index == len(DepexStr) - 3: 2529 DepexStr = DepexStr[:-3] 2530 DepexStr = DepexStr.strip() 2531 DepexStr += ')' 2532 if Count == 1: 2533 DepexStr = DepexStr.lstrip('(').rstrip(')').strip() 2534 if not DepexStr: 2535 return '[Depex.%s]\n' % self.Arch 2536 return '[Depex.%s]\n# ' % self.Arch + DepexStr 2537 2538 ## Merge dependency expression 2539 # 2540 # @retval list The token list of the dependency expression after parsed 2541 # 2542 def _GetDepexTokenList(self): 2543 if self._DepexList == None: 2544 self._DepexList = {} 2545 if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes: 2546 return self._DepexList 2547 2548 self._DepexList[self.ModuleType] = [] 2549 2550 for ModuleType in self._DepexList: 2551 DepexList = self._DepexList[ModuleType] 2552 # 2553 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion 2554 # 2555 for M in [self.Module] + self.DependentLibraryList: 2556 Inherited = False 2557 for D in M.Depex[self.Arch, ModuleType]: 2558 if DepexList != []: 2559 DepexList.append('AND') 2560 DepexList.append('(') 2561 DepexList.extend(D) 2562 if DepexList[-1] == 'END': # no need of a END at this time 2563 DepexList.pop() 2564 DepexList.append(')') 2565 Inherited = True 2566 if Inherited: 2567 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList)) 2568 if 'BEFORE' in DepexList or 'AFTER' in DepexList: 2569 break 2570 if len(DepexList) > 0: 2571 EdkLogger.verbose('') 2572 return self._DepexList 2573 2574 ## Merge dependency expression 2575 # 2576 # @retval list The token list of the dependency expression after parsed 2577 # 2578 def _GetDepexExpressionTokenList(self): 2579 if self._DepexExpressionList == None: 2580 self._DepexExpressionList = {} 2581 if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes: 2582 return self._DepexExpressionList 2583 2584 self._DepexExpressionList[self.ModuleType] = '' 2585 2586 for ModuleType in self._DepexExpressionList: 2587 DepexExpressionList = self._DepexExpressionList[ModuleType] 2588 # 2589 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion 2590 # 2591 for M in [self.Module] + self.DependentLibraryList: 2592 Inherited = False 2593 for D in M.DepexExpression[self.Arch, ModuleType]: 2594 if DepexExpressionList != '': 2595 DepexExpressionList += ' AND ' 2596 DepexExpressionList += '(' 2597 DepexExpressionList += D 2598 DepexExpressionList = DepexExpressionList.rstrip('END').strip() 2599 DepexExpressionList += ')' 2600 Inherited = True 2601 if Inherited: 2602 EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList)) 2603 if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList: 2604 break 2605 if len(DepexExpressionList) > 0: 2606 EdkLogger.verbose('') 2607 self._DepexExpressionList[ModuleType] = DepexExpressionList 2608 return self._DepexExpressionList 2609 2610 ## Return the list of specification version required for the module 2611 # 2612 # @retval list The list of specification defined in module file 2613 # 2614 def _GetSpecification(self): 2615 return self.Module.Specification 2616 2617 ## Tool option for the module build 2618 # 2619 # @param PlatformInfo The object of PlatformBuildInfo 2620 # @retval dict The dict containing valid options 2621 # 2622 def _GetModuleBuildOption(self): 2623 if self._BuildOption == None: 2624 self._BuildOption, self.BuildRuleOrder = self.PlatformInfo.ApplyBuildOption(self.Module) 2625 if self.BuildRuleOrder: 2626 self.BuildRuleOrder = ['.%s' % Ext for Ext in self.BuildRuleOrder.split()] 2627 return self._BuildOption 2628 2629 ## Get include path list from tool option for the module build 2630 # 2631 # @retval list The include path list 2632 # 2633 def _GetBuildOptionIncPathList(self): 2634 if self._BuildOptionIncPathList == None: 2635 # 2636 # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT 2637 # is the former use /I , the Latter used -I to specify include directories 2638 # 2639 if self.PlatformInfo.ToolChainFamily in ('MSFT'): 2640 gBuildOptIncludePattern = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL) 2641 elif self.PlatformInfo.ToolChainFamily in ('INTEL', 'GCC', 'RVCT'): 2642 gBuildOptIncludePattern = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL) 2643 else: 2644 # 2645 # New ToolChainFamily, don't known whether there is option to specify include directories 2646 # 2647 self._BuildOptionIncPathList = [] 2648 return self._BuildOptionIncPathList 2649 2650 BuildOptionIncPathList = [] 2651 for Tool in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'): 2652 Attr = 'FLAGS' 2653 try: 2654 FlagOption = self.BuildOption[Tool][Attr] 2655 except KeyError: 2656 FlagOption = '' 2657 2658 if self.PlatformInfo.ToolChainFamily != 'RVCT': 2659 IncPathList = [NormPath(Path, self.Macros) for Path in gBuildOptIncludePattern.findall(FlagOption)] 2660 else: 2661 # 2662 # RVCT may specify a list of directory seperated by commas 2663 # 2664 IncPathList = [] 2665 for Path in gBuildOptIncludePattern.findall(FlagOption): 2666 PathList = GetSplitList(Path, TAB_COMMA_SPLIT) 2667 IncPathList += [NormPath(PathEntry, self.Macros) for PathEntry in PathList] 2668 2669 # 2670 # EDK II modules must not reference header files outside of the packages they depend on or 2671 # within the module's directory tree. Report error if violation. 2672 # 2673 if self.AutoGenVersion >= 0x00010005 and len(IncPathList) > 0: 2674 for Path in IncPathList: 2675 if (Path not in self.IncludePathList) and (CommonPath([Path, self.MetaFile.Dir]) != self.MetaFile.Dir): 2676 ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path, Tool, FlagOption) 2677 EdkLogger.error("build", 2678 PARAMETER_INVALID, 2679 ExtraData=ErrMsg, 2680 File=str(self.MetaFile)) 2681 2682 2683 BuildOptionIncPathList += IncPathList 2684 2685 self._BuildOptionIncPathList = BuildOptionIncPathList 2686 2687 return self._BuildOptionIncPathList 2688 2689 ## Return a list of files which can be built from source 2690 # 2691 # What kind of files can be built is determined by build rules in 2692 # $(CONF_DIRECTORY)/build_rule.txt and toolchain family. 2693 # 2694 def _GetSourceFileList(self): 2695 if self._SourceFileList == None: 2696 self._SourceFileList = [] 2697 for F in self.Module.Sources: 2698 # match tool chain 2699 if F.TagName not in ("", "*", self.ToolChain): 2700 EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, " 2701 "but [%s] is needed" % (F.TagName, str(F), self.ToolChain)) 2702 continue 2703 # match tool chain family 2704 if F.ToolChainFamily not in ("", "*", self.ToolChainFamily): 2705 EdkLogger.debug( 2706 EdkLogger.DEBUG_0, 2707 "The file [%s] must be built by tools of [%s], " \ 2708 "but current toolchain family is [%s]" \ 2709 % (str(F), F.ToolChainFamily, self.ToolChainFamily)) 2710 continue 2711 2712 # add the file path into search path list for file including 2713 if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005: 2714 self.IncludePathList.insert(0, F.Dir) 2715 self._SourceFileList.append(F) 2716 self._ApplyBuildRule(F, TAB_UNKNOWN_FILE) 2717 return self._SourceFileList 2718 2719 ## Return the list of unicode files 2720 def _GetUnicodeFileList(self): 2721 if self._UnicodeFileList == None: 2722 if TAB_UNICODE_FILE in self.FileTypes: 2723 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE] 2724 else: 2725 self._UnicodeFileList = [] 2726 return self._UnicodeFileList 2727 2728 ## Return a list of files which can be built from binary 2729 # 2730 # "Build" binary files are just to copy them to build directory. 2731 # 2732 # @retval list The list of files which can be built later 2733 # 2734 def _GetBinaryFiles(self): 2735 if self._BinaryFileList == None: 2736 self._BinaryFileList = [] 2737 for F in self.Module.Binaries: 2738 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget: 2739 continue 2740 self._BinaryFileList.append(F) 2741 self._ApplyBuildRule(F, F.Type) 2742 return self._BinaryFileList 2743 2744 def _GetBuildRules(self): 2745 if self._BuildRules == None: 2746 BuildRules = {} 2747 BuildRuleDatabase = self.PlatformInfo.BuildRule 2748 for Type in BuildRuleDatabase.FileTypeList: 2749 #first try getting build rule by BuildRuleFamily 2750 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily] 2751 if not RuleObject: 2752 # build type is always module type, but ... 2753 if self.ModuleType != self.BuildType: 2754 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily] 2755 #second try getting build rule by ToolChainFamily 2756 if not RuleObject: 2757 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily] 2758 if not RuleObject: 2759 # build type is always module type, but ... 2760 if self.ModuleType != self.BuildType: 2761 RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily] 2762 if not RuleObject: 2763 continue 2764 RuleObject = RuleObject.Instantiate(self.Macros) 2765 BuildRules[Type] = RuleObject 2766 for Ext in RuleObject.SourceFileExtList: 2767 BuildRules[Ext] = RuleObject 2768 self._BuildRules = BuildRules 2769 return self._BuildRules 2770 2771 def _ApplyBuildRule(self, File, FileType): 2772 if self._BuildTargets == None: 2773 self._IntroBuildTargetList = set() 2774 self._FinalBuildTargetList = set() 2775 self._BuildTargets = {} 2776 self._FileTypes = {} 2777 2778 SubDirectory = os.path.join(self.OutputDir, File.SubDir) 2779 if not os.path.exists(SubDirectory): 2780 CreateDirectory(SubDirectory) 2781 LastTarget = None 2782 RuleChain = [] 2783 SourceList = [File] 2784 Index = 0 2785 # 2786 # Make sure to get build rule order value 2787 # 2788 self._GetModuleBuildOption() 2789 2790 while Index < len(SourceList): 2791 Source = SourceList[Index] 2792 Index = Index + 1 2793 2794 if Source != File: 2795 CreateDirectory(Source.Dir) 2796 2797 if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList: 2798 # Skip all files that are not binary libraries 2799 if not self.IsLibrary: 2800 continue 2801 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE] 2802 elif FileType in self.BuildRules: 2803 RuleObject = self.BuildRules[FileType] 2804 elif Source.Ext in self.BuildRules: 2805 RuleObject = self.BuildRules[Source.Ext] 2806 else: 2807 # stop at no more rules 2808 if LastTarget: 2809 self._FinalBuildTargetList.add(LastTarget) 2810 break 2811 2812 FileType = RuleObject.SourceFileType 2813 if FileType not in self._FileTypes: 2814 self._FileTypes[FileType] = set() 2815 self._FileTypes[FileType].add(Source) 2816 2817 # stop at STATIC_LIBRARY for library 2818 if self.IsLibrary and FileType == TAB_STATIC_LIBRARY: 2819 if LastTarget: 2820 self._FinalBuildTargetList.add(LastTarget) 2821 break 2822 2823 Target = RuleObject.Apply(Source, self.BuildRuleOrder) 2824 if not Target: 2825 if LastTarget: 2826 self._FinalBuildTargetList.add(LastTarget) 2827 break 2828 elif not Target.Outputs: 2829 # Only do build for target with outputs 2830 self._FinalBuildTargetList.add(Target) 2831 2832 if FileType not in self._BuildTargets: 2833 self._BuildTargets[FileType] = set() 2834 self._BuildTargets[FileType].add(Target) 2835 2836 if not Source.IsBinary and Source == File: 2837 self._IntroBuildTargetList.add(Target) 2838 2839 # to avoid cyclic rule 2840 if FileType in RuleChain: 2841 break 2842 2843 RuleChain.append(FileType) 2844 SourceList.extend(Target.Outputs) 2845 LastTarget = Target 2846 FileType = TAB_UNKNOWN_FILE 2847 2848 def _GetTargets(self): 2849 if self._BuildTargets == None: 2850 self._IntroBuildTargetList = set() 2851 self._FinalBuildTargetList = set() 2852 self._BuildTargets = {} 2853 self._FileTypes = {} 2854 2855 #TRICK: call _GetSourceFileList to apply build rule for source files 2856 if self.SourceFileList: 2857 pass 2858 2859 #TRICK: call _GetBinaryFileList to apply build rule for binary files 2860 if self.BinaryFileList: 2861 pass 2862 2863 return self._BuildTargets 2864 2865 def _GetIntroTargetList(self): 2866 self._GetTargets() 2867 return self._IntroBuildTargetList 2868 2869 def _GetFinalTargetList(self): 2870 self._GetTargets() 2871 return self._FinalBuildTargetList 2872 2873 def _GetFileTypes(self): 2874 self._GetTargets() 2875 return self._FileTypes 2876 2877 ## Get the list of package object the module depends on 2878 # 2879 # @retval list The package object list 2880 # 2881 def _GetDependentPackageList(self): 2882 return self.Module.Packages 2883 2884 ## Return the list of auto-generated code file 2885 # 2886 # @retval list The list of auto-generated file 2887 # 2888 def _GetAutoGenFileList(self): 2889 UniStringAutoGenC = True 2890 UniStringBinBuffer = StringIO() 2891 if self.BuildType == 'UEFI_HII': 2892 UniStringAutoGenC = False 2893 if self._AutoGenFileList == None: 2894 self._AutoGenFileList = {} 2895 AutoGenC = TemplateString() 2896 AutoGenH = TemplateString() 2897 StringH = TemplateString() 2898 GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer) 2899 # 2900 # AutoGen.c is generated if there are library classes in inf, or there are object files 2901 # 2902 if str(AutoGenC) != "" and (len(self.Module.LibraryClasses) > 0 2903 or TAB_OBJECT_FILE in self.FileTypes): 2904 AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir) 2905 self._AutoGenFileList[AutoFile] = str(AutoGenC) 2906 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) 2907 if str(AutoGenH) != "": 2908 AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir) 2909 self._AutoGenFileList[AutoFile] = str(AutoGenH) 2910 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) 2911 if str(StringH) != "": 2912 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir) 2913 self._AutoGenFileList[AutoFile] = str(StringH) 2914 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) 2915 if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "": 2916 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir) 2917 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue() 2918 AutoFile.IsBinary = True 2919 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) 2920 if UniStringBinBuffer != None: 2921 UniStringBinBuffer.close() 2922 return self._AutoGenFileList 2923 2924 ## Return the list of library modules explicitly or implicityly used by this module 2925 def _GetLibraryList(self): 2926 if self._DependentLibraryList == None: 2927 # only merge library classes and PCD for non-library module 2928 if self.IsLibrary: 2929 self._DependentLibraryList = [] 2930 else: 2931 if self.AutoGenVersion < 0x00010005: 2932 self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module) 2933 else: 2934 self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module) 2935 return self._DependentLibraryList 2936 2937 @staticmethod 2938 def UpdateComments(Recver, Src): 2939 for Key in Src: 2940 if Key not in Recver: 2941 Recver[Key] = [] 2942 Recver[Key].extend(Src[Key]) 2943 ## Get the list of PCDs from current module 2944 # 2945 # @retval list The list of PCD 2946 # 2947 def _GetModulePcdList(self): 2948 if self._ModulePcdList == None: 2949 # apply PCD settings from platform 2950 self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds) 2951 self.UpdateComments(self._PcdComments, self.Module.PcdComments) 2952 return self._ModulePcdList 2953 2954 ## Get the list of PCDs from dependent libraries 2955 # 2956 # @retval list The list of PCD 2957 # 2958 def _GetLibraryPcdList(self): 2959 if self._LibraryPcdList == None: 2960 Pcds = sdict() 2961 if not self.IsLibrary: 2962 # get PCDs from dependent libraries 2963 for Library in self.DependentLibraryList: 2964 self.UpdateComments(self._PcdComments, Library.PcdComments) 2965 for Key in Library.Pcds: 2966 # skip duplicated PCDs 2967 if Key in self.Module.Pcds or Key in Pcds: 2968 continue 2969 Pcds[Key] = copy.copy(Library.Pcds[Key]) 2970 # apply PCD settings from platform 2971 self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds) 2972 else: 2973 self._LibraryPcdList = [] 2974 return self._LibraryPcdList 2975 2976 ## Get the GUID value mapping 2977 # 2978 # @retval dict The mapping between GUID cname and its value 2979 # 2980 def _GetGuidList(self): 2981 if self._GuidList == None: 2982 self._GuidList = sdict() 2983 self._GuidList.update(self.Module.Guids) 2984 for Library in self.DependentLibraryList: 2985 self._GuidList.update(Library.Guids) 2986 self.UpdateComments(self._GuidComments, Library.GuidComments) 2987 self.UpdateComments(self._GuidComments, self.Module.GuidComments) 2988 return self._GuidList 2989 2990 def GetGuidsUsedByPcd(self): 2991 if self._GuidsUsedByPcd == None: 2992 self._GuidsUsedByPcd = sdict() 2993 self._GuidsUsedByPcd.update(self.Module.GetGuidsUsedByPcd()) 2994 for Library in self.DependentLibraryList: 2995 self._GuidsUsedByPcd.update(Library.GetGuidsUsedByPcd()) 2996 return self._GuidsUsedByPcd 2997 ## Get the protocol value mapping 2998 # 2999 # @retval dict The mapping between protocol cname and its value 3000 # 3001 def _GetProtocolList(self): 3002 if self._ProtocolList == None: 3003 self._ProtocolList = sdict() 3004 self._ProtocolList.update(self.Module.Protocols) 3005 for Library in self.DependentLibraryList: 3006 self._ProtocolList.update(Library.Protocols) 3007 self.UpdateComments(self._ProtocolComments, Library.ProtocolComments) 3008 self.UpdateComments(self._ProtocolComments, self.Module.ProtocolComments) 3009 return self._ProtocolList 3010 3011 ## Get the PPI value mapping 3012 # 3013 # @retval dict The mapping between PPI cname and its value 3014 # 3015 def _GetPpiList(self): 3016 if self._PpiList == None: 3017 self._PpiList = sdict() 3018 self._PpiList.update(self.Module.Ppis) 3019 for Library in self.DependentLibraryList: 3020 self._PpiList.update(Library.Ppis) 3021 self.UpdateComments(self._PpiComments, Library.PpiComments) 3022 self.UpdateComments(self._PpiComments, self.Module.PpiComments) 3023 return self._PpiList 3024 3025 ## Get the list of include search path 3026 # 3027 # @retval list The list path 3028 # 3029 def _GetIncludePathList(self): 3030 if self._IncludePathList == None: 3031 self._IncludePathList = [] 3032 if self.AutoGenVersion < 0x00010005: 3033 for Inc in self.Module.Includes: 3034 if Inc not in self._IncludePathList: 3035 self._IncludePathList.append(Inc) 3036 # for Edk modules 3037 Inc = path.join(Inc, self.Arch.capitalize()) 3038 if os.path.exists(Inc) and Inc not in self._IncludePathList: 3039 self._IncludePathList.append(Inc) 3040 # Edk module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time 3041 self._IncludePathList.append(self.DebugDir) 3042 else: 3043 self._IncludePathList.append(self.MetaFile.Dir) 3044 self._IncludePathList.append(self.DebugDir) 3045 3046 for Package in self.Module.Packages: 3047 PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir) 3048 if PackageDir not in self._IncludePathList: 3049 self._IncludePathList.append(PackageDir) 3050 for Inc in Package.Includes: 3051 if Inc not in self._IncludePathList: 3052 self._IncludePathList.append(str(Inc)) 3053 return self._IncludePathList 3054 3055 ## Get HII EX PCDs which maybe used by VFR 3056 # 3057 # efivarstore used by VFR may relate with HII EX PCDs 3058 # Get the variable name and GUID from efivarstore and HII EX PCD 3059 # List the HII EX PCDs in As Built INF if both name and GUID match. 3060 # 3061 # @retval list HII EX PCDs 3062 # 3063 def _GetPcdsMaybeUsedByVfr(self): 3064 if not self.SourceFileList: 3065 return [] 3066 3067 NameGuids = [] 3068 for SrcFile in self.SourceFileList: 3069 if SrcFile.Ext.lower() != '.vfr': 3070 continue 3071 Vfri = os.path.join(self.OutputDir, SrcFile.BaseName + '.i') 3072 if not os.path.exists(Vfri): 3073 continue 3074 VfriFile = open(Vfri, 'r') 3075 Content = VfriFile.read() 3076 VfriFile.close() 3077 Pos = Content.find('efivarstore') 3078 while Pos != -1: 3079 # 3080 # Make sure 'efivarstore' is the start of efivarstore statement 3081 # In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore' 3082 # 3083 Index = Pos - 1 3084 while Index >= 0 and Content[Index] in ' \t\r\n': 3085 Index -= 1 3086 if Index >= 0 and Content[Index] != ';': 3087 Pos = Content.find('efivarstore', Pos + len('efivarstore')) 3088 continue 3089 # 3090 # 'efivarstore' must be followed by name and guid 3091 # 3092 Name = gEfiVarStoreNamePattern.search(Content, Pos) 3093 if not Name: 3094 break 3095 Guid = gEfiVarStoreGuidPattern.search(Content, Pos) 3096 if not Guid: 3097 break 3098 NameArray = ConvertStringToByteArray('L"' + Name.group(1) + '"') 3099 NameGuids.append((NameArray, GuidStructureStringToGuidString(Guid.group(1)))) 3100 Pos = Content.find('efivarstore', Name.end()) 3101 if not NameGuids: 3102 return [] 3103 HiiExPcds = [] 3104 for Pcd in self.PlatformInfo.Platform.Pcds.values(): 3105 if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII: 3106 continue 3107 for SkuName in Pcd.SkuInfoList: 3108 SkuInfo = Pcd.SkuInfoList[SkuName] 3109 Name = ConvertStringToByteArray(SkuInfo.VariableName) 3110 Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList) 3111 if not Value: 3112 continue 3113 Guid = GuidStructureStringToGuidString(Value) 3114 if (Name, Guid) in NameGuids and Pcd not in HiiExPcds: 3115 HiiExPcds.append(Pcd) 3116 break 3117 3118 return HiiExPcds 3119 3120 def _GenOffsetBin(self): 3121 VfrUniBaseName = {} 3122 for SourceFile in self.Module.Sources: 3123 if SourceFile.Type.upper() == ".VFR" : 3124 # 3125 # search the .map file to find the offset of vfr binary in the PE32+/TE file. 3126 # 3127 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin") 3128 if SourceFile.Type.upper() == ".UNI" : 3129 # 3130 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. 3131 # 3132 VfrUniBaseName["UniOffsetName"] = (self.Name + "Strings") 3133 3134 if len(VfrUniBaseName) == 0: 3135 return None 3136 MapFileName = os.path.join(self.OutputDir, self.Name + ".map") 3137 EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi") 3138 VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values()) 3139 if not VfrUniOffsetList: 3140 return None 3141 3142 OutputName = '%sOffset.bin' % self.Name 3143 UniVfrOffsetFileName = os.path.join( self.OutputDir, OutputName) 3144 3145 try: 3146 fInputfile = open(UniVfrOffsetFileName, "wb+", 0) 3147 except: 3148 EdkLogger.error("build", FILE_OPEN_FAILURE, "File open failed for %s" % UniVfrOffsetFileName,None) 3149 3150 # Use a instance of StringIO to cache data 3151 fStringIO = StringIO('') 3152 3153 for Item in VfrUniOffsetList: 3154 if (Item[0].find("Strings") != -1): 3155 # 3156 # UNI offset in image. 3157 # GUID + Offset 3158 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } } 3159 # 3160 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66] 3161 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid] 3162 fStringIO.write(''.join(UniGuid)) 3163 UniValue = pack ('Q', int (Item[1], 16)) 3164 fStringIO.write (UniValue) 3165 else: 3166 # 3167 # VFR binary offset in image. 3168 # GUID + Offset 3169 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }; 3170 # 3171 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2] 3172 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid] 3173 fStringIO.write(''.join(VfrGuid)) 3174 type (Item[1]) 3175 VfrValue = pack ('Q', int (Item[1], 16)) 3176 fStringIO.write (VfrValue) 3177 # 3178 # write data into file. 3179 # 3180 try : 3181 fInputfile.write (fStringIO.getvalue()) 3182 except: 3183 EdkLogger.error("build", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the " 3184 "file been locked or using by other applications." %UniVfrOffsetFileName,None) 3185 3186 fStringIO.close () 3187 fInputfile.close () 3188 return OutputName 3189 3190 ## Create AsBuilt INF file the module 3191 # 3192 def CreateAsBuiltInf(self): 3193 if self.IsAsBuiltInfCreated: 3194 return 3195 3196 # Skip the following code for EDK I inf 3197 if self.AutoGenVersion < 0x00010005: 3198 return 3199 3200 # Skip the following code for libraries 3201 if self.IsLibrary: 3202 return 3203 3204 # Skip the following code for modules with no source files 3205 if self.SourceFileList == None or self.SourceFileList == []: 3206 return 3207 3208 # Skip the following code for modules without any binary files 3209 if self.BinaryFileList <> None and self.BinaryFileList <> []: 3210 return 3211 3212 ### TODO: How to handles mixed source and binary modules 3213 3214 # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries 3215 # Also find all packages that the DynamicEx PCDs depend on 3216 Pcds = [] 3217 PatchablePcds = {} 3218 Packages = [] 3219 PcdCheckList = [] 3220 PcdTokenSpaceList = [] 3221 for Pcd in self.ModulePcdList + self.LibraryPcdList: 3222 if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE: 3223 PatchablePcds[Pcd.TokenCName] = Pcd 3224 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'PatchableInModule')) 3225 elif Pcd.Type in GenC.gDynamicExPcd: 3226 if Pcd not in Pcds: 3227 Pcds += [Pcd] 3228 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx')) 3229 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic')) 3230 PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName) 3231 GuidList = sdict() 3232 GuidList.update(self.GuidList) 3233 for TokenSpace in self.GetGuidsUsedByPcd(): 3234 # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list 3235 # The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs 3236 if TokenSpace not in PcdTokenSpaceList and TokenSpace in GuidList: 3237 GuidList.pop(TokenSpace) 3238 CheckList = (GuidList, self.PpiList, self.ProtocolList, PcdCheckList) 3239 for Package in self.DerivedPackageList: 3240 if Package in Packages: 3241 continue 3242 BeChecked = (Package.Guids, Package.Ppis, Package.Protocols, Package.Pcds) 3243 Found = False 3244 for Index in range(len(BeChecked)): 3245 for Item in CheckList[Index]: 3246 if Item in BeChecked[Index]: 3247 Packages += [Package] 3248 Found = True 3249 break 3250 if Found: break 3251 3252 VfrPcds = self._GetPcdsMaybeUsedByVfr() 3253 for Pkg in self.PlatformInfo.PackageList: 3254 if Pkg in Packages: 3255 continue 3256 for VfrPcd in VfrPcds: 3257 if ((VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'DynamicEx') in Pkg.Pcds or 3258 (VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'Dynamic') in Pkg.Pcds): 3259 Packages += [Pkg] 3260 break 3261 3262 ModuleType = self.ModuleType 3263 if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated: 3264 ModuleType = 'DXE_DRIVER' 3265 3266 DriverType = '' 3267 if self.PcdIsDriver != '': 3268 DriverType = self.PcdIsDriver 3269 3270 Guid = self.Guid 3271 MDefs = self.Module.Defines 3272 3273 AsBuiltInfDict = { 3274 'module_name' : self.Name, 3275 'module_guid' : Guid, 3276 'module_module_type' : ModuleType, 3277 'module_version_string' : [MDefs['VERSION_STRING']] if 'VERSION_STRING' in MDefs else [], 3278 'pcd_is_driver_string' : [], 3279 'module_uefi_specification_version' : [], 3280 'module_pi_specification_version' : [], 3281 'module_entry_point' : self.Module.ModuleEntryPointList, 3282 'module_unload_image' : self.Module.ModuleUnloadImageList, 3283 'module_constructor' : self.Module.ConstructorList, 3284 'module_destructor' : self.Module.DestructorList, 3285 'module_shadow' : [MDefs['SHADOW']] if 'SHADOW' in MDefs else [], 3286 'module_pci_vendor_id' : [MDefs['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs else [], 3287 'module_pci_device_id' : [MDefs['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs else [], 3288 'module_pci_class_code' : [MDefs['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs else [], 3289 'module_pci_revision' : [MDefs['PCI_REVISION']] if 'PCI_REVISION' in MDefs else [], 3290 'module_build_number' : [MDefs['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs else [], 3291 'module_spec' : [MDefs['SPEC']] if 'SPEC' in MDefs else [], 3292 'module_uefi_hii_resource_section' : [MDefs['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs else [], 3293 'module_uni_file' : [MDefs['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs else [], 3294 'module_arch' : self.Arch, 3295 'package_item' : ['%s' % (Package.MetaFile.File.replace('\\', '/')) for Package in Packages], 3296 'binary_item' : [], 3297 'patchablepcd_item' : [], 3298 'pcd_item' : [], 3299 'protocol_item' : [], 3300 'ppi_item' : [], 3301 'guid_item' : [], 3302 'flags_item' : [], 3303 'libraryclasses_item' : [] 3304 } 3305 3306 if self.AutoGenVersion > int(gInfSpecVersion, 0): 3307 AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion 3308 else: 3309 AsBuiltInfDict['module_inf_version'] = gInfSpecVersion 3310 3311 if DriverType: 3312 AsBuiltInfDict['pcd_is_driver_string'] += [DriverType] 3313 3314 if 'UEFI_SPECIFICATION_VERSION' in self.Specification: 3315 AsBuiltInfDict['module_uefi_specification_version'] += [self.Specification['UEFI_SPECIFICATION_VERSION']] 3316 if 'PI_SPECIFICATION_VERSION' in self.Specification: 3317 AsBuiltInfDict['module_pi_specification_version'] += [self.Specification['PI_SPECIFICATION_VERSION']] 3318 3319 OutputDir = self.OutputDir.replace('\\', '/').strip('/') 3320 if self.ModuleType in ['BASE', 'USER_DEFINED']: 3321 for Item in self.CodaTargetList: 3322 File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/') 3323 if Item.Target.Ext.lower() == '.aml': 3324 AsBuiltInfDict['binary_item'] += ['ASL|' + File] 3325 elif Item.Target.Ext.lower() == '.acpi': 3326 AsBuiltInfDict['binary_item'] += ['ACPI|' + File] 3327 else: 3328 AsBuiltInfDict['binary_item'] += ['BIN|' + File] 3329 else: 3330 for Item in self.CodaTargetList: 3331 File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/') 3332 if Item.Target.Ext.lower() == '.efi': 3333 AsBuiltInfDict['binary_item'] += ['PE32|' + self.Name + '.efi'] 3334 else: 3335 AsBuiltInfDict['binary_item'] += ['BIN|' + File] 3336 if self.DepexGenerated: 3337 if self.ModuleType in ['PEIM']: 3338 AsBuiltInfDict['binary_item'] += ['PEI_DEPEX|' + self.Name + '.depex'] 3339 if self.ModuleType in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']: 3340 AsBuiltInfDict['binary_item'] += ['DXE_DEPEX|' + self.Name + '.depex'] 3341 if self.ModuleType in ['DXE_SMM_DRIVER']: 3342 AsBuiltInfDict['binary_item'] += ['SMM_DEPEX|' + self.Name + '.depex'] 3343 3344 Bin = self._GenOffsetBin() 3345 if Bin: 3346 AsBuiltInfDict['binary_item'] += ['BIN|%s' % Bin] 3347 3348 for Root, Dirs, Files in os.walk(OutputDir): 3349 for File in Files: 3350 if File.lower().endswith('.pdb'): 3351 AsBuiltInfDict['binary_item'] += ['DISPOSABLE|' + File] 3352 HeaderComments = self.Module.HeaderComments 3353 StartPos = 0 3354 for Index in range(len(HeaderComments)): 3355 if HeaderComments[Index].find('@BinaryHeader') != -1: 3356 HeaderComments[Index] = HeaderComments[Index].replace('@BinaryHeader', '@file') 3357 StartPos = Index 3358 break 3359 AsBuiltInfDict['header_comments'] = '\n'.join(HeaderComments[StartPos:]).replace(':#', '://') 3360 AsBuiltInfDict['tail_comments'] = '\n'.join(self.Module.TailComments) 3361 3362 GenList = [ 3363 (self.ProtocolList, self._ProtocolComments, 'protocol_item'), 3364 (self.PpiList, self._PpiComments, 'ppi_item'), 3365 (GuidList, self._GuidComments, 'guid_item') 3366 ] 3367 for Item in GenList: 3368 for CName in Item[0]: 3369 Comments = '' 3370 if CName in Item[1]: 3371 Comments = '\n '.join(Item[1][CName]) 3372 Entry = CName 3373 if Comments: 3374 Entry = Comments + '\n ' + CName 3375 AsBuiltInfDict[Item[2]].append(Entry) 3376 PatchList = parsePcdInfoFromMapFile( 3377 os.path.join(self.OutputDir, self.Name + '.map'), 3378 os.path.join(self.OutputDir, self.Name + '.efi') 3379 ) 3380 if PatchList: 3381 for PatchPcd in PatchList: 3382 if PatchPcd[0] not in PatchablePcds: 3383 continue 3384 Pcd = PatchablePcds[PatchPcd[0]] 3385 PcdValue = '' 3386 if Pcd.DatumType != 'VOID*': 3387 HexFormat = '0x%02x' 3388 if Pcd.DatumType == 'UINT16': 3389 HexFormat = '0x%04x' 3390 elif Pcd.DatumType == 'UINT32': 3391 HexFormat = '0x%08x' 3392 elif Pcd.DatumType == 'UINT64': 3393 HexFormat = '0x%016x' 3394 PcdValue = HexFormat % int(Pcd.DefaultValue, 0) 3395 else: 3396 if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '': 3397 EdkLogger.error("build", AUTOGEN_ERROR, 3398 "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) 3399 ) 3400 ArraySize = int(Pcd.MaxDatumSize, 0) 3401 PcdValue = Pcd.DefaultValue 3402 if PcdValue[0] != '{': 3403 Unicode = False 3404 if PcdValue[0] == 'L': 3405 Unicode = True 3406 PcdValue = PcdValue.lstrip('L') 3407 PcdValue = eval(PcdValue) 3408 NewValue = '{' 3409 for Index in range(0, len(PcdValue)): 3410 if Unicode: 3411 CharVal = ord(PcdValue[Index]) 3412 NewValue = NewValue + '0x%02x' % (CharVal & 0x00FF) + ', ' \ 3413 + '0x%02x' % (CharVal >> 8) + ', ' 3414 else: 3415 NewValue = NewValue + '0x%02x' % (ord(PcdValue[Index]) % 0x100) + ', ' 3416 Padding = '0x00, ' 3417 if Unicode: 3418 Padding = Padding * 2 3419 ArraySize = ArraySize / 2 3420 if ArraySize < (len(PcdValue) + 1): 3421 EdkLogger.error("build", AUTOGEN_ERROR, 3422 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) 3423 ) 3424 if ArraySize > len(PcdValue) + 1: 3425 NewValue = NewValue + Padding * (ArraySize - len(PcdValue) - 1) 3426 PcdValue = NewValue + Padding.strip().rstrip(',') + '}' 3427 elif len(PcdValue.split(',')) <= ArraySize: 3428 PcdValue = PcdValue.rstrip('}') + ', 0x00' * (ArraySize - len(PcdValue.split(','))) 3429 PcdValue += '}' 3430 else: 3431 EdkLogger.error("build", AUTOGEN_ERROR, 3432 "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) 3433 ) 3434 PcdItem = '%s.%s|%s|0x%X' % \ 3435 (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, PcdValue, PatchPcd[1]) 3436 PcdComments = '' 3437 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments: 3438 PcdComments = '\n '.join(self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName]) 3439 if PcdComments: 3440 PcdItem = PcdComments + '\n ' + PcdItem 3441 AsBuiltInfDict['patchablepcd_item'].append(PcdItem) 3442 3443 HiiPcds = [] 3444 for Pcd in Pcds + VfrPcds: 3445 PcdComments = '' 3446 PcdCommentList = [] 3447 HiiInfo = '' 3448 SkuId = '' 3449 if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII: 3450 for SkuName in Pcd.SkuInfoList: 3451 SkuInfo = Pcd.SkuInfoList[SkuName] 3452 SkuId = SkuInfo.SkuId 3453 HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset) 3454 break 3455 if SkuId: 3456 # 3457 # Don't generate duplicated HII PCD 3458 # 3459 if (SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in HiiPcds: 3460 continue 3461 else: 3462 HiiPcds.append((SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)) 3463 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments: 3464 PcdCommentList = self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName][:] 3465 if HiiInfo: 3466 UsageIndex = -1 3467 UsageStr = '' 3468 for Index, Comment in enumerate(PcdCommentList): 3469 for Usage in UsageList: 3470 if Comment.find(Usage) != -1: 3471 UsageStr = Usage 3472 UsageIndex = Index 3473 break 3474 if UsageIndex != -1: 3475 PcdCommentList[UsageIndex] = '## %s %s %s' % (UsageStr, HiiInfo, PcdCommentList[UsageIndex].replace(UsageStr, '')) 3476 else: 3477 PcdCommentList.append('## UNDEFINED ' + HiiInfo) 3478 PcdComments = '\n '.join(PcdCommentList) 3479 PcdEntry = Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName 3480 if PcdComments: 3481 PcdEntry = PcdComments + '\n ' + PcdEntry 3482 AsBuiltInfDict['pcd_item'] += [PcdEntry] 3483 for Item in self.BuildOption: 3484 if 'FLAGS' in self.BuildOption[Item]: 3485 AsBuiltInfDict['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self.ToolChainFamily, self.BuildTarget, self.ToolChain, self.Arch, Item, self.BuildOption[Item]['FLAGS'].strip())] 3486 3487 # Generated LibraryClasses section in comments. 3488 for Library in self.LibraryAutoGenList: 3489 AsBuiltInfDict['libraryclasses_item'] += [Library.MetaFile.File.replace('\\', '/')] 3490 3491 # Generated depex expression section in comments. 3492 AsBuiltInfDict['depexsection_item'] = '' 3493 DepexExpresion = self._GetDepexExpresionString() 3494 if DepexExpresion: 3495 AsBuiltInfDict['depexsection_item'] = DepexExpresion 3496 3497 AsBuiltInf = TemplateString() 3498 AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict)) 3499 3500 SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False) 3501 3502 self.IsAsBuiltInfCreated = True 3503 3504 ## Create makefile for the module and its dependent libraries 3505 # 3506 # @param CreateLibraryMakeFile Flag indicating if or not the makefiles of 3507 # dependent libraries will be created 3508 # 3509 def CreateMakeFile(self, CreateLibraryMakeFile=True): 3510 # Ignore generating makefile when it is a binary module 3511 if self.IsBinaryModule: 3512 return 3513 3514 if self.IsMakeFileCreated: 3515 return 3516 3517 if not self.IsLibrary and CreateLibraryMakeFile: 3518 for LibraryAutoGen in self.LibraryAutoGenList: 3519 LibraryAutoGen.CreateMakeFile() 3520 3521 if len(self.CustomMakefile) == 0: 3522 Makefile = GenMake.ModuleMakefile(self) 3523 else: 3524 Makefile = GenMake.CustomMakefile(self) 3525 if Makefile.Generate(): 3526 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" % 3527 (self.Name, self.Arch)) 3528 else: 3529 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" % 3530 (self.Name, self.Arch)) 3531 3532 self.IsMakeFileCreated = True 3533 3534 def CopyBinaryFiles(self): 3535 for File in self.Module.Binaries: 3536 SrcPath = File.Path 3537 DstPath = os.path.join(self.OutputDir , os.path.basename(SrcPath)) 3538 CopyLongFilePath(SrcPath, DstPath) 3539 ## Create autogen code for the module and its dependent libraries 3540 # 3541 # @param CreateLibraryCodeFile Flag indicating if or not the code of 3542 # dependent libraries will be created 3543 # 3544 def CreateCodeFile(self, CreateLibraryCodeFile=True): 3545 if self.IsCodeFileCreated: 3546 return 3547 3548 # Need to generate PcdDatabase even PcdDriver is binarymodule 3549 if self.IsBinaryModule and self.PcdIsDriver != '': 3550 CreatePcdDatabaseCode(self, TemplateString(), TemplateString()) 3551 return 3552 if self.IsBinaryModule: 3553 if self.IsLibrary: 3554 self.CopyBinaryFiles() 3555 return 3556 3557 if not self.IsLibrary and CreateLibraryCodeFile: 3558 for LibraryAutoGen in self.LibraryAutoGenList: 3559 LibraryAutoGen.CreateCodeFile() 3560 3561 AutoGenList = [] 3562 IgoredAutoGenList = [] 3563 3564 for File in self.AutoGenFileList: 3565 if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary): 3566 #Ignore Edk AutoGen.c 3567 if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c': 3568 continue 3569 3570 AutoGenList.append(str(File)) 3571 else: 3572 IgoredAutoGenList.append(str(File)) 3573 3574 # Skip the following code for EDK I inf 3575 if self.AutoGenVersion < 0x00010005: 3576 return 3577 3578 for ModuleType in self.DepexList: 3579 # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module 3580 if len(self.DepexList[ModuleType]) == 0 or ModuleType == "USER_DEFINED": 3581 continue 3582 3583 Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True) 3584 DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name} 3585 3586 if len(Dpx.PostfixNotation) <> 0: 3587 self.DepexGenerated = True 3588 3589 if Dpx.Generate(path.join(self.OutputDir, DpxFile)): 3590 AutoGenList.append(str(DpxFile)) 3591 else: 3592 IgoredAutoGenList.append(str(DpxFile)) 3593 3594 if IgoredAutoGenList == []: 3595 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" % 3596 (" ".join(AutoGenList), self.Name, self.Arch)) 3597 elif AutoGenList == []: 3598 EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" % 3599 (" ".join(IgoredAutoGenList), self.Name, self.Arch)) 3600 else: 3601 EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" % 3602 (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch)) 3603 3604 self.IsCodeFileCreated = True 3605 return AutoGenList 3606 3607 ## Summarize the ModuleAutoGen objects of all libraries used by this module 3608 def _GetLibraryAutoGenList(self): 3609 if self._LibraryAutoGenList == None: 3610 self._LibraryAutoGenList = [] 3611 for Library in self.DependentLibraryList: 3612 La = ModuleAutoGen( 3613 self.Workspace, 3614 Library.MetaFile, 3615 self.BuildTarget, 3616 self.ToolChain, 3617 self.Arch, 3618 self.PlatformInfo.MetaFile 3619 ) 3620 if La not in self._LibraryAutoGenList: 3621 self._LibraryAutoGenList.append(La) 3622 for Lib in La.CodaTargetList: 3623 self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE) 3624 return self._LibraryAutoGenList 3625 3626 Module = property(_GetModule) 3627 Name = property(_GetBaseName) 3628 Guid = property(_GetGuid) 3629 Version = property(_GetVersion) 3630 ModuleType = property(_GetModuleType) 3631 ComponentType = property(_GetComponentType) 3632 BuildType = property(_GetBuildType) 3633 PcdIsDriver = property(_GetPcdIsDriver) 3634 AutoGenVersion = property(_GetAutoGenVersion) 3635 Macros = property(_GetMacros) 3636 Specification = property(_GetSpecification) 3637 3638 IsLibrary = property(_IsLibrary) 3639 IsBinaryModule = property(_IsBinaryModule) 3640 BuildDir = property(_GetBuildDir) 3641 OutputDir = property(_GetOutputDir) 3642 DebugDir = property(_GetDebugDir) 3643 MakeFileDir = property(_GetMakeFileDir) 3644 CustomMakefile = property(_GetCustomMakefile) 3645 3646 IncludePathList = property(_GetIncludePathList) 3647 AutoGenFileList = property(_GetAutoGenFileList) 3648 UnicodeFileList = property(_GetUnicodeFileList) 3649 SourceFileList = property(_GetSourceFileList) 3650 BinaryFileList = property(_GetBinaryFiles) # FileType : [File List] 3651 Targets = property(_GetTargets) 3652 IntroTargetList = property(_GetIntroTargetList) 3653 CodaTargetList = property(_GetFinalTargetList) 3654 FileTypes = property(_GetFileTypes) 3655 BuildRules = property(_GetBuildRules) 3656 3657 DependentPackageList = property(_GetDependentPackageList) 3658 DependentLibraryList = property(_GetLibraryList) 3659 LibraryAutoGenList = property(_GetLibraryAutoGenList) 3660 DerivedPackageList = property(_GetDerivedPackageList) 3661 3662 ModulePcdList = property(_GetModulePcdList) 3663 LibraryPcdList = property(_GetLibraryPcdList) 3664 GuidList = property(_GetGuidList) 3665 ProtocolList = property(_GetProtocolList) 3666 PpiList = property(_GetPpiList) 3667 DepexList = property(_GetDepexTokenList) 3668 DxsFile = property(_GetDxsFile) 3669 DepexExpressionList = property(_GetDepexExpressionTokenList) 3670 BuildOption = property(_GetModuleBuildOption) 3671 BuildOptionIncPathList = property(_GetBuildOptionIncPathList) 3672 BuildCommand = property(_GetBuildCommand) 3673 3674 FixedAtBuildPcds = property(_GetFixedAtBuildPcds) 3675 3676# This acts like the main() function for the script, unless it is 'import'ed into another script. 3677if __name__ == '__main__': 3678 pass 3679 3680