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