1## @file 2# This file is used to create a database used by build tool 3# 4# Copyright (c) 2008 - 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## 15# Import Modules 16# 17import sqlite3 18import Common.LongFilePathOs as os 19import pickle 20import uuid 21 22import Common.EdkLogger as EdkLogger 23import Common.GlobalData as GlobalData 24from Common.MultipleWorkspace import MultipleWorkspace as mws 25 26from Common.String import * 27from Common.DataType import * 28from Common.Misc import * 29from types import * 30 31from CommonDataClass.CommonClass import SkuInfoClass 32 33from MetaDataTable import * 34from MetaFileTable import * 35from MetaFileParser import * 36from BuildClassObject import * 37from WorkspaceCommon import GetDeclaredPcd 38from Common.Misc import AnalyzeDscPcd 39from Common.Misc import ProcessDuplicatedInf 40import re 41from Common.Parsing import IsValidWord 42from Common.VariableAttributes import VariableAttributes 43import Common.GlobalData as GlobalData 44 45## Platform build information from DSC file 46# 47# This class is used to retrieve information stored in database and convert them 48# into PlatformBuildClassObject form for easier use for AutoGen. 49# 50class DscBuildData(PlatformBuildClassObject): 51 # dict used to convert PCD type in database to string used by build tool 52 _PCD_TYPE_STRING_ = { 53 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild", 54 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule", 55 MODEL_PCD_FEATURE_FLAG : "FeatureFlag", 56 MODEL_PCD_DYNAMIC : "Dynamic", 57 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic", 58 MODEL_PCD_DYNAMIC_HII : "DynamicHii", 59 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd", 60 MODEL_PCD_DYNAMIC_EX : "DynamicEx", 61 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx", 62 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii", 63 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd", 64 } 65 66 # dict used to convert part of [Defines] to members of DscBuildData directly 67 _PROPERTY_ = { 68 # 69 # Required Fields 70 # 71 TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName", 72 TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid", 73 TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version", 74 TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification", 75 #TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory", 76 #TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList", 77 #TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets", 78 TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName", 79 #TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition", 80 TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber", 81 TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName", 82 TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress", 83 TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress", 84 #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages", 85 #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages", 86 } 87 88 # used to compose dummy library class name for those forced library instances 89 _NullLibraryNumber = 0 90 91 ## Constructor of DscBuildData 92 # 93 # Initialize object of DscBuildData 94 # 95 # @param FilePath The path of platform description file 96 # @param RawData The raw data of DSC file 97 # @param BuildDataBase Database used to retrieve module/package information 98 # @param Arch The target architecture 99 # @param Platform (not used for DscBuildData) 100 # @param Macros Macros used for replacement in DSC file 101 # 102 def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None): 103 self.MetaFile = FilePath 104 self._RawData = RawData 105 self._Bdb = BuildDataBase 106 self._Arch = Arch 107 self._Target = Target 108 self._Toolchain = Toolchain 109 self._Clear() 110 self._HandleOverridePath() 111 112 ## XXX[key] = value 113 def __setitem__(self, key, value): 114 self.__dict__[self._PROPERTY_[key]] = value 115 116 ## value = XXX[key] 117 def __getitem__(self, key): 118 return self.__dict__[self._PROPERTY_[key]] 119 120 ## "in" test support 121 def __contains__(self, key): 122 return key in self._PROPERTY_ 123 124 ## Set all internal used members of DscBuildData to None 125 def _Clear(self): 126 self._Header = None 127 self._PlatformName = None 128 self._Guid = None 129 self._Version = None 130 self._DscSpecification = None 131 self._OutputDirectory = None 132 self._SupArchList = None 133 self._BuildTargets = None 134 self._SkuName = None 135 self._SkuIdentifier = None 136 self._AvilableSkuIds = None 137 self._PcdInfoFlag = None 138 self._VarCheckFlag = None 139 self._FlashDefinition = None 140 self._BuildNumber = None 141 self._MakefileName = None 142 self._BsBaseAddress = None 143 self._RtBaseAddress = None 144 self._SkuIds = None 145 self._Modules = None 146 self._LibraryInstances = None 147 self._LibraryClasses = None 148 self._Pcds = None 149 self._DecPcds = None 150 self._BuildOptions = None 151 self._ModuleTypeOptions = None 152 self._LoadFixAddress = None 153 self._RFCLanguages = None 154 self._ISOLanguages = None 155 self._VpdToolGuid = None 156 self.__Macros = None 157 158 159 ## handle Override Path of Module 160 def _HandleOverridePath(self): 161 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch] 162 Macros = self._Macros 163 Macros["EDK_SOURCE"] = GlobalData.gEcpSource 164 for Record in RecordList: 165 ModuleId = Record[5] 166 LineNo = Record[6] 167 ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch) 168 RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId] 169 if RecordList != []: 170 SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0])) 171 172 # Check if the source override path exists 173 if not os.path.isdir(SourceOverridePath): 174 EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo) 175 176 #Add to GlobalData Variables 177 GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath 178 179 ## Get current effective macros 180 def _GetMacros(self): 181 if self.__Macros == None: 182 self.__Macros = {} 183 self.__Macros.update(GlobalData.gPlatformDefines) 184 self.__Macros.update(GlobalData.gGlobalDefines) 185 self.__Macros.update(GlobalData.gCommandLineDefines) 186 return self.__Macros 187 188 ## Get architecture 189 def _GetArch(self): 190 return self._Arch 191 192 ## Set architecture 193 # 194 # Changing the default ARCH to another may affect all other information 195 # because all information in a platform may be ARCH-related. That's 196 # why we need to clear all internal used members, in order to cause all 197 # information to be re-retrieved. 198 # 199 # @param Value The value of ARCH 200 # 201 def _SetArch(self, Value): 202 if self._Arch == Value: 203 return 204 self._Arch = Value 205 self._Clear() 206 207 ## Retrieve all information in [Defines] section 208 # 209 # (Retriving all [Defines] information in one-shot is just to save time.) 210 # 211 def _GetHeaderInfo(self): 212 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch] 213 for Record in RecordList: 214 Name = Record[1] 215 # items defined _PROPERTY_ don't need additional processing 216 217 # some special items in [Defines] section need special treatment 218 if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY: 219 self._OutputDirectory = NormPath(Record[2], self._Macros) 220 if ' ' in self._OutputDirectory: 221 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY", 222 File=self.MetaFile, Line=Record[-1], 223 ExtraData=self._OutputDirectory) 224 elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION: 225 self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace) 226 ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf') 227 if ErrorCode != 0: 228 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1], 229 ExtraData=ErrorInfo) 230 elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES: 231 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT) 232 elif Name == TAB_DSC_DEFINES_BUILD_TARGETS: 233 self._BuildTargets = GetSplitValueList(Record[2]) 234 elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER: 235 if self._SkuName == None: 236 self._SkuName = Record[2] 237 self._SkuIdentifier = Record[2] 238 self._AvilableSkuIds = Record[2] 239 elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION: 240 self._PcdInfoFlag = Record[2] 241 elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION: 242 self._VarCheckFlag = Record[2] 243 elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS: 244 try: 245 self._LoadFixAddress = int (Record[2], 0) 246 except: 247 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2])) 248 elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES: 249 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1: 250 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"', 251 File=self.MetaFile, Line=Record[-1]) 252 LanguageCodes = Record[2][1:-1] 253 if not LanguageCodes: 254 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement', 255 File=self.MetaFile, Line=Record[-1]) 256 LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT) 257 # check whether there is empty entries in the list 258 if None in LanguageList: 259 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement', 260 File=self.MetaFile, Line=Record[-1]) 261 self._RFCLanguages = LanguageList 262 elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES: 263 if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1: 264 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"', 265 File=self.MetaFile, Line=Record[-1]) 266 LanguageCodes = Record[2][1:-1] 267 if not LanguageCodes: 268 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement', 269 File=self.MetaFile, Line=Record[-1]) 270 if len(LanguageCodes)%3: 271 EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES', 272 File=self.MetaFile, Line=Record[-1]) 273 LanguageList = [] 274 for i in range(0, len(LanguageCodes), 3): 275 LanguageList.append(LanguageCodes[i:i+3]) 276 self._ISOLanguages = LanguageList 277 elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID: 278 # 279 # try to convert GUID to a real UUID value to see whether the GUID is format 280 # for VPD_TOOL_GUID is correct. 281 # 282 try: 283 uuid.UUID(Record[2]) 284 except: 285 EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile) 286 self._VpdToolGuid = Record[2] 287 elif Name in self: 288 self[Name] = Record[2] 289 # set _Header to non-None in order to avoid database re-querying 290 self._Header = 'DUMMY' 291 292 ## Retrieve platform name 293 def _GetPlatformName(self): 294 if self._PlatformName == None: 295 if self._Header == None: 296 self._GetHeaderInfo() 297 if self._PlatformName == None: 298 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile) 299 return self._PlatformName 300 301 ## Retrieve file guid 302 def _GetFileGuid(self): 303 if self._Guid == None: 304 if self._Header == None: 305 self._GetHeaderInfo() 306 if self._Guid == None: 307 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile) 308 return self._Guid 309 310 ## Retrieve platform version 311 def _GetVersion(self): 312 if self._Version == None: 313 if self._Header == None: 314 self._GetHeaderInfo() 315 if self._Version == None: 316 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile) 317 return self._Version 318 319 ## Retrieve platform description file version 320 def _GetDscSpec(self): 321 if self._DscSpecification == None: 322 if self._Header == None: 323 self._GetHeaderInfo() 324 if self._DscSpecification == None: 325 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile) 326 return self._DscSpecification 327 328 ## Retrieve OUTPUT_DIRECTORY 329 def _GetOutpuDir(self): 330 if self._OutputDirectory == None: 331 if self._Header == None: 332 self._GetHeaderInfo() 333 if self._OutputDirectory == None: 334 self._OutputDirectory = os.path.join("Build", self._PlatformName) 335 return self._OutputDirectory 336 337 ## Retrieve SUPPORTED_ARCHITECTURES 338 def _GetSupArch(self): 339 if self._SupArchList == None: 340 if self._Header == None: 341 self._GetHeaderInfo() 342 if self._SupArchList == None: 343 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile) 344 return self._SupArchList 345 346 ## Retrieve BUILD_TARGETS 347 def _GetBuildTarget(self): 348 if self._BuildTargets == None: 349 if self._Header == None: 350 self._GetHeaderInfo() 351 if self._BuildTargets == None: 352 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile) 353 return self._BuildTargets 354 355 def _GetPcdInfoFlag(self): 356 if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE': 357 return False 358 elif self._PcdInfoFlag.upper() == 'TRUE': 359 return True 360 else: 361 return False 362 def _GetVarCheckFlag(self): 363 if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE': 364 return False 365 elif self._VarCheckFlag.upper() == 'TRUE': 366 return True 367 else: 368 return False 369 def _GetAviableSkuIds(self): 370 if self._AvilableSkuIds: 371 return self._AvilableSkuIds 372 return self.SkuIdentifier 373 def _GetSkuIdentifier(self): 374 if self._SkuName: 375 return self._SkuName 376 if self._SkuIdentifier == None: 377 if self._Header == None: 378 self._GetHeaderInfo() 379 return self._SkuIdentifier 380 ## Retrieve SKUID_IDENTIFIER 381 def _GetSkuName(self): 382 if self._SkuName == None: 383 if self._Header == None: 384 self._GetHeaderInfo() 385 if (self._SkuName == None or self._SkuName not in self.SkuIds): 386 self._SkuName = 'DEFAULT' 387 return self._SkuName 388 389 ## Override SKUID_IDENTIFIER 390 def _SetSkuName(self, Value): 391 self._SkuName = Value 392 self._Pcds = None 393 394 def _GetFdfFile(self): 395 if self._FlashDefinition == None: 396 if self._Header == None: 397 self._GetHeaderInfo() 398 if self._FlashDefinition == None: 399 self._FlashDefinition = '' 400 return self._FlashDefinition 401 402 ## Retrieve FLASH_DEFINITION 403 def _GetBuildNumber(self): 404 if self._BuildNumber == None: 405 if self._Header == None: 406 self._GetHeaderInfo() 407 if self._BuildNumber == None: 408 self._BuildNumber = '' 409 return self._BuildNumber 410 411 ## Retrieve MAKEFILE_NAME 412 def _GetMakefileName(self): 413 if self._MakefileName == None: 414 if self._Header == None: 415 self._GetHeaderInfo() 416 if self._MakefileName == None: 417 self._MakefileName = '' 418 return self._MakefileName 419 420 ## Retrieve BsBaseAddress 421 def _GetBsBaseAddress(self): 422 if self._BsBaseAddress == None: 423 if self._Header == None: 424 self._GetHeaderInfo() 425 if self._BsBaseAddress == None: 426 self._BsBaseAddress = '' 427 return self._BsBaseAddress 428 429 ## Retrieve RtBaseAddress 430 def _GetRtBaseAddress(self): 431 if self._RtBaseAddress == None: 432 if self._Header == None: 433 self._GetHeaderInfo() 434 if self._RtBaseAddress == None: 435 self._RtBaseAddress = '' 436 return self._RtBaseAddress 437 438 ## Retrieve the top address for the load fix address 439 def _GetLoadFixAddress(self): 440 if self._LoadFixAddress == None: 441 if self._Header == None: 442 self._GetHeaderInfo() 443 444 if self._LoadFixAddress == None: 445 self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0') 446 447 try: 448 self._LoadFixAddress = int (self._LoadFixAddress, 0) 449 except: 450 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress)) 451 452 # 453 # If command line defined, should override the value in DSC file. 454 # 455 if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys(): 456 try: 457 self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0) 458 except: 459 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'])) 460 461 if self._LoadFixAddress < 0: 462 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress)) 463 if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0: 464 EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress)) 465 466 return self._LoadFixAddress 467 468 ## Retrieve RFCLanguage filter 469 def _GetRFCLanguages(self): 470 if self._RFCLanguages == None: 471 if self._Header == None: 472 self._GetHeaderInfo() 473 if self._RFCLanguages == None: 474 self._RFCLanguages = [] 475 return self._RFCLanguages 476 477 ## Retrieve ISOLanguage filter 478 def _GetISOLanguages(self): 479 if self._ISOLanguages == None: 480 if self._Header == None: 481 self._GetHeaderInfo() 482 if self._ISOLanguages == None: 483 self._ISOLanguages = [] 484 return self._ISOLanguages 485 ## Retrieve the GUID string for VPD tool 486 def _GetVpdToolGuid(self): 487 if self._VpdToolGuid == None: 488 if self._Header == None: 489 self._GetHeaderInfo() 490 if self._VpdToolGuid == None: 491 self._VpdToolGuid = '' 492 return self._VpdToolGuid 493 494 ## Retrieve [SkuIds] section information 495 def _GetSkuIds(self): 496 if self._SkuIds == None: 497 self._SkuIds = sdict() 498 RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch] 499 for Record in RecordList: 500 if Record[0] in [None, '']: 501 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number', 502 File=self.MetaFile, Line=Record[-1]) 503 if Record[1] in [None, '']: 504 EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name', 505 File=self.MetaFile, Line=Record[-1]) 506 self._SkuIds[Record[1]] = Record[0] 507 if 'DEFAULT' not in self._SkuIds: 508 self._SkuIds['DEFAULT'] = '0' 509 if 'COMMON' not in self._SkuIds: 510 self._SkuIds['COMMON'] = '0' 511 return self._SkuIds 512 513 ## Retrieve [Components] section information 514 def _GetModules(self): 515 if self._Modules != None: 516 return self._Modules 517 518 self._Modules = sdict() 519 RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch] 520 Macros = self._Macros 521 Macros["EDK_SOURCE"] = GlobalData.gEcpSource 522 for Record in RecordList: 523 DuplicatedFile = False 524 ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) 525 ModuleId = Record[5] 526 LineNo = Record[6] 527 528 # check the file validation 529 ErrorCode, ErrorInfo = ModuleFile.Validate('.inf') 530 if ErrorCode != 0: 531 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, 532 ExtraData=ErrorInfo) 533 # Check duplication 534 # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected 535 if self._Arch != 'COMMON' and ModuleFile in self._Modules: 536 DuplicatedFile = True 537 538 Module = ModuleBuildClassObject() 539 Module.MetaFile = ModuleFile 540 541 # get module private library instance 542 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId] 543 for Record in RecordList: 544 LibraryClass = Record[0] 545 LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch) 546 LineNo = Record[-1] 547 548 # check the file validation 549 ErrorCode, ErrorInfo = LibraryPath.Validate('.inf') 550 if ErrorCode != 0: 551 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, 552 ExtraData=ErrorInfo) 553 554 if LibraryClass == '' or LibraryClass == 'NULL': 555 self._NullLibraryNumber += 1 556 LibraryClass = 'NULL%d' % self._NullLibraryNumber 557 EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass)) 558 Module.LibraryClasses[LibraryClass] = LibraryPath 559 if LibraryPath not in self.LibraryInstances: 560 self.LibraryInstances.append(LibraryPath) 561 562 # get module private PCD setting 563 for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \ 564 MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]: 565 RecordList = self._RawData[Type, self._Arch, None, ModuleId] 566 for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList: 567 TokenList = GetSplitValueList(Setting) 568 DefaultValue = TokenList[0] 569 if len(TokenList) > 1: 570 MaxDatumSize = TokenList[1] 571 else: 572 MaxDatumSize = '' 573 TypeString = self._PCD_TYPE_STRING_[Type] 574 Pcd = PcdClassObject( 575 PcdCName, 576 TokenSpaceGuid, 577 TypeString, 578 '', 579 DefaultValue, 580 '', 581 MaxDatumSize, 582 {}, 583 False, 584 None 585 ) 586 Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd 587 588 # get module private build options 589 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId] 590 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList: 591 if (ToolChainFamily, ToolChain) not in Module.BuildOptions: 592 Module.BuildOptions[ToolChainFamily, ToolChain] = Option 593 else: 594 OptionString = Module.BuildOptions[ToolChainFamily, ToolChain] 595 Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option 596 597 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId] 598 if DuplicatedFile and not RecordList: 599 EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo) 600 if RecordList: 601 if len(RecordList) != 1: 602 EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in <Defines> section.', 603 File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo) 604 ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace) 605 ModuleFile.Arch = self._Arch 606 607 self._Modules[ModuleFile] = Module 608 return self._Modules 609 610 ## Retrieve all possible library instances used in this platform 611 def _GetLibraryInstances(self): 612 if self._LibraryInstances == None: 613 self._GetLibraryClasses() 614 return self._LibraryInstances 615 616 ## Retrieve [LibraryClasses] information 617 def _GetLibraryClasses(self): 618 if self._LibraryClasses == None: 619 self._LibraryInstances = [] 620 # 621 # tdict is a special dict kind of type, used for selecting correct 622 # library instance for given library class and module type 623 # 624 LibraryClassDict = tdict(True, 3) 625 # track all library class names 626 LibraryClassSet = set() 627 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1] 628 Macros = self._Macros 629 for Record in RecordList: 630 LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record 631 if LibraryClass == '' or LibraryClass == 'NULL': 632 self._NullLibraryNumber += 1 633 LibraryClass = 'NULL%d' % self._NullLibraryNumber 634 EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass)) 635 LibraryClassSet.add(LibraryClass) 636 LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch) 637 # check the file validation 638 ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf') 639 if ErrorCode != 0: 640 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, 641 ExtraData=ErrorInfo) 642 643 if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST: 644 EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType, 645 File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo) 646 LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance 647 if LibraryInstance not in self._LibraryInstances: 648 self._LibraryInstances.append(LibraryInstance) 649 650 # resolve the specific library instance for each class and each module type 651 self._LibraryClasses = tdict(True) 652 for LibraryClass in LibraryClassSet: 653 # try all possible module types 654 for ModuleType in SUP_MODULE_LIST: 655 LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass] 656 if LibraryInstance == None: 657 continue 658 self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance 659 660 # for Edk style library instances, which are listed in different section 661 Macros["EDK_SOURCE"] = GlobalData.gEcpSource 662 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch] 663 for Record in RecordList: 664 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) 665 LineNo = Record[-1] 666 # check the file validation 667 ErrorCode, ErrorInfo = File.Validate('.inf') 668 if ErrorCode != 0: 669 EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, 670 ExtraData=ErrorInfo) 671 if File not in self._LibraryInstances: 672 self._LibraryInstances.append(File) 673 # 674 # we need the module name as the library class name, so we have 675 # to parse it here. (self._Bdb[] will trigger a file parse if it 676 # hasn't been parsed) 677 # 678 Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain] 679 self._LibraryClasses[Library.BaseName, ':dummy:'] = Library 680 return self._LibraryClasses 681 682 def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo): 683 if self._DecPcds == None: 684 self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain) 685 FdfInfList = [] 686 if GlobalData.gFdfParser: 687 FdfInfList = GlobalData.gFdfParser.Profile.InfList 688 689 PkgSet = set() 690 for Inf in FdfInfList: 691 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch) 692 if ModuleFile in self._Modules: 693 continue 694 ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain] 695 PkgSet.update(ModuleData.Packages) 696 DecPcds = {} 697 for Pkg in PkgSet: 698 for Pcd in Pkg.Pcds: 699 DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd] 700 self._DecPcds.update(DecPcds) 701 702 if (PcdCName, TokenSpaceGuid) not in self._DecPcds: 703 EdkLogger.error('build', PARSER_ERROR, 704 "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch), 705 File=self.MetaFile, Line=LineNo) 706 ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType) 707 if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]: 708 EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo, 709 ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting)) 710 if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]: 711 try: 712 ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True) 713 except WrnExpression, Value: 714 ValueList[Index] = Value.result 715 except EvaluationException, Excpt: 716 if hasattr(Excpt, 'Pcd'): 717 if Excpt.Pcd in GlobalData.gPlatformOtherPcds: 718 EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as" 719 " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section" 720 " of the DSC file" % Excpt.Pcd, 721 File=self.MetaFile, Line=LineNo) 722 else: 723 EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd, 724 File=self.MetaFile, Line=LineNo) 725 else: 726 EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt), 727 File=self.MetaFile, Line=LineNo) 728 if ValueList[Index] == 'True': 729 ValueList[Index] = '1' 730 elif ValueList[Index] == 'False': 731 ValueList[Index] = '0' 732 if ValueList[Index]: 733 Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index]) 734 if not Valid: 735 EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo, 736 ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName)) 737 return ValueList 738 739 ## Retrieve all PCD settings in platform 740 def _GetPcds(self): 741 if self._Pcds == None: 742 self._Pcds = sdict() 743 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD)) 744 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE)) 745 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG)) 746 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT)) 747 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII)) 748 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD)) 749 self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT)) 750 self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII)) 751 self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD)) 752 return self._Pcds 753 754 ## Retrieve [BuildOptions] 755 def _GetBuildOptions(self): 756 if self._BuildOptions == None: 757 self._BuildOptions = sdict() 758 # 759 # Retrieve build option for EDKII and EDK style module 760 # 761 for CodeBase in (EDKII_NAME, EDK_NAME): 762 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase] 763 for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList: 764 CurKey = (ToolChainFamily, ToolChain, CodeBase) 765 # 766 # Only flags can be appended 767 # 768 if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='): 769 self._BuildOptions[CurKey] = Option 770 else: 771 self._BuildOptions[CurKey] += ' ' + Option 772 return self._BuildOptions 773 774 def GetBuildOptionsByModuleType(self, Edk, ModuleType): 775 if self._ModuleTypeOptions == None: 776 self._ModuleTypeOptions = sdict() 777 if (Edk, ModuleType) not in self._ModuleTypeOptions: 778 options = sdict() 779 self._ModuleTypeOptions[Edk, ModuleType] = options 780 DriverType = '%s.%s' % (Edk, ModuleType) 781 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType] 782 for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList: 783 if Type == DriverType: 784 Key = (ToolChainFamily, ToolChain, Edk) 785 if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='): 786 options[Key] = Option 787 else: 788 options[Key] += ' ' + Option 789 return self._ModuleTypeOptions[Edk, ModuleType] 790 791 ## Retrieve non-dynamic PCD settings 792 # 793 # @param Type PCD type 794 # 795 # @retval a dict object contains settings of given PCD type 796 # 797 def _GetPcd(self, Type): 798 Pcds = sdict() 799 # 800 # tdict is a special dict kind of type, used for selecting correct 801 # PCD settings for certain ARCH 802 # 803 804 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds) 805 806 PcdDict = tdict(True, 3) 807 PcdSet = set() 808 # Find out all possible PCD candidates for self._Arch 809 RecordList = self._RawData[Type, self._Arch] 810 PcdValueDict = sdict() 811 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: 812 if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'): 813 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4)) 814 PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting 815 816 #handle pcd value override 817 for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet: 818 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName] 819 if Setting == None: 820 continue 821 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) 822 if (PcdCName, TokenSpaceGuid) in PcdValueDict: 823 PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize) 824 else: 825 PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)} 826 827 PcdsKeys = PcdValueDict.keys() 828 for PcdCName,TokenSpaceGuid in PcdsKeys: 829 830 PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid] 831 PcdValue = None 832 DatumType = None 833 MaxDatumSize = None 834 if 'COMMON' in PcdSetting: 835 PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON'] 836 if 'DEFAULT' in PcdSetting: 837 PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT'] 838 if SkuObj.SystemSkuId in PcdSetting: 839 PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId] 840 841 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( 842 PcdCName, 843 TokenSpaceGuid, 844 self._PCD_TYPE_STRING_[Type], 845 DatumType, 846 PcdValue, 847 '', 848 MaxDatumSize, 849 {}, 850 False, 851 None 852 ) 853 return Pcds 854 855 ## Retrieve dynamic PCD settings 856 # 857 # @param Type PCD type 858 # 859 # @retval a dict object contains settings of given PCD type 860 # 861 def _GetDynamicPcd(self, Type): 862 863 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds) 864 865 Pcds = sdict() 866 # 867 # tdict is a special dict kind of type, used for selecting correct 868 # PCD settings for certain ARCH and SKU 869 # 870 PcdDict = tdict(True, 4) 871 PcdList = [] 872 # Find out all possible PCD candidates for self._Arch 873 RecordList = self._RawData[Type, self._Arch] 874 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy() 875 876 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0}) 877 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: 878 if SkuName not in AvailableSkuIdSet: 879 continue 880 881 PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4)) 882 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting 883 # Remove redundant PCD candidates, per the ARCH and SKU 884 for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList: 885 886 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid] 887 if Setting == None: 888 continue 889 890 PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) 891 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue) 892 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): 893 pcdObject = Pcds[PcdCName,TokenSpaceGuid] 894 pcdObject.SkuInfoList[SkuName] = SkuInfo 895 if MaxDatumSize.strip(): 896 CurrentMaxSize = int(MaxDatumSize.strip(),0) 897 else: 898 CurrentMaxSize = 0 899 if pcdObject.MaxDatumSize: 900 PcdMaxSize = int(pcdObject.MaxDatumSize,0) 901 else: 902 PcdMaxSize = 0 903 if CurrentMaxSize > PcdMaxSize: 904 pcdObject.MaxDatumSize = str(CurrentMaxSize) 905 else: 906 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( 907 PcdCName, 908 TokenSpaceGuid, 909 self._PCD_TYPE_STRING_[Type], 910 DatumType, 911 PcdValue, 912 '', 913 MaxDatumSize, 914 {SkuName : SkuInfo}, 915 False, 916 None 917 ) 918 919 for pcd in Pcds.values(): 920 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName] 921 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): 922 valuefromDec = pcdDecObject.DefaultValue 923 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec) 924 pcd.SkuInfoList['DEFAULT'] = SkuInfo 925 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): 926 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON'] 927 del(pcd.SkuInfoList['COMMON']) 928 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): 929 del(pcd.SkuInfoList['COMMON']) 930 if SkuObj.SkuUsageType == SkuObj.SINGLE: 931 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys(): 932 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] 933 del(pcd.SkuInfoList['DEFAULT']) 934 935 return Pcds 936 937 def CompareVarAttr(self, Attr1, Attr2): 938 if not Attr1 or not Attr2: # for empty string 939 return True 940 Attr1s = [attr.strip() for attr in Attr1.split(",")] 941 Attr1Set = set(Attr1s) 942 Attr2s = [attr.strip() for attr in Attr2.split(",")] 943 Attr2Set = set(Attr2s) 944 if Attr2Set == Attr1Set: 945 return True 946 else: 947 return False 948 ## Retrieve dynamic HII PCD settings 949 # 950 # @param Type PCD type 951 # 952 # @retval a dict object contains settings of given PCD type 953 # 954 def _GetDynamicHiiPcd(self, Type): 955 956 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds) 957 VariableAttrs = {} 958 959 Pcds = sdict() 960 # 961 # tdict is a special dict kind of type, used for selecting correct 962 # PCD settings for certain ARCH and SKU 963 # 964 PcdDict = tdict(True, 4) 965 PcdSet = set() 966 RecordList = self._RawData[Type, self._Arch] 967 # Find out all possible PCD candidates for self._Arch 968 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy() 969 970 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0}) 971 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: 972 if SkuName not in AvailableSkuIdSet: 973 continue 974 PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4)) 975 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting 976 # Remove redundant PCD candidates, per the ARCH and SKU 977 for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet: 978 979 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid] 980 if Setting == None: 981 continue 982 VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) 983 984 rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute) 985 if not rt: 986 EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg), 987 ExtraData = "[%s]" % VarAttribute) 988 ExceedMax = False 989 FormatCorrect = True 990 if VariableOffset.isdigit(): 991 if int(VariableOffset,10) > 0xFFFF: 992 ExceedMax = True 993 elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset): 994 if int(VariableOffset,16) > 0xFFFF: 995 ExceedMax = True 996 # For Offset written in "A.B" 997 elif VariableOffset.find('.') > -1: 998 VariableOffsetList = VariableOffset.split(".") 999 if not (len(VariableOffsetList) == 2 1000 and IsValidWord(VariableOffsetList[0]) 1001 and IsValidWord(VariableOffsetList[1])): 1002 FormatCorrect = False 1003 else: 1004 FormatCorrect = False 1005 if not FormatCorrect: 1006 EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid,PcdCName))) 1007 1008 if ExceedMax: 1009 EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName))) 1010 if (VariableName, VariableGuid) not in VariableAttrs: 1011 VariableAttrs[(VariableName, VariableGuid)] = VarAttribute 1012 else: 1013 if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute): 1014 EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)])) 1015 1016 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute) 1017 pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid] 1018 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): 1019 pcdObject = Pcds[PcdCName,TokenSpaceGuid] 1020 pcdObject.SkuInfoList[SkuName] = SkuInfo 1021 else: 1022 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( 1023 PcdCName, 1024 TokenSpaceGuid, 1025 self._PCD_TYPE_STRING_[Type], 1026 '', 1027 DefaultValue, 1028 '', 1029 '', 1030 {SkuName : SkuInfo}, 1031 False, 1032 None, 1033 pcdDecObject.validateranges, 1034 pcdDecObject.validlists, 1035 pcdDecObject.expressions 1036 ) 1037 1038 1039 for pcd in Pcds.values(): 1040 SkuInfoObj = pcd.SkuInfoList.values()[0] 1041 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName] 1042 # Only fix the value while no value provided in DSC file. 1043 for sku in pcd.SkuInfoList.values(): 1044 if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue==None): 1045 sku.HiiDefaultValue = pcdDecObject.DefaultValue 1046 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): 1047 valuefromDec = pcdDecObject.DefaultValue 1048 SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec) 1049 pcd.SkuInfoList['DEFAULT'] = SkuInfo 1050 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): 1051 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON'] 1052 del(pcd.SkuInfoList['COMMON']) 1053 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): 1054 del(pcd.SkuInfoList['COMMON']) 1055 1056 if SkuObj.SkuUsageType == SkuObj.SINGLE: 1057 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys(): 1058 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] 1059 del(pcd.SkuInfoList['DEFAULT']) 1060 1061 1062 if pcd.MaxDatumSize.strip(): 1063 MaxSize = int(pcd.MaxDatumSize,0) 1064 else: 1065 MaxSize = 0 1066 if pcdDecObject.DatumType == 'VOID*': 1067 for (skuname,skuobj) in pcd.SkuInfoList.items(): 1068 datalen = 0 1069 if skuobj.HiiDefaultValue.startswith("L"): 1070 datalen = (len(skuobj.HiiDefaultValue)- 3 + 1) * 2 1071 elif skuobj.HiiDefaultValue.startswith("{"): 1072 datalen = len(skuobj.HiiDefaultValue.split(",")) 1073 else: 1074 datalen = len(skuobj.HiiDefaultValue) -2 + 1 1075 if datalen>MaxSize: 1076 MaxSize = datalen 1077 pcd.MaxDatumSize = str(MaxSize) 1078 return Pcds 1079 1080 ## Retrieve dynamic VPD PCD settings 1081 # 1082 # @param Type PCD type 1083 # 1084 # @retval a dict object contains settings of given PCD type 1085 # 1086 def _GetDynamicVpdPcd(self, Type): 1087 1088 SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds) 1089 1090 Pcds = sdict() 1091 # 1092 # tdict is a special dict kind of type, used for selecting correct 1093 # PCD settings for certain ARCH and SKU 1094 # 1095 PcdDict = tdict(True, 4) 1096 PcdList = [] 1097 # Find out all possible PCD candidates for self._Arch 1098 RecordList = self._RawData[Type, self._Arch] 1099 AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy() 1100 1101 AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0}) 1102 for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList: 1103 if SkuName not in AvailableSkuIdSet: 1104 continue 1105 1106 PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4)) 1107 PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting 1108 # Remove redundant PCD candidates, per the ARCH and SKU 1109 for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList: 1110 Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid] 1111 if Setting == None: 1112 continue 1113 # 1114 # For the VOID* type, it can have optional data of MaxDatumSize and InitialValue 1115 # For the Integer & Boolean type, the optional data can only be InitialValue. 1116 # At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype 1117 # until the DEC parser has been called. 1118 # 1119 VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) 1120 SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue) 1121 if (PcdCName,TokenSpaceGuid) in Pcds.keys(): 1122 pcdObject = Pcds[PcdCName,TokenSpaceGuid] 1123 pcdObject.SkuInfoList[SkuName] = SkuInfo 1124 if MaxDatumSize.strip(): 1125 CurrentMaxSize = int(MaxDatumSize.strip(),0) 1126 else: 1127 CurrentMaxSize = 0 1128 if pcdObject.MaxDatumSize: 1129 PcdMaxSize = int(pcdObject.MaxDatumSize,0) 1130 else: 1131 PcdMaxSize = 0 1132 if CurrentMaxSize > PcdMaxSize: 1133 pcdObject.MaxDatumSize = str(CurrentMaxSize) 1134 else: 1135 Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( 1136 PcdCName, 1137 TokenSpaceGuid, 1138 self._PCD_TYPE_STRING_[Type], 1139 '', 1140 InitialValue, 1141 '', 1142 MaxDatumSize, 1143 {SkuName : SkuInfo}, 1144 False, 1145 None 1146 ) 1147 for pcd in Pcds.values(): 1148 SkuInfoObj = pcd.SkuInfoList.values()[0] 1149 pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName] 1150 if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys(): 1151 valuefromDec = pcdDecObject.DefaultValue 1152 SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec) 1153 pcd.SkuInfoList['DEFAULT'] = SkuInfo 1154 elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): 1155 pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON'] 1156 del(pcd.SkuInfoList['COMMON']) 1157 elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys(): 1158 del(pcd.SkuInfoList['COMMON']) 1159 if SkuObj.SkuUsageType == SkuObj.SINGLE: 1160 if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys(): 1161 pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] 1162 del(pcd.SkuInfoList['DEFAULT']) 1163 1164 return Pcds 1165 1166 ## Add external modules 1167 # 1168 # The external modules are mostly those listed in FDF file, which don't 1169 # need "build". 1170 # 1171 # @param FilePath The path of module description file 1172 # 1173 def AddModule(self, FilePath): 1174 FilePath = NormPath(FilePath) 1175 if FilePath not in self.Modules: 1176 Module = ModuleBuildClassObject() 1177 Module.MetaFile = FilePath 1178 self.Modules.append(Module) 1179 1180 ## Add external PCDs 1181 # 1182 # The external PCDs are mostly those listed in FDF file to specify address 1183 # or offset information. 1184 # 1185 # @param Name Name of the PCD 1186 # @param Guid Token space guid of the PCD 1187 # @param Value Value of the PCD 1188 # 1189 def AddPcd(self, Name, Guid, Value): 1190 if (Name, Guid) not in self.Pcds: 1191 self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None) 1192 self.Pcds[Name, Guid].DefaultValue = Value 1193 1194 _Macros = property(_GetMacros) 1195 Arch = property(_GetArch, _SetArch) 1196 Platform = property(_GetPlatformName) 1197 PlatformName = property(_GetPlatformName) 1198 Guid = property(_GetFileGuid) 1199 Version = property(_GetVersion) 1200 DscSpecification = property(_GetDscSpec) 1201 OutputDirectory = property(_GetOutpuDir) 1202 SupArchList = property(_GetSupArch) 1203 BuildTargets = property(_GetBuildTarget) 1204 SkuName = property(_GetSkuName, _SetSkuName) 1205 SkuIdentifier = property(_GetSkuIdentifier) 1206 AvilableSkuIds = property(_GetAviableSkuIds) 1207 PcdInfoFlag = property(_GetPcdInfoFlag) 1208 VarCheckFlag = property(_GetVarCheckFlag) 1209 FlashDefinition = property(_GetFdfFile) 1210 BuildNumber = property(_GetBuildNumber) 1211 MakefileName = property(_GetMakefileName) 1212 BsBaseAddress = property(_GetBsBaseAddress) 1213 RtBaseAddress = property(_GetRtBaseAddress) 1214 LoadFixAddress = property(_GetLoadFixAddress) 1215 RFCLanguages = property(_GetRFCLanguages) 1216 ISOLanguages = property(_GetISOLanguages) 1217 VpdToolGuid = property(_GetVpdToolGuid) 1218 SkuIds = property(_GetSkuIds) 1219 Modules = property(_GetModules) 1220 LibraryInstances = property(_GetLibraryInstances) 1221 LibraryClasses = property(_GetLibraryClasses) 1222 Pcds = property(_GetPcds) 1223 BuildOptions = property(_GetBuildOptions) 1224 1225## Platform build information from DEC file 1226# 1227# This class is used to retrieve information stored in database and convert them 1228# into PackageBuildClassObject form for easier use for AutoGen. 1229# 1230class DecBuildData(PackageBuildClassObject): 1231 # dict used to convert PCD type in database to string used by build tool 1232 _PCD_TYPE_STRING_ = { 1233 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild", 1234 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule", 1235 MODEL_PCD_FEATURE_FLAG : "FeatureFlag", 1236 MODEL_PCD_DYNAMIC : "Dynamic", 1237 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic", 1238 MODEL_PCD_DYNAMIC_HII : "DynamicHii", 1239 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd", 1240 MODEL_PCD_DYNAMIC_EX : "DynamicEx", 1241 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx", 1242 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii", 1243 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd", 1244 } 1245 1246 # dict used to convert part of [Defines] to members of DecBuildData directly 1247 _PROPERTY_ = { 1248 # 1249 # Required Fields 1250 # 1251 TAB_DEC_DEFINES_PACKAGE_NAME : "_PackageName", 1252 TAB_DEC_DEFINES_PACKAGE_GUID : "_Guid", 1253 TAB_DEC_DEFINES_PACKAGE_VERSION : "_Version", 1254 TAB_DEC_DEFINES_PKG_UNI_FILE : "_PkgUniFile", 1255 } 1256 1257 1258 ## Constructor of DecBuildData 1259 # 1260 # Initialize object of DecBuildData 1261 # 1262 # @param FilePath The path of package description file 1263 # @param RawData The raw data of DEC file 1264 # @param BuildDataBase Database used to retrieve module information 1265 # @param Arch The target architecture 1266 # @param Platform (not used for DecBuildData) 1267 # @param Macros Macros used for replacement in DSC file 1268 # 1269 def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None): 1270 self.MetaFile = File 1271 self._PackageDir = File.Dir 1272 self._RawData = RawData 1273 self._Bdb = BuildDataBase 1274 self._Arch = Arch 1275 self._Target = Target 1276 self._Toolchain = Toolchain 1277 self._Clear() 1278 1279 ## XXX[key] = value 1280 def __setitem__(self, key, value): 1281 self.__dict__[self._PROPERTY_[key]] = value 1282 1283 ## value = XXX[key] 1284 def __getitem__(self, key): 1285 return self.__dict__[self._PROPERTY_[key]] 1286 1287 ## "in" test support 1288 def __contains__(self, key): 1289 return key in self._PROPERTY_ 1290 1291 ## Set all internal used members of DecBuildData to None 1292 def _Clear(self): 1293 self._Header = None 1294 self._PackageName = None 1295 self._Guid = None 1296 self._Version = None 1297 self._PkgUniFile = None 1298 self._Protocols = None 1299 self._Ppis = None 1300 self._Guids = None 1301 self._Includes = None 1302 self._LibraryClasses = None 1303 self._Pcds = None 1304 self.__Macros = None 1305 1306 ## Get current effective macros 1307 def _GetMacros(self): 1308 if self.__Macros == None: 1309 self.__Macros = {} 1310 self.__Macros.update(GlobalData.gGlobalDefines) 1311 return self.__Macros 1312 1313 ## Get architecture 1314 def _GetArch(self): 1315 return self._Arch 1316 1317 ## Set architecture 1318 # 1319 # Changing the default ARCH to another may affect all other information 1320 # because all information in a platform may be ARCH-related. That's 1321 # why we need to clear all internal used members, in order to cause all 1322 # information to be re-retrieved. 1323 # 1324 # @param Value The value of ARCH 1325 # 1326 def _SetArch(self, Value): 1327 if self._Arch == Value: 1328 return 1329 self._Arch = Value 1330 self._Clear() 1331 1332 ## Retrieve all information in [Defines] section 1333 # 1334 # (Retriving all [Defines] information in one-shot is just to save time.) 1335 # 1336 def _GetHeaderInfo(self): 1337 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch] 1338 for Record in RecordList: 1339 Name = Record[1] 1340 if Name in self: 1341 self[Name] = Record[2] 1342 self._Header = 'DUMMY' 1343 1344 ## Retrieve package name 1345 def _GetPackageName(self): 1346 if self._PackageName == None: 1347 if self._Header == None: 1348 self._GetHeaderInfo() 1349 if self._PackageName == None: 1350 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_NAME", File=self.MetaFile) 1351 return self._PackageName 1352 1353 ## Retrieve file guid 1354 def _GetFileGuid(self): 1355 if self._Guid == None: 1356 if self._Header == None: 1357 self._GetHeaderInfo() 1358 if self._Guid == None: 1359 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "No PACKAGE_GUID", File=self.MetaFile) 1360 return self._Guid 1361 1362 ## Retrieve package version 1363 def _GetVersion(self): 1364 if self._Version == None: 1365 if self._Header == None: 1366 self._GetHeaderInfo() 1367 if self._Version == None: 1368 self._Version = '' 1369 return self._Version 1370 1371 ## Retrieve protocol definitions (name/value pairs) 1372 def _GetProtocol(self): 1373 if self._Protocols == None: 1374 # 1375 # tdict is a special kind of dict, used for selecting correct 1376 # protocol defition for given ARCH 1377 # 1378 ProtocolDict = tdict(True) 1379 NameList = [] 1380 # find out all protocol definitions for specific and 'common' arch 1381 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch] 1382 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList: 1383 if Name not in NameList: 1384 NameList.append(Name) 1385 ProtocolDict[Arch, Name] = Guid 1386 # use sdict to keep the order 1387 self._Protocols = sdict() 1388 for Name in NameList: 1389 # 1390 # limit the ARCH to self._Arch, if no self._Arch found, tdict 1391 # will automatically turn to 'common' ARCH for trying 1392 # 1393 self._Protocols[Name] = ProtocolDict[self._Arch, Name] 1394 return self._Protocols 1395 1396 ## Retrieve PPI definitions (name/value pairs) 1397 def _GetPpi(self): 1398 if self._Ppis == None: 1399 # 1400 # tdict is a special kind of dict, used for selecting correct 1401 # PPI defition for given ARCH 1402 # 1403 PpiDict = tdict(True) 1404 NameList = [] 1405 # find out all PPI definitions for specific arch and 'common' arch 1406 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch] 1407 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList: 1408 if Name not in NameList: 1409 NameList.append(Name) 1410 PpiDict[Arch, Name] = Guid 1411 # use sdict to keep the order 1412 self._Ppis = sdict() 1413 for Name in NameList: 1414 # 1415 # limit the ARCH to self._Arch, if no self._Arch found, tdict 1416 # will automatically turn to 'common' ARCH for trying 1417 # 1418 self._Ppis[Name] = PpiDict[self._Arch, Name] 1419 return self._Ppis 1420 1421 ## Retrieve GUID definitions (name/value pairs) 1422 def _GetGuid(self): 1423 if self._Guids == None: 1424 # 1425 # tdict is a special kind of dict, used for selecting correct 1426 # GUID defition for given ARCH 1427 # 1428 GuidDict = tdict(True) 1429 NameList = [] 1430 # find out all protocol definitions for specific and 'common' arch 1431 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch] 1432 for Name, Guid, Dummy, Arch, ID, LineNo in RecordList: 1433 if Name not in NameList: 1434 NameList.append(Name) 1435 GuidDict[Arch, Name] = Guid 1436 # use sdict to keep the order 1437 self._Guids = sdict() 1438 for Name in NameList: 1439 # 1440 # limit the ARCH to self._Arch, if no self._Arch found, tdict 1441 # will automatically turn to 'common' ARCH for trying 1442 # 1443 self._Guids[Name] = GuidDict[self._Arch, Name] 1444 return self._Guids 1445 1446 ## Retrieve public include paths declared in this package 1447 def _GetInclude(self): 1448 if self._Includes == None: 1449 self._Includes = [] 1450 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch] 1451 Macros = self._Macros 1452 Macros["EDK_SOURCE"] = GlobalData.gEcpSource 1453 for Record in RecordList: 1454 File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch) 1455 LineNo = Record[-1] 1456 # validate the path 1457 ErrorCode, ErrorInfo = File.Validate() 1458 if ErrorCode != 0: 1459 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) 1460 1461 # avoid duplicate include path 1462 if File not in self._Includes: 1463 self._Includes.append(File) 1464 return self._Includes 1465 1466 ## Retrieve library class declarations (not used in build at present) 1467 def _GetLibraryClass(self): 1468 if self._LibraryClasses == None: 1469 # 1470 # tdict is a special kind of dict, used for selecting correct 1471 # library class declaration for given ARCH 1472 # 1473 LibraryClassDict = tdict(True) 1474 LibraryClassSet = set() 1475 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch] 1476 Macros = self._Macros 1477 for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList: 1478 File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch) 1479 # check the file validation 1480 ErrorCode, ErrorInfo = File.Validate() 1481 if ErrorCode != 0: 1482 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) 1483 LibraryClassSet.add(LibraryClass) 1484 LibraryClassDict[Arch, LibraryClass] = File 1485 self._LibraryClasses = sdict() 1486 for LibraryClass in LibraryClassSet: 1487 self._LibraryClasses[LibraryClass] = LibraryClassDict[self._Arch, LibraryClass] 1488 return self._LibraryClasses 1489 1490 ## Retrieve PCD declarations 1491 def _GetPcds(self): 1492 if self._Pcds == None: 1493 self._Pcds = sdict() 1494 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD)) 1495 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE)) 1496 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG)) 1497 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC)) 1498 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX)) 1499 return self._Pcds 1500 1501 ## Retrieve PCD declarations for given type 1502 def _GetPcd(self, Type): 1503 Pcds = sdict() 1504 # 1505 # tdict is a special kind of dict, used for selecting correct 1506 # PCD declaration for given ARCH 1507 # 1508 PcdDict = tdict(True, 3) 1509 # for summarizing PCD 1510 PcdSet = set() 1511 # find out all PCDs of the 'type' 1512 RecordList = self._RawData[Type, self._Arch] 1513 for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList: 1514 PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting 1515 PcdSet.add((PcdCName, TokenSpaceGuid)) 1516 1517 for PcdCName, TokenSpaceGuid in PcdSet: 1518 # 1519 # limit the ARCH to self._Arch, if no self._Arch found, tdict 1520 # will automatically turn to 'common' ARCH and try again 1521 # 1522 Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid] 1523 if Setting == None: 1524 continue 1525 1526 DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting) 1527 1528 validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName) 1529 Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject( 1530 PcdCName, 1531 TokenSpaceGuid, 1532 self._PCD_TYPE_STRING_[Type], 1533 DatumType, 1534 DefaultValue, 1535 TokenNumber, 1536 '', 1537 {}, 1538 False, 1539 None, 1540 list(validateranges), 1541 list(validlists), 1542 list(expressions) 1543 ) 1544 return Pcds 1545 1546 1547 _Macros = property(_GetMacros) 1548 Arch = property(_GetArch, _SetArch) 1549 PackageName = property(_GetPackageName) 1550 Guid = property(_GetFileGuid) 1551 Version = property(_GetVersion) 1552 1553 Protocols = property(_GetProtocol) 1554 Ppis = property(_GetPpi) 1555 Guids = property(_GetGuid) 1556 Includes = property(_GetInclude) 1557 LibraryClasses = property(_GetLibraryClass) 1558 Pcds = property(_GetPcds) 1559 1560## Module build information from INF file 1561# 1562# This class is used to retrieve information stored in database and convert them 1563# into ModuleBuildClassObject form for easier use for AutoGen. 1564# 1565class InfBuildData(ModuleBuildClassObject): 1566 # dict used to convert PCD type in database to string used by build tool 1567 _PCD_TYPE_STRING_ = { 1568 MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild", 1569 MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule", 1570 MODEL_PCD_FEATURE_FLAG : "FeatureFlag", 1571 MODEL_PCD_DYNAMIC : "Dynamic", 1572 MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic", 1573 MODEL_PCD_DYNAMIC_HII : "DynamicHii", 1574 MODEL_PCD_DYNAMIC_VPD : "DynamicVpd", 1575 MODEL_PCD_DYNAMIC_EX : "DynamicEx", 1576 MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx", 1577 MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii", 1578 MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd", 1579 } 1580 1581 # dict used to convert part of [Defines] to members of InfBuildData directly 1582 _PROPERTY_ = { 1583 # 1584 # Required Fields 1585 # 1586 TAB_INF_DEFINES_BASE_NAME : "_BaseName", 1587 TAB_INF_DEFINES_FILE_GUID : "_Guid", 1588 TAB_INF_DEFINES_MODULE_TYPE : "_ModuleType", 1589 # 1590 # Optional Fields 1591 # 1592 #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion", 1593 TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType", 1594 TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName", 1595 #TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile", 1596 TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile", 1597 TAB_INF_DEFINES_VERSION_NUMBER : "_Version", 1598 TAB_INF_DEFINES_VERSION_STRING : "_Version", 1599 TAB_INF_DEFINES_VERSION : "_Version", 1600 TAB_INF_DEFINES_PCD_IS_DRIVER : "_PcdIsDriver", 1601 TAB_INF_DEFINES_SHADOW : "_Shadow", 1602 1603 TAB_COMPONENTS_SOURCE_OVERRIDE_PATH : "_SourceOverridePath", 1604 } 1605 1606 # dict used to convert Component type to Module type 1607 _MODULE_TYPE_ = { 1608 "LIBRARY" : "BASE", 1609 "SECURITY_CORE" : "SEC", 1610 "PEI_CORE" : "PEI_CORE", 1611 "COMBINED_PEIM_DRIVER" : "PEIM", 1612 "PIC_PEIM" : "PEIM", 1613 "RELOCATABLE_PEIM" : "PEIM", 1614 "PE32_PEIM" : "PEIM", 1615 "BS_DRIVER" : "DXE_DRIVER", 1616 "RT_DRIVER" : "DXE_RUNTIME_DRIVER", 1617 "SAL_RT_DRIVER" : "DXE_SAL_DRIVER", 1618 "DXE_SMM_DRIVER" : "DXE_SMM_DRIVER", 1619 # "SMM_DRIVER" : "DXE_SMM_DRIVER", 1620 # "BS_DRIVER" : "DXE_SMM_DRIVER", 1621 # "BS_DRIVER" : "UEFI_DRIVER", 1622 "APPLICATION" : "UEFI_APPLICATION", 1623 "LOGO" : "BASE", 1624 } 1625 1626 # regular expression for converting XXX_FLAGS in [nmake] section to new type 1627 _NMAKE_FLAG_PATTERN_ = re.compile("(?:EBC_)?([A-Z]+)_(?:STD_|PROJ_|ARCH_)?FLAGS(?:_DLL|_ASL|_EXE)?", re.UNICODE) 1628 # dict used to convert old tool name used in [nmake] section to new ones 1629 _TOOL_CODE_ = { 1630 "C" : "CC", 1631 "LIB" : "SLINK", 1632 "LINK" : "DLINK", 1633 } 1634 1635 1636 ## Constructor of DscBuildData 1637 # 1638 # Initialize object of DscBuildData 1639 # 1640 # @param FilePath The path of platform description file 1641 # @param RawData The raw data of DSC file 1642 # @param BuildDataBase Database used to retrieve module/package information 1643 # @param Arch The target architecture 1644 # @param Platform The name of platform employing this module 1645 # @param Macros Macros used for replacement in DSC file 1646 # 1647 def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None): 1648 self.MetaFile = FilePath 1649 self._ModuleDir = FilePath.Dir 1650 self._RawData = RawData 1651 self._Bdb = BuildDatabase 1652 self._Arch = Arch 1653 self._Target = Target 1654 self._Toolchain = Toolchain 1655 self._Platform = 'COMMON' 1656 self._SourceOverridePath = None 1657 if FilePath.Key in GlobalData.gOverrideDir: 1658 self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key] 1659 self._Clear() 1660 1661 ## XXX[key] = value 1662 def __setitem__(self, key, value): 1663 self.__dict__[self._PROPERTY_[key]] = value 1664 1665 ## value = XXX[key] 1666 def __getitem__(self, key): 1667 return self.__dict__[self._PROPERTY_[key]] 1668 1669 ## "in" test support 1670 def __contains__(self, key): 1671 return key in self._PROPERTY_ 1672 1673 ## Set all internal used members of InfBuildData to None 1674 def _Clear(self): 1675 self._HeaderComments = None 1676 self._TailComments = None 1677 self._Header_ = None 1678 self._AutoGenVersion = None 1679 self._BaseName = None 1680 self._DxsFile = None 1681 self._ModuleType = None 1682 self._ComponentType = None 1683 self._BuildType = None 1684 self._Guid = None 1685 self._Version = None 1686 self._PcdIsDriver = None 1687 self._BinaryModule = None 1688 self._Shadow = None 1689 self._MakefileName = None 1690 self._CustomMakefile = None 1691 self._Specification = None 1692 self._LibraryClass = None 1693 self._ModuleEntryPointList = None 1694 self._ModuleUnloadImageList = None 1695 self._ConstructorList = None 1696 self._DestructorList = None 1697 self._Defs = None 1698 self._Binaries = None 1699 self._Sources = None 1700 self._LibraryClasses = None 1701 self._Libraries = None 1702 self._Protocols = None 1703 self._ProtocolComments = None 1704 self._Ppis = None 1705 self._PpiComments = None 1706 self._Guids = None 1707 self._GuidsUsedByPcd = sdict() 1708 self._GuidComments = None 1709 self._Includes = None 1710 self._Packages = None 1711 self._Pcds = None 1712 self._PcdComments = None 1713 self._BuildOptions = None 1714 self._Depex = None 1715 self._DepexExpression = None 1716 self.__Macros = None 1717 1718 ## Get current effective macros 1719 def _GetMacros(self): 1720 if self.__Macros == None: 1721 self.__Macros = {} 1722 # EDK_GLOBAL defined macros can be applied to EDK module 1723 if self.AutoGenVersion < 0x00010005: 1724 self.__Macros.update(GlobalData.gEdkGlobal) 1725 self.__Macros.update(GlobalData.gGlobalDefines) 1726 return self.__Macros 1727 1728 ## Get architecture 1729 def _GetArch(self): 1730 return self._Arch 1731 1732 ## Set architecture 1733 # 1734 # Changing the default ARCH to another may affect all other information 1735 # because all information in a platform may be ARCH-related. That's 1736 # why we need to clear all internal used members, in order to cause all 1737 # information to be re-retrieved. 1738 # 1739 # @param Value The value of ARCH 1740 # 1741 def _SetArch(self, Value): 1742 if self._Arch == Value: 1743 return 1744 self._Arch = Value 1745 self._Clear() 1746 1747 ## Return the name of platform employing this module 1748 def _GetPlatform(self): 1749 return self._Platform 1750 1751 ## Change the name of platform employing this module 1752 # 1753 # Changing the default name of platform to another may affect some information 1754 # because they may be PLATFORM-related. That's why we need to clear all internal 1755 # used members, in order to cause all information to be re-retrieved. 1756 # 1757 def _SetPlatform(self, Value): 1758 if self._Platform == Value: 1759 return 1760 self._Platform = Value 1761 self._Clear() 1762 def _GetHeaderComments(self): 1763 if not self._HeaderComments: 1764 self._HeaderComments = [] 1765 RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT] 1766 for Record in RecordList: 1767 self._HeaderComments.append(Record[0]) 1768 return self._HeaderComments 1769 def _GetTailComments(self): 1770 if not self._TailComments: 1771 self._TailComments = [] 1772 RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT] 1773 for Record in RecordList: 1774 self._TailComments.append(Record[0]) 1775 return self._TailComments 1776 ## Retrieve all information in [Defines] section 1777 # 1778 # (Retriving all [Defines] information in one-shot is just to save time.) 1779 # 1780 def _GetHeaderInfo(self): 1781 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform] 1782 for Record in RecordList: 1783 Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False) 1784 # items defined _PROPERTY_ don't need additional processing 1785 if Name in self: 1786 self[Name] = Value 1787 if self._Defs == None: 1788 self._Defs = sdict() 1789 self._Defs[Name] = Value 1790 # some special items in [Defines] section need special treatment 1791 elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'): 1792 if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'): 1793 Name = 'UEFI_SPECIFICATION_VERSION' 1794 if self._Specification == None: 1795 self._Specification = sdict() 1796 self._Specification[Name] = GetHexVerValue(Value) 1797 if self._Specification[Name] == None: 1798 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, 1799 "'%s' format is not supported for %s" % (Value, Name), 1800 File=self.MetaFile, Line=Record[-1]) 1801 elif Name == 'LIBRARY_CLASS': 1802 if self._LibraryClass == None: 1803 self._LibraryClass = [] 1804 ValueList = GetSplitValueList(Value) 1805 LibraryClass = ValueList[0] 1806 if len(ValueList) > 1: 1807 SupModuleList = GetSplitValueList(ValueList[1], ' ') 1808 else: 1809 SupModuleList = SUP_MODULE_LIST 1810 self._LibraryClass.append(LibraryClassObject(LibraryClass, SupModuleList)) 1811 elif Name == 'ENTRY_POINT': 1812 if self._ModuleEntryPointList == None: 1813 self._ModuleEntryPointList = [] 1814 self._ModuleEntryPointList.append(Value) 1815 elif Name == 'UNLOAD_IMAGE': 1816 if self._ModuleUnloadImageList == None: 1817 self._ModuleUnloadImageList = [] 1818 if not Value: 1819 continue 1820 self._ModuleUnloadImageList.append(Value) 1821 elif Name == 'CONSTRUCTOR': 1822 if self._ConstructorList == None: 1823 self._ConstructorList = [] 1824 if not Value: 1825 continue 1826 self._ConstructorList.append(Value) 1827 elif Name == 'DESTRUCTOR': 1828 if self._DestructorList == None: 1829 self._DestructorList = [] 1830 if not Value: 1831 continue 1832 self._DestructorList.append(Value) 1833 elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE: 1834 TokenList = GetSplitValueList(Value) 1835 if self._CustomMakefile == None: 1836 self._CustomMakefile = {} 1837 if len(TokenList) < 2: 1838 self._CustomMakefile['MSFT'] = TokenList[0] 1839 self._CustomMakefile['GCC'] = TokenList[0] 1840 else: 1841 if TokenList[0] not in ['MSFT', 'GCC']: 1842 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, 1843 "No supported family [%s]" % TokenList[0], 1844 File=self.MetaFile, Line=Record[-1]) 1845 self._CustomMakefile[TokenList[0]] = TokenList[1] 1846 else: 1847 if self._Defs == None: 1848 self._Defs = sdict() 1849 self._Defs[Name] = Value 1850 1851 # 1852 # Retrieve information in sections specific to Edk.x modules 1853 # 1854 if self.AutoGenVersion >= 0x00010005: 1855 if not self._ModuleType: 1856 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, 1857 "MODULE_TYPE is not given", File=self.MetaFile) 1858 if self._ModuleType not in SUP_MODULE_LIST: 1859 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform] 1860 for Record in RecordList: 1861 Name = Record[1] 1862 if Name == "MODULE_TYPE": 1863 LineNo = Record[6] 1864 break 1865 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, 1866 "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)), 1867 File=self.MetaFile, Line=LineNo) 1868 if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A): 1869 if self._ModuleType == SUP_MODULE_SMM_CORE: 1870 EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile) 1871 if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \ 1872 and 'PCI_CLASS_CODE' in self._Defs: 1873 self._BuildType = 'UEFI_OPTIONROM' 1874 elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \ 1875 and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE': 1876 self._BuildType = 'UEFI_HII' 1877 else: 1878 self._BuildType = self._ModuleType.upper() 1879 1880 if self._DxsFile: 1881 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch) 1882 # check the file validation 1883 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False) 1884 if ErrorCode != 0: 1885 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, 1886 File=self.MetaFile, Line=LineNo) 1887 if self.Sources == None: 1888 self._Sources = [] 1889 self._Sources.append(File) 1890 else: 1891 if not self._ComponentType: 1892 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, 1893 "COMPONENT_TYPE is not given", File=self.MetaFile) 1894 self._BuildType = self._ComponentType.upper() 1895 if self._ComponentType in self._MODULE_TYPE_: 1896 self._ModuleType = self._MODULE_TYPE_[self._ComponentType] 1897 if self._ComponentType == 'LIBRARY': 1898 self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)] 1899 # make use some [nmake] section macros 1900 Macros = self._Macros 1901 Macros["EDK_SOURCE"] = GlobalData.gEcpSource 1902 Macros['PROCESSOR'] = self._Arch 1903 RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform] 1904 for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList: 1905 Value = ReplaceMacro(Value, Macros, True) 1906 if Name == "IMAGE_ENTRY_POINT": 1907 if self._ModuleEntryPointList == None: 1908 self._ModuleEntryPointList = [] 1909 self._ModuleEntryPointList.append(Value) 1910 elif Name == "DPX_SOURCE": 1911 File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch) 1912 # check the file validation 1913 ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False) 1914 if ErrorCode != 0: 1915 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, 1916 File=self.MetaFile, Line=LineNo) 1917 if self.Sources == None: 1918 self._Sources = [] 1919 self._Sources.append(File) 1920 else: 1921 ToolList = self._NMAKE_FLAG_PATTERN_.findall(Name) 1922 if len(ToolList) == 0 or len(ToolList) != 1: 1923 pass 1924# EdkLogger.warn("build", "Don't know how to do with macro [%s]" % Name, 1925# File=self.MetaFile, Line=LineNo) 1926 else: 1927 if self._BuildOptions == None: 1928 self._BuildOptions = sdict() 1929 1930 if ToolList[0] in self._TOOL_CODE_: 1931 Tool = self._TOOL_CODE_[ToolList[0]] 1932 else: 1933 Tool = ToolList[0] 1934 ToolChain = "*_*_*_%s_FLAGS" % Tool 1935 ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain 1936 #ignore not replaced macros in value 1937 ValueList = GetSplitList(' ' + Value, '/D') 1938 Dummy = ValueList[0] 1939 for Index in range(1, len(ValueList)): 1940 if ValueList[Index][-1] == '=' or ValueList[Index] == '': 1941 continue 1942 Dummy = Dummy + ' /D ' + ValueList[Index] 1943 Value = Dummy.strip() 1944 if (ToolChainFamily, ToolChain) not in self._BuildOptions: 1945 self._BuildOptions[ToolChainFamily, ToolChain] = Value 1946 else: 1947 OptionString = self._BuildOptions[ToolChainFamily, ToolChain] 1948 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Value 1949 # set _Header to non-None in order to avoid database re-querying 1950 self._Header_ = 'DUMMY' 1951 1952 ## Retrieve file version 1953 def _GetInfVersion(self): 1954 if self._AutoGenVersion == None: 1955 RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform] 1956 for Record in RecordList: 1957 if Record[1] == TAB_INF_DEFINES_INF_VERSION: 1958 if '.' in Record[2]: 1959 ValueList = Record[2].split('.') 1960 Major = '%04o' % int(ValueList[0], 0) 1961 Minor = '%04o' % int(ValueList[1], 0) 1962 self._AutoGenVersion = int('0x' + Major + Minor, 0) 1963 else: 1964 self._AutoGenVersion = int(Record[2], 0) 1965 break 1966 if self._AutoGenVersion == None: 1967 self._AutoGenVersion = 0x00010000 1968 return self._AutoGenVersion 1969 1970 ## Retrieve BASE_NAME 1971 def _GetBaseName(self): 1972 if self._BaseName == None: 1973 if self._Header_ == None: 1974 self._GetHeaderInfo() 1975 if self._BaseName == None: 1976 EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile) 1977 return self._BaseName 1978 1979 ## Retrieve DxsFile 1980 def _GetDxsFile(self): 1981 if self._DxsFile == None: 1982 if self._Header_ == None: 1983 self._GetHeaderInfo() 1984 if self._DxsFile == None: 1985 self._DxsFile = '' 1986 return self._DxsFile 1987 1988 ## Retrieve MODULE_TYPE 1989 def _GetModuleType(self): 1990 if self._ModuleType == None: 1991 if self._Header_ == None: 1992 self._GetHeaderInfo() 1993 if self._ModuleType == None: 1994 self._ModuleType = 'BASE' 1995 if self._ModuleType not in SUP_MODULE_LIST: 1996 self._ModuleType = "USER_DEFINED" 1997 return self._ModuleType 1998 1999 ## Retrieve COMPONENT_TYPE 2000 def _GetComponentType(self): 2001 if self._ComponentType == None: 2002 if self._Header_ == None: 2003 self._GetHeaderInfo() 2004 if self._ComponentType == None: 2005 self._ComponentType = 'USER_DEFINED' 2006 return self._ComponentType 2007 2008 ## Retrieve "BUILD_TYPE" 2009 def _GetBuildType(self): 2010 if self._BuildType == None: 2011 if self._Header_ == None: 2012 self._GetHeaderInfo() 2013 if not self._BuildType: 2014 self._BuildType = "BASE" 2015 return self._BuildType 2016 2017 ## Retrieve file guid 2018 def _GetFileGuid(self): 2019 if self._Guid == None: 2020 if self._Header_ == None: 2021 self._GetHeaderInfo() 2022 if self._Guid == None: 2023 self._Guid = '00000000-0000-0000-0000-000000000000' 2024 return self._Guid 2025 2026 ## Retrieve module version 2027 def _GetVersion(self): 2028 if self._Version == None: 2029 if self._Header_ == None: 2030 self._GetHeaderInfo() 2031 if self._Version == None: 2032 self._Version = '0.0' 2033 return self._Version 2034 2035 ## Retrieve PCD_IS_DRIVER 2036 def _GetPcdIsDriver(self): 2037 if self._PcdIsDriver == None: 2038 if self._Header_ == None: 2039 self._GetHeaderInfo() 2040 if self._PcdIsDriver == None: 2041 self._PcdIsDriver = '' 2042 return self._PcdIsDriver 2043 2044 ## Retrieve SHADOW 2045 def _GetShadow(self): 2046 if self._Shadow == None: 2047 if self._Header_ == None: 2048 self._GetHeaderInfo() 2049 if self._Shadow != None and self._Shadow.upper() == 'TRUE': 2050 self._Shadow = True 2051 else: 2052 self._Shadow = False 2053 return self._Shadow 2054 2055 ## Retrieve CUSTOM_MAKEFILE 2056 def _GetMakefile(self): 2057 if self._CustomMakefile == None: 2058 if self._Header_ == None: 2059 self._GetHeaderInfo() 2060 if self._CustomMakefile == None: 2061 self._CustomMakefile = {} 2062 return self._CustomMakefile 2063 2064 ## Retrieve EFI_SPECIFICATION_VERSION 2065 def _GetSpec(self): 2066 if self._Specification == None: 2067 if self._Header_ == None: 2068 self._GetHeaderInfo() 2069 if self._Specification == None: 2070 self._Specification = {} 2071 return self._Specification 2072 2073 ## Retrieve LIBRARY_CLASS 2074 def _GetLibraryClass(self): 2075 if self._LibraryClass == None: 2076 if self._Header_ == None: 2077 self._GetHeaderInfo() 2078 if self._LibraryClass == None: 2079 self._LibraryClass = [] 2080 return self._LibraryClass 2081 2082 ## Retrieve ENTRY_POINT 2083 def _GetEntryPoint(self): 2084 if self._ModuleEntryPointList == None: 2085 if self._Header_ == None: 2086 self._GetHeaderInfo() 2087 if self._ModuleEntryPointList == None: 2088 self._ModuleEntryPointList = [] 2089 return self._ModuleEntryPointList 2090 2091 ## Retrieve UNLOAD_IMAGE 2092 def _GetUnloadImage(self): 2093 if self._ModuleUnloadImageList == None: 2094 if self._Header_ == None: 2095 self._GetHeaderInfo() 2096 if self._ModuleUnloadImageList == None: 2097 self._ModuleUnloadImageList = [] 2098 return self._ModuleUnloadImageList 2099 2100 ## Retrieve CONSTRUCTOR 2101 def _GetConstructor(self): 2102 if self._ConstructorList == None: 2103 if self._Header_ == None: 2104 self._GetHeaderInfo() 2105 if self._ConstructorList == None: 2106 self._ConstructorList = [] 2107 return self._ConstructorList 2108 2109 ## Retrieve DESTRUCTOR 2110 def _GetDestructor(self): 2111 if self._DestructorList == None: 2112 if self._Header_ == None: 2113 self._GetHeaderInfo() 2114 if self._DestructorList == None: 2115 self._DestructorList = [] 2116 return self._DestructorList 2117 2118 ## Retrieve definies other than above ones 2119 def _GetDefines(self): 2120 if self._Defs == None: 2121 if self._Header_ == None: 2122 self._GetHeaderInfo() 2123 if self._Defs == None: 2124 self._Defs = sdict() 2125 return self._Defs 2126 2127 ## Retrieve binary files 2128 def _GetBinaries(self): 2129 if self._Binaries == None: 2130 self._Binaries = [] 2131 RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform] 2132 Macros = self._Macros 2133 Macros["EDK_SOURCE"] = GlobalData.gEcpSource 2134 Macros['PROCESSOR'] = self._Arch 2135 for Record in RecordList: 2136 FileType = Record[0] 2137 LineNo = Record[-1] 2138 Target = 'COMMON' 2139 FeatureFlag = [] 2140 if Record[2]: 2141 TokenList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT) 2142 if TokenList: 2143 Target = TokenList[0] 2144 if len(TokenList) > 1: 2145 FeatureFlag = Record[1:] 2146 2147 File = PathClass(NormPath(Record[1], Macros), self._ModuleDir, '', FileType, True, self._Arch, '', Target) 2148 # check the file validation 2149 ErrorCode, ErrorInfo = File.Validate() 2150 if ErrorCode != 0: 2151 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) 2152 self._Binaries.append(File) 2153 return self._Binaries 2154 2155 ## Retrieve binary files with error check. 2156 def _GetBinaryFiles(self): 2157 Binaries = self._GetBinaries() 2158 if GlobalData.gIgnoreSource and Binaries == []: 2159 ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n" 2160 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile) 2161 2162 return Binaries 2163 ## Check whether it exists the binaries with current ARCH in AsBuild INF 2164 def _IsSupportedArch(self): 2165 if self._GetBinaries() and not self._GetSourceFiles(): 2166 return True 2167 else: 2168 return False 2169 ## Retrieve source files 2170 def _GetSourceFiles(self): 2171 #Ignore all source files in a binary build mode 2172 if GlobalData.gIgnoreSource: 2173 self._Sources = [] 2174 return self._Sources 2175 2176 if self._Sources == None: 2177 self._Sources = [] 2178 RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform] 2179 Macros = self._Macros 2180 for Record in RecordList: 2181 LineNo = Record[-1] 2182 ToolChainFamily = Record[1] 2183 TagName = Record[2] 2184 ToolCode = Record[3] 2185 FeatureFlag = Record[4] 2186 if self.AutoGenVersion < 0x00010005: 2187 Macros["EDK_SOURCE"] = GlobalData.gEcpSource 2188 Macros['PROCESSOR'] = self._Arch 2189 SourceFile = NormPath(Record[0], Macros) 2190 if SourceFile[0] == os.path.sep: 2191 SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:]) 2192 # old module source files (Edk) 2193 File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath, 2194 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode) 2195 # check the file validation 2196 ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False) 2197 if ErrorCode != 0: 2198 if File.Ext.lower() == '.h': 2199 EdkLogger.warn('build', 'Include file not found', ExtraData=ErrorInfo, 2200 File=self.MetaFile, Line=LineNo) 2201 continue 2202 else: 2203 EdkLogger.error('build', ErrorCode, ExtraData=File, File=self.MetaFile, Line=LineNo) 2204 else: 2205 File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, '', 2206 '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode) 2207 # check the file validation 2208 ErrorCode, ErrorInfo = File.Validate() 2209 if ErrorCode != 0: 2210 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) 2211 2212 self._Sources.append(File) 2213 return self._Sources 2214 2215 ## Retrieve library classes employed by this module 2216 def _GetLibraryClassUses(self): 2217 if self._LibraryClasses == None: 2218 self._LibraryClasses = sdict() 2219 RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform] 2220 for Record in RecordList: 2221 Lib = Record[0] 2222 Instance = Record[1] 2223 if Instance: 2224 Instance = NormPath(Instance, self._Macros) 2225 self._LibraryClasses[Lib] = Instance 2226 return self._LibraryClasses 2227 2228 ## Retrieve library names (for Edk.x style of modules) 2229 def _GetLibraryNames(self): 2230 if self._Libraries == None: 2231 self._Libraries = [] 2232 RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform] 2233 for Record in RecordList: 2234 LibraryName = ReplaceMacro(Record[0], self._Macros, False) 2235 # in case of name with '.lib' extension, which is unusual in Edk.x inf 2236 LibraryName = os.path.splitext(LibraryName)[0] 2237 if LibraryName not in self._Libraries: 2238 self._Libraries.append(LibraryName) 2239 return self._Libraries 2240 2241 def _GetProtocolComments(self): 2242 self._GetProtocols() 2243 return self._ProtocolComments 2244 ## Retrieve protocols consumed/produced by this module 2245 def _GetProtocols(self): 2246 if self._Protocols == None: 2247 self._Protocols = sdict() 2248 self._ProtocolComments = sdict() 2249 RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform] 2250 for Record in RecordList: 2251 CName = Record[0] 2252 Value = ProtocolValue(CName, self.Packages) 2253 if Value == None: 2254 PackageList = "\n\t".join([str(P) for P in self.Packages]) 2255 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, 2256 "Value of Protocol [%s] is not found under [Protocols] section in" % CName, 2257 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) 2258 self._Protocols[CName] = Value 2259 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]] 2260 Comments = [] 2261 for CmtRec in CommentRecords: 2262 Comments.append(CmtRec[0]) 2263 self._ProtocolComments[CName] = Comments 2264 return self._Protocols 2265 2266 def _GetPpiComments(self): 2267 self._GetPpis() 2268 return self._PpiComments 2269 ## Retrieve PPIs consumed/produced by this module 2270 def _GetPpis(self): 2271 if self._Ppis == None: 2272 self._Ppis = sdict() 2273 self._PpiComments = sdict() 2274 RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform] 2275 for Record in RecordList: 2276 CName = Record[0] 2277 Value = PpiValue(CName, self.Packages) 2278 if Value == None: 2279 PackageList = "\n\t".join([str(P) for P in self.Packages]) 2280 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, 2281 "Value of PPI [%s] is not found under [Ppis] section in " % CName, 2282 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) 2283 self._Ppis[CName] = Value 2284 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]] 2285 Comments = [] 2286 for CmtRec in CommentRecords: 2287 Comments.append(CmtRec[0]) 2288 self._PpiComments[CName] = Comments 2289 return self._Ppis 2290 2291 def _GetGuidComments(self): 2292 self._GetGuids() 2293 return self._GuidComments 2294 ## Retrieve GUIDs consumed/produced by this module 2295 def _GetGuids(self): 2296 if self._Guids == None: 2297 self._Guids = sdict() 2298 self._GuidComments = sdict() 2299 RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform] 2300 for Record in RecordList: 2301 CName = Record[0] 2302 Value = GuidValue(CName, self.Packages) 2303 if Value == None: 2304 PackageList = "\n\t".join([str(P) for P in self.Packages]) 2305 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, 2306 "Value of Guid [%s] is not found under [Guids] section in" % CName, 2307 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) 2308 self._Guids[CName] = Value 2309 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]] 2310 Comments = [] 2311 for CmtRec in CommentRecords: 2312 Comments.append(CmtRec[0]) 2313 self._GuidComments[CName] = Comments 2314 return self._Guids 2315 2316 ## Retrieve include paths necessary for this module (for Edk.x style of modules) 2317 def _GetIncludes(self): 2318 if self._Includes == None: 2319 self._Includes = [] 2320 if self._SourceOverridePath: 2321 self._Includes.append(self._SourceOverridePath) 2322 2323 Macros = self._Macros 2324 if 'PROCESSOR' in GlobalData.gEdkGlobal.keys(): 2325 Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR'] 2326 else: 2327 Macros['PROCESSOR'] = self._Arch 2328 RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform] 2329 for Record in RecordList: 2330 if Record[0].find('EDK_SOURCE') > -1: 2331 Macros['EDK_SOURCE'] = GlobalData.gEcpSource 2332 File = NormPath(Record[0], self._Macros) 2333 if File[0] == '.': 2334 File = os.path.join(self._ModuleDir, File) 2335 else: 2336 File = os.path.join(GlobalData.gWorkspace, File) 2337 File = RealPath(os.path.normpath(File)) 2338 if File: 2339 self._Includes.append(File) 2340 2341 #TRICK: let compiler to choose correct header file 2342 Macros['EDK_SOURCE'] = GlobalData.gEdkSource 2343 File = NormPath(Record[0], self._Macros) 2344 if File[0] == '.': 2345 File = os.path.join(self._ModuleDir, File) 2346 else: 2347 File = os.path.join(GlobalData.gWorkspace, File) 2348 File = RealPath(os.path.normpath(File)) 2349 if File: 2350 self._Includes.append(File) 2351 else: 2352 File = NormPath(Record[0], Macros) 2353 if File[0] == '.': 2354 File = os.path.join(self._ModuleDir, File) 2355 else: 2356 File = mws.join(GlobalData.gWorkspace, File) 2357 File = RealPath(os.path.normpath(File)) 2358 if File: 2359 self._Includes.append(File) 2360 if not File and Record[0].find('EFI_SOURCE') > -1: 2361 # tricky to regard WorkSpace as EFI_SOURCE 2362 Macros['EFI_SOURCE'] = GlobalData.gWorkspace 2363 File = NormPath(Record[0], Macros) 2364 if File[0] == '.': 2365 File = os.path.join(self._ModuleDir, File) 2366 else: 2367 File = os.path.join(GlobalData.gWorkspace, File) 2368 File = RealPath(os.path.normpath(File)) 2369 if File: 2370 self._Includes.append(File) 2371 return self._Includes 2372 2373 ## Retrieve packages this module depends on 2374 def _GetPackages(self): 2375 if self._Packages == None: 2376 self._Packages = [] 2377 RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform] 2378 Macros = self._Macros 2379 Macros['EDK_SOURCE'] = GlobalData.gEcpSource 2380 for Record in RecordList: 2381 File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch) 2382 LineNo = Record[-1] 2383 # check the file validation 2384 ErrorCode, ErrorInfo = File.Validate('.dec') 2385 if ErrorCode != 0: 2386 EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo) 2387 # parse this package now. we need it to get protocol/ppi/guid value 2388 Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain] 2389 self._Packages.append(Package) 2390 return self._Packages 2391 2392 ## Retrieve PCD comments 2393 def _GetPcdComments(self): 2394 self._GetPcds() 2395 return self._PcdComments 2396 ## Retrieve PCDs used in this module 2397 def _GetPcds(self): 2398 if self._Pcds == None: 2399 self._Pcds = sdict() 2400 self._PcdComments = sdict() 2401 self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD)) 2402 self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE)) 2403 self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG)) 2404 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC)) 2405 self._Pcds.update(self._GetPcd(MODEL_PCD_DYNAMIC_EX)) 2406 return self._Pcds 2407 2408 ## Retrieve build options specific to this module 2409 def _GetBuildOptions(self): 2410 if self._BuildOptions == None: 2411 self._BuildOptions = sdict() 2412 RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, self._Platform] 2413 for Record in RecordList: 2414 ToolChainFamily = Record[0] 2415 ToolChain = Record[1] 2416 Option = Record[2] 2417 if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='): 2418 self._BuildOptions[ToolChainFamily, ToolChain] = Option 2419 else: 2420 # concatenate the option string if they're for the same tool 2421 OptionString = self._BuildOptions[ToolChainFamily, ToolChain] 2422 self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option 2423 return self._BuildOptions 2424 2425 ## Retrieve dependency expression 2426 def _GetDepex(self): 2427 if self._Depex == None: 2428 self._Depex = tdict(False, 2) 2429 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch] 2430 2431 # If the module has only Binaries and no Sources, then ignore [Depex] 2432 if self.Sources == None or self.Sources == []: 2433 if self.Binaries != None and self.Binaries != []: 2434 return self._Depex 2435 2436 # PEIM and DXE drivers must have a valid [Depex] section 2437 if len(self.LibraryClass) == 0 and len(RecordList) == 0: 2438 if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \ 2439 self.ModuleType == 'DXE_SAL_DRIVER' or self.ModuleType == 'DXE_RUNTIME_DRIVER': 2440 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \ 2441 % self.ModuleType, File=self.MetaFile) 2442 2443 if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED': 2444 for Record in RecordList: 2445 if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']: 2446 EdkLogger.error('build', FORMAT_INVALID, 2447 "'%s' module must specify the type of [Depex] section" % self.ModuleType, 2448 File=self.MetaFile) 2449 2450 Depex = sdict() 2451 for Record in RecordList: 2452 DepexStr = ReplaceMacro(Record[0], self._Macros, False) 2453 Arch = Record[3] 2454 ModuleType = Record[4] 2455 TokenList = DepexStr.split() 2456 if (Arch, ModuleType) not in Depex: 2457 Depex[Arch, ModuleType] = [] 2458 DepexList = Depex[Arch, ModuleType] 2459 for Token in TokenList: 2460 if Token in DEPEX_SUPPORTED_OPCODE: 2461 DepexList.append(Token) 2462 elif Token.endswith(".inf"): # module file name 2463 ModuleFile = os.path.normpath(Token) 2464 Module = self.BuildDatabase[ModuleFile] 2465 if Module == None: 2466 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "Module is not found in active platform", 2467 ExtraData=Token, File=self.MetaFile, Line=Record[-1]) 2468 DepexList.append(Module.Guid) 2469 else: 2470 # get the GUID value now 2471 Value = ProtocolValue(Token, self.Packages) 2472 if Value == None: 2473 Value = PpiValue(Token, self.Packages) 2474 if Value == None: 2475 Value = GuidValue(Token, self.Packages) 2476 if Value == None: 2477 PackageList = "\n\t".join([str(P) for P in self.Packages]) 2478 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, 2479 "Value of [%s] is not found in" % Token, 2480 ExtraData=PackageList, File=self.MetaFile, Line=Record[-1]) 2481 DepexList.append(Value) 2482 for Arch, ModuleType in Depex: 2483 self._Depex[Arch, ModuleType] = Depex[Arch, ModuleType] 2484 return self._Depex 2485 2486 ## Retrieve depedency expression 2487 def _GetDepexExpression(self): 2488 if self._DepexExpression == None: 2489 self._DepexExpression = tdict(False, 2) 2490 RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch] 2491 DepexExpression = sdict() 2492 for Record in RecordList: 2493 DepexStr = ReplaceMacro(Record[0], self._Macros, False) 2494 Arch = Record[3] 2495 ModuleType = Record[4] 2496 TokenList = DepexStr.split() 2497 if (Arch, ModuleType) not in DepexExpression: 2498 DepexExpression[Arch, ModuleType] = '' 2499 for Token in TokenList: 2500 DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] + Token.strip() + ' ' 2501 for Arch, ModuleType in DepexExpression: 2502 self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType] 2503 return self._DepexExpression 2504 2505 def GetGuidsUsedByPcd(self): 2506 return self._GuidsUsedByPcd 2507 ## Retrieve PCD for given type 2508 def _GetPcd(self, Type): 2509 Pcds = sdict() 2510 PcdDict = tdict(True, 4) 2511 PcdList = [] 2512 RecordList = self._RawData[Type, self._Arch, self._Platform] 2513 for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList: 2514 PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo) 2515 PcdList.append((PcdCName, TokenSpaceGuid)) 2516 # get the guid value 2517 if TokenSpaceGuid not in self.Guids: 2518 Value = GuidValue(TokenSpaceGuid, self.Packages) 2519 if Value == None: 2520 PackageList = "\n\t".join([str(P) for P in self.Packages]) 2521 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, 2522 "Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid, 2523 ExtraData=PackageList, File=self.MetaFile, Line=LineNo) 2524 self.Guids[TokenSpaceGuid] = Value 2525 self._GuidsUsedByPcd[TokenSpaceGuid] = Value 2526 CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id] 2527 Comments = [] 2528 for CmtRec in CommentRecords: 2529 Comments.append(CmtRec[0]) 2530 self._PcdComments[TokenSpaceGuid, PcdCName] = Comments 2531 2532 # resolve PCD type, value, datum info, etc. by getting its definition from package 2533 for PcdCName, TokenSpaceGuid in PcdList: 2534 Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid] 2535 if Setting == None: 2536 continue 2537 ValueList = AnalyzePcdData(Setting) 2538 DefaultValue = ValueList[0] 2539 Pcd = PcdClassObject( 2540 PcdCName, 2541 TokenSpaceGuid, 2542 '', 2543 '', 2544 DefaultValue, 2545 '', 2546 '', 2547 {}, 2548 False, 2549 self.Guids[TokenSpaceGuid] 2550 ) 2551 if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]: 2552 # Patch PCD: TokenSpace.PcdCName|Value|Offset 2553 Pcd.Offset = ValueList[1] 2554 2555 # get necessary info from package declaring this PCD 2556 for Package in self.Packages: 2557 # 2558 # 'dynamic' in INF means its type is determined by platform; 2559 # if platform doesn't give its type, use 'lowest' one in the 2560 # following order, if any 2561 # 2562 # "FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx" 2563 # 2564 PcdType = self._PCD_TYPE_STRING_[Type] 2565 if Type == MODEL_PCD_DYNAMIC: 2566 Pcd.Pending = True 2567 for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]: 2568 if (PcdCName, TokenSpaceGuid, T) in Package.Pcds: 2569 PcdType = T 2570 break 2571 else: 2572 Pcd.Pending = False 2573 2574 if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds: 2575 PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType] 2576 Pcd.Type = PcdType 2577 Pcd.TokenValue = PcdInPackage.TokenValue 2578 2579 # 2580 # Check whether the token value exist or not. 2581 # 2582 if Pcd.TokenValue == None or Pcd.TokenValue == "": 2583 EdkLogger.error( 2584 'build', 2585 FORMAT_INVALID, 2586 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdCName, str(Package)), 2587 File=self.MetaFile, Line=LineNo, 2588 ExtraData=None 2589 ) 2590 # 2591 # Check hexadecimal token value length and format. 2592 # 2593 ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL) 2594 if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"): 2595 if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None: 2596 EdkLogger.error( 2597 'build', 2598 FORMAT_INVALID, 2599 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)), 2600 File=self.MetaFile, Line=LineNo, 2601 ExtraData=None 2602 ) 2603 2604 # 2605 # Check decimal token value length and format. 2606 # 2607 else: 2608 try: 2609 TokenValueInt = int (Pcd.TokenValue, 10) 2610 if (TokenValueInt < 0 or TokenValueInt > 4294967295): 2611 EdkLogger.error( 2612 'build', 2613 FORMAT_INVALID, 2614 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)), 2615 File=self.MetaFile, Line=LineNo, 2616 ExtraData=None 2617 ) 2618 except: 2619 EdkLogger.error( 2620 'build', 2621 FORMAT_INVALID, 2622 "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)), 2623 File=self.MetaFile, Line=LineNo, 2624 ExtraData=None 2625 ) 2626 2627 Pcd.DatumType = PcdInPackage.DatumType 2628 Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize 2629 Pcd.InfDefaultValue = Pcd.DefaultValue 2630 if Pcd.DefaultValue in [None, '']: 2631 Pcd.DefaultValue = PcdInPackage.DefaultValue 2632 break 2633 else: 2634 EdkLogger.error( 2635 'build', 2636 FORMAT_INVALID, 2637 "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile), 2638 File=self.MetaFile, Line=LineNo, 2639 ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages]) 2640 ) 2641 Pcds[PcdCName, TokenSpaceGuid] = Pcd 2642 2643 return Pcds 2644 2645 ## check whether current module is binary module 2646 def _IsBinaryModule(self): 2647 if self.Binaries and not self.Sources: 2648 return True 2649 elif GlobalData.gIgnoreSource: 2650 return True 2651 else: 2652 return False 2653 2654 _Macros = property(_GetMacros) 2655 Arch = property(_GetArch, _SetArch) 2656 Platform = property(_GetPlatform, _SetPlatform) 2657 2658 HeaderComments = property(_GetHeaderComments) 2659 TailComments = property(_GetTailComments) 2660 AutoGenVersion = property(_GetInfVersion) 2661 BaseName = property(_GetBaseName) 2662 ModuleType = property(_GetModuleType) 2663 ComponentType = property(_GetComponentType) 2664 BuildType = property(_GetBuildType) 2665 Guid = property(_GetFileGuid) 2666 Version = property(_GetVersion) 2667 PcdIsDriver = property(_GetPcdIsDriver) 2668 Shadow = property(_GetShadow) 2669 CustomMakefile = property(_GetMakefile) 2670 Specification = property(_GetSpec) 2671 LibraryClass = property(_GetLibraryClass) 2672 ModuleEntryPointList = property(_GetEntryPoint) 2673 ModuleUnloadImageList = property(_GetUnloadImage) 2674 ConstructorList = property(_GetConstructor) 2675 DestructorList = property(_GetDestructor) 2676 Defines = property(_GetDefines) 2677 DxsFile = property(_GetDxsFile) 2678 2679 Binaries = property(_GetBinaryFiles) 2680 Sources = property(_GetSourceFiles) 2681 LibraryClasses = property(_GetLibraryClassUses) 2682 Libraries = property(_GetLibraryNames) 2683 Protocols = property(_GetProtocols) 2684 ProtocolComments = property(_GetProtocolComments) 2685 Ppis = property(_GetPpis) 2686 PpiComments = property(_GetPpiComments) 2687 Guids = property(_GetGuids) 2688 GuidComments = property(_GetGuidComments) 2689 Includes = property(_GetIncludes) 2690 Packages = property(_GetPackages) 2691 Pcds = property(_GetPcds) 2692 PcdComments = property(_GetPcdComments) 2693 BuildOptions = property(_GetBuildOptions) 2694 Depex = property(_GetDepex) 2695 DepexExpression = property(_GetDepexExpression) 2696 IsBinaryModule = property(_IsBinaryModule) 2697 IsSupportedArch = property(_IsSupportedArch) 2698 2699## Database 2700# 2701# This class defined the build database for all modules, packages and platform. 2702# It will call corresponding parser for the given file if it cannot find it in 2703# the database. 2704# 2705# @param DbPath Path of database file 2706# @param GlobalMacros Global macros used for replacement during file parsing 2707# @prarm RenewDb=False Create new database file if it's already there 2708# 2709class WorkspaceDatabase(object): 2710 2711 2712 # 2713 # internal class used for call corresponding file parser and caching the result 2714 # to avoid unnecessary re-parsing 2715 # 2716 class BuildObjectFactory(object): 2717 2718 _FILE_TYPE_ = { 2719 ".inf" : MODEL_FILE_INF, 2720 ".dec" : MODEL_FILE_DEC, 2721 ".dsc" : MODEL_FILE_DSC, 2722 } 2723 2724 # file parser 2725 _FILE_PARSER_ = { 2726 MODEL_FILE_INF : InfParser, 2727 MODEL_FILE_DEC : DecParser, 2728 MODEL_FILE_DSC : DscParser, 2729 } 2730 2731 # convert to xxxBuildData object 2732 _GENERATOR_ = { 2733 MODEL_FILE_INF : InfBuildData, 2734 MODEL_FILE_DEC : DecBuildData, 2735 MODEL_FILE_DSC : DscBuildData, 2736 } 2737 2738 _CACHE_ = {} # (FilePath, Arch) : <object> 2739 2740 # constructor 2741 def __init__(self, WorkspaceDb): 2742 self.WorkspaceDb = WorkspaceDb 2743 2744 # key = (FilePath, Arch=None) 2745 def __contains__(self, Key): 2746 FilePath = Key[0] 2747 if len(Key) > 1: 2748 Arch = Key[1] 2749 else: 2750 Arch = None 2751 return (FilePath, Arch) in self._CACHE_ 2752 2753 # key = (FilePath, Arch=None, Target=None, Toochain=None) 2754 def __getitem__(self, Key): 2755 FilePath = Key[0] 2756 KeyLength = len(Key) 2757 if KeyLength > 1: 2758 Arch = Key[1] 2759 else: 2760 Arch = None 2761 if KeyLength > 2: 2762 Target = Key[2] 2763 else: 2764 Target = None 2765 if KeyLength > 3: 2766 Toolchain = Key[3] 2767 else: 2768 Toolchain = None 2769 2770 # if it's generated before, just return the cached one 2771 Key = (FilePath, Arch, Target, Toolchain) 2772 if Key in self._CACHE_: 2773 return self._CACHE_[Key] 2774 2775 # check file type 2776 Ext = FilePath.Type 2777 if Ext not in self._FILE_TYPE_: 2778 return None 2779 FileType = self._FILE_TYPE_[Ext] 2780 if FileType not in self._GENERATOR_: 2781 return None 2782 2783 # get the parser ready for this file 2784 MetaFile = self._FILE_PARSER_[FileType]( 2785 FilePath, 2786 FileType, 2787 MetaFileStorage(self.WorkspaceDb.Cur, FilePath, FileType) 2788 ) 2789 # alwasy do post-process, in case of macros change 2790 MetaFile.DoPostProcess() 2791 # object the build is based on 2792 BuildObject = self._GENERATOR_[FileType]( 2793 FilePath, 2794 MetaFile, 2795 self, 2796 Arch, 2797 Target, 2798 Toolchain 2799 ) 2800 self._CACHE_[Key] = BuildObject 2801 return BuildObject 2802 2803 # placeholder for file format conversion 2804 class TransformObjectFactory: 2805 def __init__(self, WorkspaceDb): 2806 self.WorkspaceDb = WorkspaceDb 2807 2808 # key = FilePath, Arch 2809 def __getitem__(self, Key): 2810 pass 2811 2812 ## Constructor of WorkspaceDatabase 2813 # 2814 # @param DbPath Path of database file 2815 # @param GlobalMacros Global macros used for replacement during file parsing 2816 # @prarm RenewDb=False Create new database file if it's already there 2817 # 2818 def __init__(self, DbPath, RenewDb=False): 2819 self._DbClosedFlag = False 2820 if not DbPath: 2821 DbPath = os.path.normpath(mws.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath)) 2822 2823 # don't create necessary path for db in memory 2824 if DbPath != ':memory:': 2825 DbDir = os.path.split(DbPath)[0] 2826 if not os.path.exists(DbDir): 2827 os.makedirs(DbDir) 2828 2829 # remove db file in case inconsistency between db and file in file system 2830 if self._CheckWhetherDbNeedRenew(RenewDb, DbPath): 2831 os.remove(DbPath) 2832 2833 # create db with optimized parameters 2834 self.Conn = sqlite3.connect(DbPath, isolation_level='DEFERRED') 2835 self.Conn.execute("PRAGMA synchronous=OFF") 2836 self.Conn.execute("PRAGMA temp_store=MEMORY") 2837 self.Conn.execute("PRAGMA count_changes=OFF") 2838 self.Conn.execute("PRAGMA cache_size=8192") 2839 #self.Conn.execute("PRAGMA page_size=8192") 2840 2841 # to avoid non-ascii character conversion issue 2842 self.Conn.text_factory = str 2843 self.Cur = self.Conn.cursor() 2844 2845 # create table for internal uses 2846 self.TblDataModel = TableDataModel(self.Cur) 2847 self.TblFile = TableFile(self.Cur) 2848 self.Platform = None 2849 2850 # conversion object for build or file format conversion purpose 2851 self.BuildObject = WorkspaceDatabase.BuildObjectFactory(self) 2852 self.TransformObject = WorkspaceDatabase.TransformObjectFactory(self) 2853 2854 ## Check whether workspace database need to be renew. 2855 # The renew reason maybe: 2856 # 1) If user force to renew; 2857 # 2) If user do not force renew, and 2858 # a) If the time of last modified python source is newer than database file; 2859 # b) If the time of last modified frozen executable file is newer than database file; 2860 # 2861 # @param force User force renew database 2862 # @param DbPath The absolute path of workspace database file 2863 # 2864 # @return Bool value for whether need renew workspace databse 2865 # 2866 def _CheckWhetherDbNeedRenew (self, force, DbPath): 2867 # if database does not exist, we need do nothing 2868 if not os.path.exists(DbPath): return False 2869 2870 # if user force to renew database, then not check whether database is out of date 2871 if force: return True 2872 2873 # 2874 # Check the time of last modified source file or build.exe 2875 # if is newer than time of database, then database need to be re-created. 2876 # 2877 timeOfToolModified = 0 2878 if hasattr(sys, "frozen"): 2879 exePath = os.path.abspath(sys.executable) 2880 timeOfToolModified = os.stat(exePath).st_mtime 2881 else: 2882 curPath = os.path.dirname(__file__) # curPath is the path of WorkspaceDatabase.py 2883 rootPath = os.path.split(curPath)[0] # rootPath is root path of python source, such as /BaseTools/Source/Python 2884 if rootPath == "" or rootPath == None: 2885 EdkLogger.verbose("\nFail to find the root path of build.exe or python sources, so can not \ 2886determine whether database file is out of date!\n") 2887 2888 # walk the root path of source or build's binary to get the time last modified. 2889 2890 for root, dirs, files in os.walk (rootPath): 2891 for dir in dirs: 2892 # bypass source control folder 2893 if dir.lower() in [".svn", "_svn", "cvs"]: 2894 dirs.remove(dir) 2895 2896 for file in files: 2897 ext = os.path.splitext(file)[1] 2898 if ext.lower() == ".py": # only check .py files 2899 fd = os.stat(os.path.join(root, file)) 2900 if timeOfToolModified < fd.st_mtime: 2901 timeOfToolModified = fd.st_mtime 2902 if timeOfToolModified > os.stat(DbPath).st_mtime: 2903 EdkLogger.verbose("\nWorkspace database is out of data!") 2904 return True 2905 2906 return False 2907 2908 ## Initialize build database 2909 def InitDatabase(self): 2910 EdkLogger.verbose("\nInitialize build database started ...") 2911 2912 # 2913 # Create new tables 2914 # 2915 self.TblDataModel.Create(False) 2916 self.TblFile.Create(False) 2917 2918 # 2919 # Initialize table DataModel 2920 # 2921 self.TblDataModel.InitTable() 2922 EdkLogger.verbose("Initialize build database ... DONE!") 2923 2924 ## Query a table 2925 # 2926 # @param Table: The instance of the table to be queried 2927 # 2928 def QueryTable(self, Table): 2929 Table.Query() 2930 2931 def __del__(self): 2932 self.Close() 2933 2934 ## Close entire database 2935 # 2936 # Commit all first 2937 # Close the connection and cursor 2938 # 2939 def Close(self): 2940 if not self._DbClosedFlag: 2941 self.Conn.commit() 2942 self.Cur.close() 2943 self.Conn.close() 2944 self._DbClosedFlag = True 2945 2946 ## Summarize all packages in the database 2947 def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag): 2948 self.Platform = Platform 2949 PackageList = [] 2950 Pa = self.BuildObject[self.Platform, 'COMMON'] 2951 # 2952 # Get Package related to Modules 2953 # 2954 for Module in Pa.Modules: 2955 ModuleObj = self.BuildObject[Module, Arch, TargetName, ToolChainTag] 2956 for Package in ModuleObj.Packages: 2957 if Package not in PackageList: 2958 PackageList.append(Package) 2959 # 2960 # Get Packages related to Libraries 2961 # 2962 for Lib in Pa.LibraryInstances: 2963 LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag] 2964 for Package in LibObj.Packages: 2965 if Package not in PackageList: 2966 PackageList.append(Package) 2967 2968 return PackageList 2969 2970 ## Summarize all platforms in the database 2971 def _GetPlatformList(self): 2972 PlatformList = [] 2973 for PlatformFile in self.TblFile.GetFileList(MODEL_FILE_DSC): 2974 try: 2975 Platform = self.BuildObject[PathClass(PlatformFile), 'COMMON'] 2976 except: 2977 Platform = None 2978 if Platform != None: 2979 PlatformList.append(Platform) 2980 return PlatformList 2981 2982 PlatformList = property(_GetPlatformList) 2983 2984## 2985# 2986# This acts like the main() function for the script, unless it is 'import'ed into another 2987# script. 2988# 2989if __name__ == '__main__': 2990 pass 2991 2992