Home | History | Annotate | Download | only in Workspace
      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 #

     18 import sqlite3
     19 import Common.LongFilePathOs as os
     20 import pickle
     21 import uuid
     22 
     23 import Common.EdkLogger as EdkLogger
     24 import Common.GlobalData as GlobalData
     25 from Common.MultipleWorkspace import MultipleWorkspace as mws
     26 
     27 from Common.String import *
     28 from Common.DataType import *
     29 from Common.Misc import *
     30 from types import *
     31 
     32 from CommonDataClass.CommonClass import SkuInfoClass
     33 
     34 from MetaDataTable import *
     35 from MetaFileTable import *
     36 from MetaFileParser import *
     37 from BuildClassObject import *
     38 from WorkspaceCommon import GetDeclaredPcd
     39 from Common.Misc import AnalyzeDscPcd
     40 from Common.Misc import ProcessDuplicatedInf
     41 import re
     42 from Common.Parsing import IsValidWord
     43 from Common.VariableAttributes import VariableAttributes
     44 import 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 #

     51 class 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 #

   1269 class 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 #

   1672 class 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 #

   2863 class 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 \
   3041 determine 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 #

   3150 if __name__ == '__main__':
   3151     pass
   3152 
   3153