Home | History | Annotate | Download | only in AutoGen
      1 ## @file

      2 # Generate AutoGen.h, AutoGen.c and *.depex files

      3 #

      4 # Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>

      5 # This program and the accompanying materials

      6 # are licensed and made available under the terms and conditions of the BSD License

      7 # which accompanies this distribution.  The full text of the license may be found at

      8 # http://opensource.org/licenses/bsd-license.php

      9 #

     10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,

     11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

     12 #

     13 
     14 ## Import Modules

     15 #

     16 import Common.LongFilePathOs as os
     17 import re
     18 import os.path as path
     19 import copy
     20 import uuid
     21 
     22 import GenC
     23 import GenMake
     24 import GenDepex
     25 from StringIO import StringIO
     26 
     27 from StrGather import *
     28 from BuildEngine import BuildRule
     29 
     30 from Common.LongFilePathSupport import CopyLongFilePath
     31 from Common.BuildToolError import *
     32 from Common.DataType import *
     33 from Common.Misc import *
     34 from Common.String import *
     35 import Common.GlobalData as GlobalData
     36 from GenFds.FdfParser import *
     37 from CommonDataClass.CommonClass import SkuInfoClass
     38 from Workspace.BuildClassObject import *
     39 from GenPatchPcdTable.GenPatchPcdTable import parsePcdInfoFromMapFile
     40 import Common.VpdInfoFile as VpdInfoFile
     41 from GenPcdDb import CreatePcdDatabaseCode
     42 from Workspace.MetaFileCommentParser import UsageList
     43 from Common.MultipleWorkspace import MultipleWorkspace as mws
     44 import InfSectionParser
     45 
     46 ## Regular expression for splitting Dependency Expression string into tokens

     47 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
     48 
     49 #

     50 # Match name = variable

     51 #

     52 gEfiVarStoreNamePattern = re.compile("\s*name\s*=\s*(\w+)")
     53 #

     54 # The format of guid in efivarstore statement likes following and must be correct:

     55 # guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}}

     56 #

     57 gEfiVarStoreGuidPattern = re.compile("\s*guid\s*=\s*({.*?{.*?}\s*})")
     58 
     59 ## Mapping Makefile type

     60 gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}
     61 
     62 
     63 ## Build rule configuration file

     64 gDefaultBuildRuleFile = 'Conf/build_rule.txt'
     65 
     66 ## Build rule default version

     67 AutoGenReqBuildRuleVerNum = "0.1"
     68 
     69 ## default file name for AutoGen

     70 gAutoGenCodeFileName = "AutoGen.c"
     71 gAutoGenHeaderFileName = "AutoGen.h"
     72 gAutoGenStringFileName = "%(module_name)sStrDefs.h"
     73 gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"
     74 gAutoGenDepexFileName = "%(module_name)s.depex"
     75 gAutoGenImageDefFileName = "%(module_name)sImgDefs.h"
     76 gAutoGenIdfFileName = "%(module_name)sIdf.hpk"
     77 gInfSpecVersion = "0x00010017"
     78 
     79 #

     80 # Template string to generic AsBuilt INF

     81 #

     82 gAsBuiltInfHeaderString = TemplateString("""${header_comments}
     83 
     84 # DO NOT EDIT
     85 # FILE auto-generated
     86 
     87 [Defines]
     88   INF_VERSION                = ${module_inf_version}
     89   BASE_NAME                  = ${module_name}
     90   FILE_GUID                  = ${module_guid}
     91   MODULE_TYPE                = ${module_module_type}${BEGIN}
     92   VERSION_STRING             = ${module_version_string}${END}${BEGIN}
     93   PCD_IS_DRIVER              = ${pcd_is_driver_string}${END}${BEGIN}
     94   UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}
     95   PI_SPECIFICATION_VERSION   = ${module_pi_specification_version}${END}${BEGIN}
     96   ENTRY_POINT                = ${module_entry_point}${END}${BEGIN}
     97   UNLOAD_IMAGE               = ${module_unload_image}${END}${BEGIN}
     98   CONSTRUCTOR                = ${module_constructor}${END}${BEGIN}
     99   DESTRUCTOR                 = ${module_destructor}${END}${BEGIN}
    100   SHADOW                     = ${module_shadow}${END}${BEGIN}
    101   PCI_VENDOR_ID              = ${module_pci_vendor_id}${END}${BEGIN}
    102   PCI_DEVICE_ID              = ${module_pci_device_id}${END}${BEGIN}
    103   PCI_CLASS_CODE             = ${module_pci_class_code}${END}${BEGIN}
    104   PCI_REVISION               = ${module_pci_revision}${END}${BEGIN}
    105   BUILD_NUMBER               = ${module_build_number}${END}${BEGIN}
    106   SPEC                       = ${module_spec}${END}${BEGIN}
    107   UEFI_HII_RESOURCE_SECTION  = ${module_uefi_hii_resource_section}${END}${BEGIN}
    108   MODULE_UNI_FILE            = ${module_uni_file}${END}
    109 
    110 [Packages.${module_arch}]${BEGIN}
    111   ${package_item}${END}
    112 
    113 [Binaries.${module_arch}]${BEGIN}
    114   ${binary_item}${END}
    115 
    116 [PatchPcd.${module_arch}]${BEGIN}
    117   ${patchablepcd_item}
    118 ${END}
    119 
    120 [Protocols.${module_arch}]${BEGIN}
    121   ${protocol_item}
    122 ${END}
    123 
    124 [Ppis.${module_arch}]${BEGIN}
    125   ${ppi_item}
    126 ${END}
    127 
    128 [Guids.${module_arch}]${BEGIN}
    129   ${guid_item}
    130 ${END}
    131 
    132 [PcdEx.${module_arch}]${BEGIN}
    133   ${pcd_item}
    134 ${END}
    135 
    136 [LibraryClasses.${module_arch}]
    137 ## @LIB_INSTANCES${BEGIN}
    138 #  ${libraryclasses_item}${END}
    139 
    140 ${depexsection_item}
    141 
    142 ${tail_comments}
    143 
    144 [BuildOptions.${module_arch}]
    145 ## @AsBuilt${BEGIN}
    146 ##   ${flags_item}${END}
    147 """)
    148 
    149 ## Base class for AutoGen

    150 #

    151 #   This class just implements the cache mechanism of AutoGen objects.

    152 #

    153 class AutoGen(object):
    154     # database to maintain the objects of xxxAutoGen

    155     _CACHE_ = {}    # (BuildTarget, ToolChain) : {ARCH : {platform file: AutoGen object}}}

    156 
    157     ## Factory method

    158     #

    159     #   @param  Class           class object of real AutoGen class

    160     #                           (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)

    161     #   @param  Workspace       Workspace directory or WorkspaceAutoGen object

    162     #   @param  MetaFile        The path of meta file

    163     #   @param  Target          Build target

    164     #   @param  Toolchain       Tool chain name

    165     #   @param  Arch            Target arch

    166     #   @param  *args           The specific class related parameters

    167     #   @param  **kwargs        The specific class related dict parameters

    168     #

    169     def __new__(Class, Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
    170         # check if the object has been created

    171         Key = (Target, Toolchain)
    172         if Key not in Class._CACHE_ or Arch not in Class._CACHE_[Key] \
    173            or MetaFile not in Class._CACHE_[Key][Arch]:
    174             AutoGenObject = super(AutoGen, Class).__new__(Class)
    175             # call real constructor

    176             if not AutoGenObject._Init(Workspace, MetaFile, Target, Toolchain, Arch, *args, **kwargs):
    177                 return None
    178             if Key not in Class._CACHE_:
    179                 Class._CACHE_[Key] = {}
    180             if Arch not in Class._CACHE_[Key]:
    181                 Class._CACHE_[Key][Arch] = {}
    182             Class._CACHE_[Key][Arch][MetaFile] = AutoGenObject
    183         else:
    184             AutoGenObject = Class._CACHE_[Key][Arch][MetaFile]
    185 
    186         return AutoGenObject
    187 
    188     ## hash() operator

    189     #

    190     #  The file path of platform file will be used to represent hash value of this object

    191     #

    192     #   @retval int     Hash value of the file path of platform file

    193     #

    194     def __hash__(self):
    195         return hash(self.MetaFile)
    196 
    197     ## str() operator

    198     #

    199     #  The file path of platform file will be used to represent this object

    200     #

    201     #   @retval string  String of platform file path

    202     #

    203     def __str__(self):
    204         return str(self.MetaFile)
    205 
    206     ## "==" operator

    207     def __eq__(self, Other):
    208         return Other and self.MetaFile == Other
    209 
    210 ## Workspace AutoGen class

    211 #

    212 #   This class is used mainly to control the whole platform build for different

    213 # architecture. This class will generate top level makefile.

    214 #

    215 class WorkspaceAutoGen(AutoGen):
    216     ## Real constructor of WorkspaceAutoGen

    217     #

    218     # This method behaves the same as __init__ except that it needs explicit invoke

    219     # (in super class's __new__ method)

    220     #

    221     #   @param  WorkspaceDir            Root directory of workspace

    222     #   @param  ActivePlatform          Meta-file of active platform

    223     #   @param  Target                  Build target

    224     #   @param  Toolchain               Tool chain name

    225     #   @param  ArchList                List of architecture of current build

    226     #   @param  MetaFileDb              Database containing meta-files

    227     #   @param  BuildConfig             Configuration of build

    228     #   @param  ToolDefinition          Tool chain definitions

    229     #   @param  FlashDefinitionFile     File of flash definition

    230     #   @param  Fds                     FD list to be generated

    231     #   @param  Fvs                     FV list to be generated

    232     #   @param  Caps                    Capsule list to be generated

    233     #   @param  SkuId                   SKU id from command line

    234     #

    235     def _Init(self, WorkspaceDir, ActivePlatform, Target, Toolchain, ArchList, MetaFileDb,
    236               BuildConfig, ToolDefinition, FlashDefinitionFile='', Fds=None, Fvs=None, Caps=None, SkuId='', UniFlag=None,
    237               Progress=None, BuildModule=None):
    238         if Fds is None:
    239             Fds = []
    240         if Fvs is None:
    241             Fvs = []
    242         if Caps is None:
    243             Caps = []
    244         self.BuildDatabase  = MetaFileDb
    245         self.MetaFile       = ActivePlatform
    246         self.WorkspaceDir   = WorkspaceDir
    247         self.Platform       = self.BuildDatabase[self.MetaFile, 'COMMON', Target, Toolchain]
    248         GlobalData.gActivePlatform = self.Platform
    249         self.BuildTarget    = Target
    250         self.ToolChain      = Toolchain
    251         self.ArchList       = ArchList
    252         self.SkuId          = SkuId
    253         self.UniFlag        = UniFlag
    254 
    255         self.TargetTxt      = BuildConfig
    256         self.ToolDef        = ToolDefinition
    257         self.FdfFile        = FlashDefinitionFile
    258         self.FdTargetList   = Fds
    259         self.FvTargetList   = Fvs
    260         self.CapTargetList  = Caps
    261         self.AutoGenObjectList = []
    262 
    263         # there's many relative directory operations, so ...

    264         os.chdir(self.WorkspaceDir)
    265 
    266         #

    267         # Merge Arch

    268         #

    269         if not self.ArchList:
    270             ArchList = set(self.Platform.SupArchList)
    271         else:
    272             ArchList = set(self.ArchList) & set(self.Platform.SupArchList)
    273         if not ArchList:
    274             EdkLogger.error("build", PARAMETER_INVALID,
    275                             ExtraData = "Invalid ARCH specified. [Valid ARCH: %s]" % (" ".join(self.Platform.SupArchList)))
    276         elif self.ArchList and len(ArchList) != len(self.ArchList):
    277             SkippedArchList = set(self.ArchList).symmetric_difference(set(self.Platform.SupArchList))
    278             EdkLogger.verbose("\nArch [%s] is ignored because the platform supports [%s] only!"
    279                               % (" ".join(SkippedArchList), " ".join(self.Platform.SupArchList)))
    280         self.ArchList = tuple(ArchList)
    281 
    282         # Validate build target

    283         if self.BuildTarget not in self.Platform.BuildTargets:
    284             EdkLogger.error("build", PARAMETER_INVALID,
    285                             ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]"
    286                                       % (self.BuildTarget, " ".join(self.Platform.BuildTargets)))
    287 
    288         
    289         # parse FDF file to get PCDs in it, if any

    290         if not self.FdfFile:
    291             self.FdfFile = self.Platform.FlashDefinition
    292 
    293         EdkLogger.info("")
    294         if self.ArchList:
    295             EdkLogger.info('%-16s = %s' % ("Architecture(s)", ' '.join(self.ArchList)))
    296         EdkLogger.info('%-16s = %s' % ("Build target", self.BuildTarget))
    297         EdkLogger.info('%-16s = %s' % ("Toolchain", self.ToolChain))
    298 
    299         EdkLogger.info('\n%-24s = %s' % ("Active Platform", self.Platform))
    300         if BuildModule:
    301             EdkLogger.info('%-24s = %s' % ("Active Module", BuildModule))
    302 
    303         if self.FdfFile:
    304             EdkLogger.info('%-24s = %s' % ("Flash Image Definition", self.FdfFile))
    305 
    306         EdkLogger.verbose("\nFLASH_DEFINITION = %s" % self.FdfFile)
    307 
    308         if Progress:
    309             Progress.Start("\nProcessing meta-data")
    310 
    311         if self.FdfFile:
    312             #

    313             # Mark now build in AutoGen Phase

    314             #

    315             GlobalData.gAutoGenPhase = True
    316             Fdf = FdfParser(self.FdfFile.Path)
    317             Fdf.ParseFile()
    318             GlobalData.gFdfParser = Fdf
    319             GlobalData.gAutoGenPhase = False
    320             PcdSet = Fdf.Profile.PcdDict
    321             if Fdf.CurrentFdName and Fdf.CurrentFdName in Fdf.Profile.FdDict:
    322                 FdDict = Fdf.Profile.FdDict[Fdf.CurrentFdName]
    323                 for FdRegion in FdDict.RegionList:
    324                     if str(FdRegion.RegionType) is 'FILE' and self.Platform.VpdToolGuid in str(FdRegion.RegionDataList):
    325                         if int(FdRegion.Offset) % 8 != 0:
    326                             EdkLogger.error("build", FORMAT_INVALID, 'The VPD Base Address %s must be 8-byte aligned.' % (FdRegion.Offset))
    327             ModuleList = Fdf.Profile.InfList
    328             self.FdfProfile = Fdf.Profile
    329             for fvname in self.FvTargetList:
    330                 if fvname.upper() not in self.FdfProfile.FvDict:
    331                     EdkLogger.error("build", OPTION_VALUE_INVALID,
    332                                     "No such an FV in FDF file: %s" % fvname)
    333 
    334             # In DSC file may use FILE_GUID to override the module, then in the Platform.Modules use FILE_GUIDmodule.inf as key,

    335             # but the path (self.MetaFile.Path) is the real path

    336             for key in self.FdfProfile.InfDict:
    337                 if key == 'ArchTBD':
    338                     Platform_cache = {}
    339                     MetaFile_cache = {}
    340                     for Arch in self.ArchList:
    341                         Platform_cache[Arch] = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
    342                         MetaFile_cache[Arch] = []
    343                         for Pkey in Platform_cache[Arch].Modules.keys():
    344                             MetaFile_cache[Arch].append(Platform_cache[Arch].Modules[Pkey].MetaFile)
    345                     for Inf in self.FdfProfile.InfDict[key]:
    346                         ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)
    347                         for Arch in self.ArchList:
    348                             if ModuleFile in MetaFile_cache[Arch]:
    349                                 break
    350                         else:
    351                             ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
    352                             if not ModuleData.IsBinaryModule:
    353                                 EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)
    354 
    355                 else:
    356                     for Arch in self.ArchList:
    357                         if Arch == key:
    358                             Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
    359                             MetaFileList = []
    360                             for Pkey in Platform.Modules.keys():
    361                                 MetaFileList.append(Platform.Modules[Pkey].MetaFile)
    362                             for Inf in self.FdfProfile.InfDict[key]:
    363                                 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)
    364                                 if ModuleFile in MetaFileList:
    365                                     continue
    366                                 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
    367                                 if not ModuleData.IsBinaryModule:
    368                                     EdkLogger.error('build', PARSER_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % ModuleFile)
    369 
    370         else:
    371             PcdSet = {}
    372             ModuleList = []
    373             self.FdfProfile = None
    374             if self.FdTargetList:
    375                 EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdTargetList))
    376                 self.FdTargetList = []
    377             if self.FvTargetList:
    378                 EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvTargetList))
    379                 self.FvTargetList = []
    380             if self.CapTargetList:
    381                 EdkLogger.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self.CapTargetList))
    382                 self.CapTargetList = []
    383 
    384         # apply SKU and inject PCDs from Flash Definition file

    385         for Arch in self.ArchList:
    386             Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
    387 
    388             DecPcds = {}
    389             DecPcdsKey = set()
    390             PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
    391             if GlobalData.BuildOptionPcd:
    392                 for i, pcd in enumerate(GlobalData.BuildOptionPcd):
    393                     if type(pcd) is tuple:
    394                         continue
    395                     (pcdname, pcdvalue) = pcd.split('=')
    396                     if not pcdvalue:
    397                         EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
    398                     if '.' in pcdname:
    399                         (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')
    400                         HasTokenSpace = True
    401                     else:
    402                         TokenCName = pcdname
    403                         TokenSpaceGuidCName = ''
    404                         HasTokenSpace = False
    405                     TokenSpaceGuidCNameList = []
    406                     FoundFlag = False
    407                     PcdDatumType = ''
    408                     NewValue = ''
    409                     for package in PGen.PackageList:
    410                         for key in package.Pcds:
    411                             PcdItem = package.Pcds[key]
    412                             if HasTokenSpace:
    413                                 if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
    414                                     PcdDatumType = PcdItem.DatumType
    415                                     NewValue = self._BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
    416                                     FoundFlag = True
    417                             else:
    418                                 if PcdItem.TokenCName == TokenCName:
    419                                     if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
    420                                         if len (TokenSpaceGuidCNameList) < 1:
    421                                             TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
    422                                             PcdDatumType = PcdItem.DatumType
    423                                             TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
    424                                             NewValue = self._BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
    425                                             FoundFlag = True
    426                                         else:
    427                                             EdkLogger.error(
    428                                                     'build',
    429                                                      AUTOGEN_ERROR,
    430                                                     "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
    431                                                     )
    432 
    433                     GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)
    434 
    435                     if not FoundFlag:
    436                         if HasTokenSpace:
    437                             EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))
    438                         else:
    439                             EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName))
    440 
    441                     for BuildData in PGen.BuildDatabase._CACHE_.values():
    442                         if BuildData.Arch != Arch:
    443                             continue
    444                         if BuildData.MetaFile.Ext == '.dec':
    445                             continue
    446                         for key in BuildData.Pcds:
    447                             PcdItem = BuildData.Pcds[key]
    448                             if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName):
    449                                 PcdItem.DefaultValue = NewValue
    450 
    451                     if (TokenCName, TokenSpaceGuidCName) in PcdSet:
    452                         PcdSet[(TokenCName, TokenSpaceGuidCName)] = NewValue
    453 
    454             SourcePcdDict = {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}
    455             BinaryPcdDict = {'DynamicEx':[], 'PatchableInModule':[]}
    456             SourcePcdDict_Keys = SourcePcdDict.keys()
    457             BinaryPcdDict_Keys = BinaryPcdDict.keys()
    458 
    459             # generate the SourcePcdDict and BinaryPcdDict

    460             for BuildData in PGen.BuildDatabase._CACHE_.values():
    461                 if BuildData.Arch != Arch:
    462                     continue
    463                 if BuildData.MetaFile.Ext == '.inf':
    464                     for key in BuildData.Pcds:
    465                         if BuildData.Pcds[key].Pending:
    466                             if key in Platform.Pcds:
    467                                 PcdInPlatform = Platform.Pcds[key]
    468                                 if PcdInPlatform.Type not in [None, '']:
    469                                     BuildData.Pcds[key].Type = PcdInPlatform.Type
    470 
    471                             if BuildData.MetaFile in Platform.Modules:
    472                                 PlatformModule = Platform.Modules[str(BuildData.MetaFile)]
    473                                 if key in PlatformModule.Pcds:
    474                                     PcdInPlatform = PlatformModule.Pcds[key]
    475                                     if PcdInPlatform.Type not in [None, '']:
    476                                         BuildData.Pcds[key].Type = PcdInPlatform.Type
    477 
    478                         if 'DynamicEx' in BuildData.Pcds[key].Type:
    479                             if BuildData.IsBinaryModule:
    480                                 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['DynamicEx']:
    481                                     BinaryPcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
    482                             else:
    483                                 if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['DynamicEx']:
    484                                     SourcePcdDict['DynamicEx'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
    485 
    486                         elif 'PatchableInModule' in BuildData.Pcds[key].Type:
    487                             if BuildData.MetaFile.Ext == '.inf':
    488                                 if BuildData.IsBinaryModule:
    489                                     if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in BinaryPcdDict['PatchableInModule']:
    490                                         BinaryPcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
    491                                 else:
    492                                     if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['PatchableInModule']:
    493                                         SourcePcdDict['PatchableInModule'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
    494 
    495                         elif 'Dynamic' in BuildData.Pcds[key].Type:
    496                             if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['Dynamic']:
    497                                 SourcePcdDict['Dynamic'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
    498                         elif 'FixedAtBuild' in BuildData.Pcds[key].Type:
    499                             if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) not in SourcePcdDict['FixedAtBuild']:
    500                                 SourcePcdDict['FixedAtBuild'].append((BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName))
    501                 else:
    502                     pass
    503 
    504             #

    505             # intersection the BinaryPCD for Mixed PCD

    506             #

    507             for i in BinaryPcdDict_Keys:
    508                 for j in BinaryPcdDict_Keys:
    509                     if i != j:
    510                         IntersectionList = list(set(BinaryPcdDict[i]).intersection(set(BinaryPcdDict[j])))
    511                         for item in IntersectionList:
    512                             NewPcd1 = (item[0] + '_' + i, item[1])
    513                             NewPcd2 = (item[0] + '_' + j, item[1])
    514                             if item not in GlobalData.MixedPcd:
    515                                 GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]
    516                             else:
    517                                 if NewPcd1 not in GlobalData.MixedPcd[item]:
    518                                     GlobalData.MixedPcd[item].append(NewPcd1)
    519                                 if NewPcd2 not in GlobalData.MixedPcd[item]:
    520                                     GlobalData.MixedPcd[item].append(NewPcd2)
    521                     else:
    522                         pass
    523 
    524             #

    525             # intersection the SourcePCD and BinaryPCD for Mixed PCD

    526             #

    527             for i in SourcePcdDict_Keys:
    528                 for j in BinaryPcdDict_Keys:
    529                     if i != j:
    530                         IntersectionList = list(set(SourcePcdDict[i]).intersection(set(BinaryPcdDict[j])))
    531                         for item in IntersectionList:
    532                             NewPcd1 = (item[0] + '_' + i, item[1])
    533                             NewPcd2 = (item[0] + '_' + j, item[1])
    534                             if item not in GlobalData.MixedPcd:
    535                                 GlobalData.MixedPcd[item] = [NewPcd1, NewPcd2]
    536                             else:
    537                                 if NewPcd1 not in GlobalData.MixedPcd[item]:
    538                                     GlobalData.MixedPcd[item].append(NewPcd1)
    539                                 if NewPcd2 not in GlobalData.MixedPcd[item]:
    540                                     GlobalData.MixedPcd[item].append(NewPcd2)
    541                     else:
    542                         pass
    543 
    544             for BuildData in PGen.BuildDatabase._CACHE_.values():
    545                 if BuildData.Arch != Arch:
    546                     continue
    547                 for key in BuildData.Pcds:
    548                     for SinglePcd in GlobalData.MixedPcd:
    549                         if (BuildData.Pcds[key].TokenCName, BuildData.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
    550                             for item in GlobalData.MixedPcd[SinglePcd]:
    551                                 Pcd_Type = item[0].split('_')[-1]
    552                                 if (Pcd_Type == BuildData.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and BuildData.Pcds[key].Type in GenC.gDynamicExPcd) or \
    553                                    (Pcd_Type == TAB_PCDS_DYNAMIC and BuildData.Pcds[key].Type in GenC.gDynamicPcd):
    554                                     Value = BuildData.Pcds[key]
    555                                     Value.TokenCName = BuildData.Pcds[key].TokenCName + '_' + Pcd_Type
    556                                     if len(key) == 2:
    557                                         newkey = (Value.TokenCName, key[1])
    558                                     elif len(key) == 3:
    559                                         newkey = (Value.TokenCName, key[1], key[2])
    560                                     del BuildData.Pcds[key]
    561                                     BuildData.Pcds[newkey] = Value
    562                                     break
    563                                 else:
    564                                     pass
    565                             break
    566                         else:
    567                             pass
    568 
    569             # handle the mixed pcd in FDF file

    570             for key in PcdSet:
    571                 if key in GlobalData.MixedPcd:
    572                     Value = PcdSet[key]
    573                     del PcdSet[key]
    574                     for item in GlobalData.MixedPcd[key]:
    575                         PcdSet[item] = Value
    576 
    577             #Collect package set information from INF of FDF

    578             PkgSet = set()
    579             for Inf in ModuleList:
    580                 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)
    581                 if ModuleFile in Platform.Modules:
    582                     continue
    583                 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
    584                 PkgSet.update(ModuleData.Packages)
    585             Pkgs = list(PkgSet) + list(PGen.PackageList)
    586             for Pkg in Pkgs:
    587                 for Pcd in Pkg.Pcds:
    588                     DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
    589                     DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))
    590 
    591             Platform.SkuName = self.SkuId
    592             for Name, Guid in PcdSet:
    593                 if (Name, Guid) not in DecPcds:
    594                     EdkLogger.error(
    595                         'build',
    596                         PARSER_ERROR,
    597                         "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid, Name),
    598                         File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],
    599                         Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]
    600                     )
    601                 else:
    602                     # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.

    603                     if (Name, Guid, TAB_PCDS_FIXED_AT_BUILD) in DecPcdsKey \
    604                         or (Name, Guid, TAB_PCDS_PATCHABLE_IN_MODULE) in DecPcdsKey \
    605                         or (Name, Guid, TAB_PCDS_FEATURE_FLAG) in DecPcdsKey:
    606                         Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])
    607                         continue
    608                     elif (Name, Guid, TAB_PCDS_DYNAMIC) in DecPcdsKey or (Name, Guid, TAB_PCDS_DYNAMIC_EX) in DecPcdsKey:
    609                         EdkLogger.error(
    610                                 'build',
    611                                 PARSER_ERROR,
    612                                 "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid, Name),
    613                                 File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],
    614                                 Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]
    615                         )
    616 
    617             Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
    618             #

    619             # Explicitly collect platform's dynamic PCDs

    620             #

    621             Pa.CollectPlatformDynamicPcds()
    622             Pa.CollectFixedAtBuildPcds()
    623             self.AutoGenObjectList.append(Pa)
    624 
    625         #

    626         # Check PCDs token value conflict in each DEC file.

    627         #

    628         self._CheckAllPcdsTokenValueConflict()
    629 
    630         #

    631         # Check PCD type and definition between DSC and DEC

    632         #

    633         self._CheckPcdDefineAndType()
    634 
    635 #         if self.FdfFile:

    636 #             self._CheckDuplicateInFV(Fdf)

    637 
    638         self._BuildDir = None
    639         self._FvDir = None
    640         self._MakeFileDir = None
    641         self._BuildCommand = None
    642 
    643         return True
    644 
    645     def _BuildOptionPcdValueFormat(self, TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):
    646         if PcdDatumType == 'VOID*':
    647             if Value.startswith('L'):
    648                 if not Value[1]:
    649                     EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
    650                 Value = Value[0] + '"' + Value[1:] + '"'
    651             elif Value.startswith('B'):
    652                 if not Value[1]:
    653                     EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
    654                 Value = Value[1:]
    655             else:
    656                 if not Value[0]:
    657                     EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"')
    658                 Value = '"' + Value + '"'
    659 
    660         IsValid, Cause = CheckPcdDatum(PcdDatumType, Value)
    661         if not IsValid:
    662             EdkLogger.error('build', FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName))
    663         if PcdDatumType == 'BOOLEAN':
    664             Value = Value.upper()
    665             if Value == 'TRUE' or Value == '1':
    666                 Value = '1'
    667             elif Value == 'FALSE' or Value == '0':
    668                 Value = '0'
    669         return  Value
    670 
    671     ## _CheckDuplicateInFV() method

    672     #

    673     # Check whether there is duplicate modules/files exist in FV section. 

    674     # The check base on the file GUID;

    675     #

    676     def _CheckDuplicateInFV(self, Fdf):
    677         for Fv in Fdf.Profile.FvDict:
    678             _GuidDict = {}
    679             for FfsFile in Fdf.Profile.FvDict[Fv].FfsList:
    680                 if FfsFile.InfFileName and FfsFile.NameGuid == None:
    681                     #

    682                     # Get INF file GUID

    683                     #

    684                     InfFoundFlag = False
    685                     for Pa in self.AutoGenObjectList:
    686                         if InfFoundFlag:
    687                             break
    688                         for Module in Pa.ModuleAutoGenList:
    689                             if path.normpath(Module.MetaFile.File) == path.normpath(FfsFile.InfFileName):
    690                                 InfFoundFlag = True
    691                                 if not Module.Guid.upper() in _GuidDict.keys():
    692                                     _GuidDict[Module.Guid.upper()] = FfsFile
    693                                     break
    694                                 else:
    695                                     EdkLogger.error("build",
    696                                                     FORMAT_INVALID,
    697                                                     "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
    698                                                                                                                                    FfsFile.CurrentLineContent,
    699                                                                                                                                    _GuidDict[Module.Guid.upper()].CurrentLineNum,
    700                                                                                                                                    _GuidDict[Module.Guid.upper()].CurrentLineContent,
    701                                                                                                                                    Module.Guid.upper()),
    702                                                     ExtraData=self.FdfFile)
    703                     #

    704                     # Some INF files not have entity in DSC file. 

    705                     #

    706                     if not InfFoundFlag:
    707                         if FfsFile.InfFileName.find('$') == -1:
    708                             InfPath = NormPath(FfsFile.InfFileName)
    709                             if not os.path.exists(InfPath):
    710                                 EdkLogger.error('build', GENFDS_ERROR, "Non-existant Module %s !" % (FfsFile.InfFileName))
    711 
    712                             PathClassObj = PathClass(FfsFile.InfFileName, self.WorkspaceDir)
    713                             #

    714                             # Here we just need to get FILE_GUID from INF file, use 'COMMON' as ARCH attribute. and use 

    715                             # BuildObject from one of AutoGenObjectList is enough.

    716                             #

    717                             InfObj = self.AutoGenObjectList[0].BuildDatabase.WorkspaceDb.BuildObject[PathClassObj, 'COMMON', self.BuildTarget, self.ToolChain]
    718                             if not InfObj.Guid.upper() in _GuidDict.keys():
    719                                 _GuidDict[InfObj.Guid.upper()] = FfsFile
    720                             else:
    721                                 EdkLogger.error("build",
    722                                                 FORMAT_INVALID,
    723                                                 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
    724                                                                                                                                FfsFile.CurrentLineContent,
    725                                                                                                                                _GuidDict[InfObj.Guid.upper()].CurrentLineNum,
    726                                                                                                                                _GuidDict[InfObj.Guid.upper()].CurrentLineContent,
    727                                                                                                                                InfObj.Guid.upper()),
    728                                                 ExtraData=self.FdfFile)
    729                         InfFoundFlag = False
    730 
    731                 if FfsFile.NameGuid != None:
    732                     _CheckPCDAsGuidPattern = re.compile("^PCD\(.+\..+\)$")
    733 
    734                     #

    735                     # If the NameGuid reference a PCD name. 

    736                     # The style must match: PCD(xxxx.yyy)

    737                     #

    738                     if _CheckPCDAsGuidPattern.match(FfsFile.NameGuid):
    739                         #

    740                         # Replace the PCD value.

    741                         #

    742                         _PcdName = FfsFile.NameGuid.lstrip("PCD(").rstrip(")")
    743                         PcdFoundFlag = False
    744                         for Pa in self.AutoGenObjectList:
    745                             if not PcdFoundFlag:
    746                                 for PcdItem in Pa.AllPcdList:
    747                                     if (PcdItem.TokenSpaceGuidCName + "." + PcdItem.TokenCName) == _PcdName:
    748                                         #

    749                                         # First convert from CFormatGuid to GUID string

    750                                         #

    751                                         _PcdGuidString = GuidStructureStringToGuidString(PcdItem.DefaultValue)
    752 
    753                                         if not _PcdGuidString:
    754                                             #

    755                                             # Then try Byte array.

    756                                             #

    757                                             _PcdGuidString = GuidStructureByteArrayToGuidString(PcdItem.DefaultValue)
    758 
    759                                         if not _PcdGuidString:
    760                                             #

    761                                             # Not Byte array or CFormat GUID, raise error.

    762                                             #

    763                                             EdkLogger.error("build",
    764                                                             FORMAT_INVALID,
    765                                                             "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName, PcdItem.DefaultValue),
    766                                                             ExtraData=self.FdfFile)
    767 
    768                                         if not _PcdGuidString.upper() in _GuidDict.keys():
    769                                             _GuidDict[_PcdGuidString.upper()] = FfsFile
    770                                             PcdFoundFlag = True
    771                                             break
    772                                         else:
    773                                             EdkLogger.error("build",
    774                                                             FORMAT_INVALID,
    775                                                             "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
    776                                                                                                                                            FfsFile.CurrentLineContent,
    777                                                                                                                                            _GuidDict[_PcdGuidString.upper()].CurrentLineNum,
    778                                                                                                                                            _GuidDict[_PcdGuidString.upper()].CurrentLineContent,
    779                                                                                                                                            FfsFile.NameGuid.upper()),
    780                                                             ExtraData=self.FdfFile)
    781 
    782                     if not FfsFile.NameGuid.upper() in _GuidDict.keys():
    783                         _GuidDict[FfsFile.NameGuid.upper()] = FfsFile
    784                     else:
    785                         #

    786                         # Two raw file GUID conflict.

    787                         #

    788                         EdkLogger.error("build",
    789                                         FORMAT_INVALID,
    790                                         "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
    791                                                                                                                        FfsFile.CurrentLineContent,
    792                                                                                                                        _GuidDict[FfsFile.NameGuid.upper()].CurrentLineNum,
    793                                                                                                                        _GuidDict[FfsFile.NameGuid.upper()].CurrentLineContent,
    794                                                                                                                        FfsFile.NameGuid.upper()),
    795                                         ExtraData=self.FdfFile)
    796 
    797 
    798     def _CheckPcdDefineAndType(self):
    799         PcdTypeList = [
    800             "FixedAtBuild", "PatchableInModule", "FeatureFlag",
    801             "Dynamic", #"DynamicHii", "DynamicVpd",

    802             "DynamicEx", # "DynamicExHii", "DynamicExVpd"

    803         ]
    804 
    805         # This dict store PCDs which are not used by any modules with specified arches

    806         UnusedPcd = sdict()
    807         for Pa in self.AutoGenObjectList:
    808             # Key of DSC's Pcds dictionary is PcdCName, TokenSpaceGuid

    809             for Pcd in Pa.Platform.Pcds:
    810                 PcdType = Pa.Platform.Pcds[Pcd].Type
    811 
    812                 # If no PCD type, this PCD comes from FDF 

    813                 if not PcdType:
    814                     continue
    815 
    816                 # Try to remove Hii and Vpd suffix

    817                 if PcdType.startswith("DynamicEx"):
    818                     PcdType = "DynamicEx"
    819                 elif PcdType.startswith("Dynamic"):
    820                     PcdType = "Dynamic"
    821 
    822                 for Package in Pa.PackageList:
    823                     # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType

    824                     if (Pcd[0], Pcd[1], PcdType) in Package.Pcds:
    825                         break
    826                     for Type in PcdTypeList:
    827                         if (Pcd[0], Pcd[1], Type) in Package.Pcds:
    828                             EdkLogger.error(
    829                                 'build',
    830                                 FORMAT_INVALID,
    831                                 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \
    832                                 % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type),
    833                                 ExtraData=None
    834                             )
    835                             return
    836                 else:
    837                     UnusedPcd.setdefault(Pcd, []).append(Pa.Arch)
    838 
    839         for Pcd in UnusedPcd:
    840             EdkLogger.warn(
    841                 'build',
    842                 "The PCD was not specified by any INF module in the platform for the given architecture.\n"
    843                 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"
    844                 % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])),
    845                 ExtraData=None
    846             )
    847 
    848     def __repr__(self):
    849         return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))
    850 
    851     ## Return the directory to store FV files

    852     def _GetFvDir(self):
    853         if self._FvDir == None:
    854             self._FvDir = path.join(self.BuildDir, 'FV')
    855         return self._FvDir
    856 
    857     ## Return the directory to store all intermediate and final files built

    858     def _GetBuildDir(self):
    859         return self.AutoGenObjectList[0].BuildDir
    860 
    861     ## Return the build output directory platform specifies

    862     def _GetOutputDir(self):
    863         return self.Platform.OutputDirectory
    864 
    865     ## Return platform name

    866     def _GetName(self):
    867         return self.Platform.PlatformName
    868 
    869     ## Return meta-file GUID

    870     def _GetGuid(self):
    871         return self.Platform.Guid
    872 
    873     ## Return platform version

    874     def _GetVersion(self):
    875         return self.Platform.Version
    876 
    877     ## Return paths of tools

    878     def _GetToolDefinition(self):
    879         return self.AutoGenObjectList[0].ToolDefinition
    880 
    881     ## Return directory of platform makefile

    882     #

    883     #   @retval     string  Makefile directory

    884     #

    885     def _GetMakeFileDir(self):
    886         if self._MakeFileDir == None:
    887             self._MakeFileDir = self.BuildDir
    888         return self._MakeFileDir
    889 
    890     ## Return build command string

    891     #

    892     #   @retval     string  Build command string

    893     #

    894     def _GetBuildCommand(self):
    895         if self._BuildCommand == None:
    896             # BuildCommand should be all the same. So just get one from platform AutoGen

    897             self._BuildCommand = self.AutoGenObjectList[0].BuildCommand
    898         return self._BuildCommand
    899 
    900     ## Check the PCDs token value conflict in each DEC file.

    901     #

    902     # Will cause build break and raise error message while two PCDs conflict.

    903     # 

    904     # @return  None

    905     #

    906     def _CheckAllPcdsTokenValueConflict(self):
    907         for Pa in self.AutoGenObjectList:
    908             for Package in Pa.PackageList:
    909                 PcdList = Package.Pcds.values()
    910                 PcdList.sort(lambda x, y: cmp(int(x.TokenValue, 0), int(y.TokenValue, 0))) 
    911                 Count = 0
    912                 while (Count < len(PcdList) - 1) :
    913                     Item = PcdList[Count]
    914                     ItemNext = PcdList[Count + 1]
    915                     #

    916                     # Make sure in the same token space the TokenValue should be unique

    917                     #

    918                     if (int(Item.TokenValue, 0) == int(ItemNext.TokenValue, 0)):
    919                         SameTokenValuePcdList = []
    920                         SameTokenValuePcdList.append(Item)
    921                         SameTokenValuePcdList.append(ItemNext)
    922                         RemainPcdListLength = len(PcdList) - Count - 2
    923                         for ValueSameCount in range(RemainPcdListLength):
    924                             if int(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount].TokenValue, 0) == int(Item.TokenValue, 0):
    925                                 SameTokenValuePcdList.append(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount])
    926                             else:
    927                                 break;
    928                         #

    929                         # Sort same token value PCD list with TokenGuid and TokenCName

    930                         #

    931                         SameTokenValuePcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))
    932                         SameTokenValuePcdListCount = 0
    933                         while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1):
    934                             Flag = False
    935                             TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount]
    936                             TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1]
    937 
    938                             if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName):
    939                                 for PcdItem in GlobalData.MixedPcd:
    940                                     if (TemListItem.TokenCName, TemListItem.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem] or \
    941                                         (TemListItemNext.TokenCName, TemListItemNext.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
    942                                         Flag = True
    943                                 if not Flag:
    944                                     EdkLogger.error(
    945                                                 'build',
    946                                                 FORMAT_INVALID,
    947                                                 "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
    948                                                 % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),
    949                                                 ExtraData=None
    950                                                 )
    951                             SameTokenValuePcdListCount += 1
    952                         Count += SameTokenValuePcdListCount
    953                     Count += 1
    954 
    955                 PcdList = Package.Pcds.values()
    956                 PcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))
    957                 Count = 0
    958                 while (Count < len(PcdList) - 1) :
    959                     Item = PcdList[Count]
    960                     ItemNext = PcdList[Count + 1]
    961                     #

    962                     # Check PCDs with same TokenSpaceGuidCName.TokenCName have same token value as well.

    963                     #

    964                     if (Item.TokenSpaceGuidCName == ItemNext.TokenSpaceGuidCName) and (Item.TokenCName == ItemNext.TokenCName) and (int(Item.TokenValue, 0) != int(ItemNext.TokenValue, 0)):
    965                         EdkLogger.error(
    966                                     'build',
    967                                     FORMAT_INVALID,
    968                                     "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\
    969                                     % (Item.TokenValue, Item.TokenSpaceGuidCName, Item.TokenCName, Package),
    970                                     ExtraData=None
    971                                     )
    972                     Count += 1
    973     ## Generate fds command

    974     def _GenFdsCommand(self):
    975         return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip()
    976 
    977     ## Create makefile for the platform and modules in it

    978     #

    979     #   @param      CreateDepsMakeFile      Flag indicating if the makefile for

    980     #                                       modules will be created as well

    981     #

    982     def CreateMakeFile(self, CreateDepsMakeFile=False):
    983         if CreateDepsMakeFile:
    984             for Pa in self.AutoGenObjectList:
    985                 Pa.CreateMakeFile(CreateDepsMakeFile)
    986 
    987     ## Create autogen code for platform and modules

    988     #

    989     #  Since there's no autogen code for platform, this method will do nothing

    990     #  if CreateModuleCodeFile is set to False.

    991     #

    992     #   @param      CreateDepsCodeFile      Flag indicating if creating module's

    993     #                                       autogen code file or not

    994     #

    995     def CreateCodeFile(self, CreateDepsCodeFile=False):
    996         if not CreateDepsCodeFile:
    997             return
    998         for Pa in self.AutoGenObjectList:
    999             Pa.CreateCodeFile(CreateDepsCodeFile)
   1000 
   1001     ## Create AsBuilt INF file the platform

   1002     #

   1003     def CreateAsBuiltInf(self):
   1004         return
   1005 
   1006     Name                = property(_GetName)
   1007     Guid                = property(_GetGuid)
   1008     Version             = property(_GetVersion)
   1009     OutputDir           = property(_GetOutputDir)
   1010 
   1011     ToolDefinition      = property(_GetToolDefinition)       # toolcode : tool path

   1012 
   1013     BuildDir            = property(_GetBuildDir)
   1014     FvDir               = property(_GetFvDir)
   1015     MakeFileDir         = property(_GetMakeFileDir)
   1016     BuildCommand        = property(_GetBuildCommand)
   1017     GenFdsCommand       = property(_GenFdsCommand)
   1018 
   1019 ## AutoGen class for platform

   1020 #

   1021 #  PlatformAutoGen class will process the original information in platform

   1022 #  file in order to generate makefile for platform.

   1023 #

   1024 class PlatformAutoGen(AutoGen):
   1025     #

   1026     # Used to store all PCDs for both PEI and DXE phase, in order to generate 

   1027     # correct PCD database

   1028     # 

   1029     _DynaPcdList_ = []
   1030     _NonDynaPcdList_ = []
   1031     _PlatformPcds = {}
   1032     
   1033     #

   1034     # The priority list while override build option 

   1035     #

   1036     PrioList = {"0x11111"  : 16,     #  TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE (Highest)

   1037                 "0x01111"  : 15,     #  ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE

   1038                 "0x10111"  : 14,     #  TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE

   1039                 "0x00111"  : 13,     #  ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE 

   1040                 "0x11011"  : 12,     #  TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE

   1041                 "0x01011"  : 11,     #  ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE

   1042                 "0x10011"  : 10,     #  TARGET_*********_****_COMMANDTYPE_ATTRIBUTE

   1043                 "0x00011"  : 9,      #  ******_*********_****_COMMANDTYPE_ATTRIBUTE

   1044                 "0x11101"  : 8,      #  TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE

   1045                 "0x01101"  : 7,      #  ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE

   1046                 "0x10101"  : 6,      #  TARGET_*********_ARCH_***********_ATTRIBUTE

   1047                 "0x00101"  : 5,      #  ******_*********_ARCH_***********_ATTRIBUTE

   1048                 "0x11001"  : 4,      #  TARGET_TOOLCHAIN_****_***********_ATTRIBUTE

   1049                 "0x01001"  : 3,      #  ******_TOOLCHAIN_****_***********_ATTRIBUTE

   1050                 "0x10001"  : 2,      #  TARGET_*********_****_***********_ATTRIBUTE

   1051                 "0x00001"  : 1}      #  ******_*********_****_***********_ATTRIBUTE (Lowest)

   1052 
   1053     ## The real constructor of PlatformAutoGen

   1054     #

   1055     #  This method is not supposed to be called by users of PlatformAutoGen. It's

   1056     #  only used by factory method __new__() to do real initialization work for an

   1057     #  object of PlatformAutoGen

   1058     #

   1059     #   @param      Workspace       WorkspaceAutoGen object

   1060     #   @param      PlatformFile    Platform file (DSC file)

   1061     #   @param      Target          Build target (DEBUG, RELEASE)

   1062     #   @param      Toolchain       Name of tool chain

   1063     #   @param      Arch            arch of the platform supports

   1064     #

   1065     def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):
   1066         EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))
   1067         GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)
   1068 
   1069         self.MetaFile = PlatformFile
   1070         self.Workspace = Workspace
   1071         self.WorkspaceDir = Workspace.WorkspaceDir
   1072         self.ToolChain = Toolchain
   1073         self.BuildTarget = Target
   1074         self.Arch = Arch
   1075         self.SourceDir = PlatformFile.SubDir
   1076         self.SourceOverrideDir = None
   1077         self.FdTargetList = self.Workspace.FdTargetList
   1078         self.FvTargetList = self.Workspace.FvTargetList
   1079         self.AllPcdList = []
   1080         # get the original module/package/platform objects

   1081         self.BuildDatabase = Workspace.BuildDatabase
   1082 
   1083         # flag indicating if the makefile/C-code file has been created or not

   1084         self.IsMakeFileCreated  = False
   1085         self.IsCodeFileCreated  = False
   1086 
   1087         self._Platform   = None
   1088         self._Name       = None
   1089         self._Guid       = None
   1090         self._Version    = None
   1091 
   1092         self._BuildRule = None
   1093         self._SourceDir = None
   1094         self._BuildDir = None
   1095         self._OutputDir = None
   1096         self._FvDir = None
   1097         self._MakeFileDir = None
   1098         self._FdfFile = None
   1099 
   1100         self._PcdTokenNumber = None    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber

   1101         self._DynamicPcdList = None    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]

   1102         self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]

   1103         self._NonDynamicPcdDict = {}
   1104 
   1105         self._ToolDefinitions = None
   1106         self._ToolDefFile = None          # toolcode : tool path

   1107         self._ToolChainFamily = None
   1108         self._BuildRuleFamily = None
   1109         self._BuildOption = None          # toolcode : option

   1110         self._EdkBuildOption = None       # edktoolcode : option

   1111         self._EdkIIBuildOption = None     # edkiitoolcode : option

   1112         self._PackageList = None
   1113         self._ModuleAutoGenList  = None
   1114         self._LibraryAutoGenList = None
   1115         self._BuildCommand = None
   1116         self._AsBuildInfList = []
   1117         self._AsBuildModuleList = []
   1118         if GlobalData.gFdfParser != None:
   1119             self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList
   1120             for Inf in self._AsBuildInfList:
   1121                 InfClass = PathClass(NormPath(Inf), GlobalData.gWorkspace, self.Arch)
   1122                 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]
   1123                 if not M.IsSupportedArch:
   1124                     continue
   1125                 self._AsBuildModuleList.append(InfClass)
   1126         # get library/modules for build

   1127         self.LibraryBuildDirectoryList = []
   1128         self.ModuleBuildDirectoryList = []
   1129         return True
   1130 
   1131     def __repr__(self):
   1132         return "%s [%s]" % (self.MetaFile, self.Arch)
   1133 
   1134     ## Create autogen code for platform and modules

   1135     #

   1136     #  Since there's no autogen code for platform, this method will do nothing

   1137     #  if CreateModuleCodeFile is set to False.

   1138     #

   1139     #   @param      CreateModuleCodeFile    Flag indicating if creating module's

   1140     #                                       autogen code file or not

   1141     #

   1142     def CreateCodeFile(self, CreateModuleCodeFile=False):
   1143         # only module has code to be greated, so do nothing if CreateModuleCodeFile is False

   1144         if self.IsCodeFileCreated or not CreateModuleCodeFile:
   1145             return
   1146 
   1147         for Ma in self.ModuleAutoGenList:
   1148             Ma.CreateCodeFile(True)
   1149 
   1150         # don't do this twice

   1151         self.IsCodeFileCreated = True
   1152 
   1153     ## Generate Fds Command

   1154     def _GenFdsCommand(self):
   1155         return self.Workspace.GenFdsCommand
   1156 
   1157     ## Create makefile for the platform and mdoules in it

   1158     #

   1159     #   @param      CreateModuleMakeFile    Flag indicating if the makefile for

   1160     #                                       modules will be created as well

   1161     #

   1162     def CreateMakeFile(self, CreateModuleMakeFile=False):
   1163         if CreateModuleMakeFile:
   1164             for ModuleFile in self.Platform.Modules:
   1165                 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,
   1166                                    self.ToolChain, self.Arch, self.MetaFile)
   1167                 Ma.CreateMakeFile(True)
   1168                 #Ma.CreateAsBuiltInf()

   1169 
   1170         # no need to create makefile for the platform more than once

   1171         if self.IsMakeFileCreated:
   1172             return
   1173 
   1174         # create library/module build dirs for platform

   1175         Makefile = GenMake.PlatformMakefile(self)
   1176         self.LibraryBuildDirectoryList = Makefile.GetLibraryBuildDirectoryList()
   1177         self.ModuleBuildDirectoryList = Makefile.GetModuleBuildDirectoryList()
   1178 
   1179         self.IsMakeFileCreated = True
   1180 
   1181     ## Deal with Shared FixedAtBuild Pcds

   1182     #

   1183     def CollectFixedAtBuildPcds(self):
   1184         for LibAuto in self.LibraryAutoGenList:
   1185             FixedAtBuildPcds = {}  
   1186             ShareFixedAtBuildPcdsSameValue = {} 
   1187             for Module in LibAuto._ReferenceModules:                
   1188                 for Pcd in Module.FixedAtBuildPcds + LibAuto.FixedAtBuildPcds:
   1189                     key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))  
   1190                     if key not in FixedAtBuildPcds:
   1191                         ShareFixedAtBuildPcdsSameValue[key] = True
   1192                         FixedAtBuildPcds[key] = Pcd.DefaultValue
   1193                     else:
   1194                         if FixedAtBuildPcds[key] != Pcd.DefaultValue:
   1195                             ShareFixedAtBuildPcdsSameValue[key] = False      
   1196             for Pcd in LibAuto.FixedAtBuildPcds:
   1197                 key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))
   1198                 if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) not in self.NonDynamicPcdDict:
   1199                     continue
   1200                 else:
   1201                     DscPcd = self.NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)]
   1202                     if DscPcd.Type != "FixedAtBuild":
   1203                         continue
   1204                 if key in ShareFixedAtBuildPcdsSameValue and ShareFixedAtBuildPcdsSameValue[key]:                    
   1205                     LibAuto.ConstPcd[key] = Pcd.DefaultValue
   1206 
   1207     ## Collect dynamic PCDs

   1208     #

   1209     #  Gather dynamic PCDs list from each module and their settings from platform

   1210     #  This interface should be invoked explicitly when platform action is created.

   1211     #

   1212     def CollectPlatformDynamicPcds(self):
   1213         # Override the platform Pcd's value by build option

   1214         if GlobalData.BuildOptionPcd:
   1215             for key in self.Platform.Pcds:
   1216                 PlatformPcd = self.Platform.Pcds[key]
   1217                 for PcdItem in GlobalData.BuildOptionPcd:
   1218                     if (PlatformPcd.TokenSpaceGuidCName, PlatformPcd.TokenCName) == (PcdItem[0], PcdItem[1]):
   1219                         PlatformPcd.DefaultValue = PcdItem[2]
   1220                         if PlatformPcd.SkuInfoList:
   1221                             Sku = PlatformPcd.SkuInfoList[PlatformPcd.SkuInfoList.keys()[0]]
   1222                             Sku.DefaultValue = PcdItem[2]
   1223                         break
   1224 
   1225         for key in self.Platform.Pcds:
   1226             for SinglePcd in GlobalData.MixedPcd:
   1227                 if (self.Platform.Pcds[key].TokenCName, self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
   1228                     for item in GlobalData.MixedPcd[SinglePcd]:
   1229                         Pcd_Type = item[0].split('_')[-1]
   1230                         if (Pcd_Type == self.Platform.Pcds[key].Type) or (Pcd_Type == TAB_PCDS_DYNAMIC_EX and self.Platform.Pcds[key].Type in GenC.gDynamicExPcd) or \
   1231                            (Pcd_Type == TAB_PCDS_DYNAMIC and self.Platform.Pcds[key].Type in GenC.gDynamicPcd):
   1232                             Value = self.Platform.Pcds[key]
   1233                             Value.TokenCName = self.Platform.Pcds[key].TokenCName + '_' + Pcd_Type
   1234                             if len(key) == 2:
   1235                                 newkey = (Value.TokenCName, key[1])
   1236                             elif len(key) == 3:
   1237                                 newkey = (Value.TokenCName, key[1], key[2])
   1238                             del self.Platform.Pcds[key]
   1239                             self.Platform.Pcds[newkey] = Value
   1240                             break
   1241                         else:
   1242                             pass
   1243                     break
   1244                 else:
   1245                     pass
   1246 
   1247         # for gathering error information

   1248         NoDatumTypePcdList = set()
   1249         PcdNotInDb = []
   1250         self._GuidValue = {}
   1251         FdfModuleList = []
   1252         for InfName in self._AsBuildInfList:
   1253             InfName = mws.join(self.WorkspaceDir, InfName)
   1254             FdfModuleList.append(os.path.normpath(InfName))
   1255         for F in self.Platform.Modules.keys():
   1256             M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)
   1257             #GuidValue.update(M.Guids)

   1258             
   1259             self.Platform.Modules[F].M = M
   1260 
   1261             for PcdFromModule in M.ModulePcdList + M.LibraryPcdList:
   1262                 # make sure that the "VOID*" kind of datum has MaxDatumSize set

   1263                 if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:
   1264                     NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))
   1265 
   1266                 # Check the PCD from Binary INF or Source INF

   1267                 if M.IsBinaryModule == True:
   1268                     PcdFromModule.IsFromBinaryInf = True
   1269 
   1270                 # Check the PCD from DSC or not 

   1271                 if (PcdFromModule.TokenCName, PcdFromModule.TokenSpaceGuidCName) in self.Platform.Pcds.keys():
   1272                     PcdFromModule.IsFromDsc = True
   1273                 else:
   1274                     PcdFromModule.IsFromDsc = False
   1275                 if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:
   1276                     if F.Path not in FdfModuleList:
   1277                         # If one of the Source built modules listed in the DSC is not listed 

   1278                         # in FDF modules, and the INF lists a PCD can only use the PcdsDynamic 

   1279                         # access method (it is only listed in the DEC file that declares the 

   1280                         # PCD as PcdsDynamic), then build tool will report warning message

   1281                         # notify the PI that they are attempting to build a module that must 

   1282                         # be included in a flash image in order to be functional. These Dynamic 

   1283                         # PCD will not be added into the Database unless it is used by other 

   1284                         # modules that are included in the FDF file.

   1285                         if PcdFromModule.Type in GenC.gDynamicPcd and \
   1286                             PcdFromModule.IsFromBinaryInf == False:
   1287                             # Print warning message to let the developer make a determine.

   1288                             if PcdFromModule not in PcdNotInDb:
   1289                                 PcdNotInDb.append(PcdFromModule)
   1290                             continue
   1291                         # If one of the Source built modules listed in the DSC is not listed in 

   1292                         # FDF modules, and the INF lists a PCD can only use the PcdsDynamicEx 

   1293                         # access method (it is only listed in the DEC file that declares the 

   1294                         # PCD as PcdsDynamicEx), then DO NOT break the build; DO NOT add the 

   1295                         # PCD to the Platform's PCD Database.

   1296                         if PcdFromModule.Type in GenC.gDynamicExPcd:
   1297                             if PcdFromModule not in PcdNotInDb:
   1298                                 PcdNotInDb.append(PcdFromModule)
   1299                             continue
   1300                     #

   1301                     # If a dynamic PCD used by a PEM module/PEI module & DXE module,

   1302                     # it should be stored in Pcd PEI database, If a dynamic only

   1303                     # used by DXE module, it should be stored in DXE PCD database.

   1304                     # The default Phase is DXE

   1305                     #

   1306                     if M.ModuleType in ["PEIM", "PEI_CORE"]:
   1307                         PcdFromModule.Phase = "PEI"
   1308                     if PcdFromModule not in self._DynaPcdList_:
   1309                         self._DynaPcdList_.append(PcdFromModule)
   1310                     elif PcdFromModule.Phase == 'PEI':
   1311                         # overwrite any the same PCD existing, if Phase is PEI

   1312                         Index = self._DynaPcdList_.index(PcdFromModule)
   1313                         self._DynaPcdList_[Index] = PcdFromModule
   1314                 elif PcdFromModule not in self._NonDynaPcdList_:
   1315                     self._NonDynaPcdList_.append(PcdFromModule)
   1316                 elif PcdFromModule in self._NonDynaPcdList_ and PcdFromModule.IsFromBinaryInf == True:
   1317                     Index = self._NonDynaPcdList_.index(PcdFromModule)
   1318                     if self._NonDynaPcdList_[Index].IsFromBinaryInf == False:
   1319                         #The PCD from Binary INF will override the same one from source INF

   1320                         self._NonDynaPcdList_.remove (self._NonDynaPcdList_[Index])
   1321                         PcdFromModule.Pending = False
   1322                         self._NonDynaPcdList_.append (PcdFromModule)
   1323         # Parse the DynamicEx PCD from the AsBuild INF module list of FDF.

   1324         DscModuleList = []
   1325         for ModuleInf in self.Platform.Modules.keys():
   1326             DscModuleList.append (os.path.normpath(ModuleInf.Path))
   1327         # add the PCD from modules that listed in FDF but not in DSC to Database 

   1328         for InfName in FdfModuleList:
   1329             if InfName not in DscModuleList:
   1330                 InfClass = PathClass(InfName)
   1331                 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]
   1332                 # If a module INF in FDF but not in current arch's DSC module list, it must be module (either binary or source) 

   1333                 # for different Arch. PCDs in source module for different Arch is already added before, so skip the source module here. 

   1334                 # For binary module, if in current arch, we need to list the PCDs into database.   

   1335                 if not M.IsSupportedArch:
   1336                     continue
   1337                 # Override the module PCD setting by platform setting

   1338                 ModulePcdList = self.ApplyPcdSetting(M, M.Pcds)
   1339                 for PcdFromModule in ModulePcdList:
   1340                     PcdFromModule.IsFromBinaryInf = True
   1341                     PcdFromModule.IsFromDsc = False
   1342                     # Only allow the DynamicEx and Patchable PCD in AsBuild INF

   1343                     if PcdFromModule.Type not in GenC.gDynamicExPcd and PcdFromModule.Type not in TAB_PCDS_PATCHABLE_IN_MODULE:
   1344                         EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
   1345                                         File=self.MetaFile,
   1346                                         ExtraData="\n\tExisted %s PCD %s in:\n\t\t%s\n"
   1347                                         % (PcdFromModule.Type, PcdFromModule.TokenCName, InfName))
   1348                     # make sure that the "VOID*" kind of datum has MaxDatumSize set

   1349                     if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:
   1350                         NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, InfName))
   1351                     if M.ModuleType in ["PEIM", "PEI_CORE"]:
   1352                         PcdFromModule.Phase = "PEI"
   1353                     if PcdFromModule not in self._DynaPcdList_ and PcdFromModule.Type in GenC.gDynamicExPcd:
   1354                         self._DynaPcdList_.append(PcdFromModule)
   1355                     elif PcdFromModule not in self._NonDynaPcdList_ and PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE:
   1356                         self._NonDynaPcdList_.append(PcdFromModule)
   1357                     if PcdFromModule in self._DynaPcdList_ and PcdFromModule.Phase == 'PEI' and PcdFromModule.Type in GenC.gDynamicExPcd:
   1358                         # Overwrite the phase of any the same PCD existing, if Phase is PEI.

   1359                         # It is to solve the case that a dynamic PCD used by a PEM module/PEI 

   1360                         # module & DXE module at a same time.

   1361                         # Overwrite the type of the PCDs in source INF by the type of AsBuild

   1362                         # INF file as DynamicEx. 

   1363                         Index = self._DynaPcdList_.index(PcdFromModule)
   1364                         self._DynaPcdList_[Index].Phase = PcdFromModule.Phase
   1365                         self._DynaPcdList_[Index].Type = PcdFromModule.Type
   1366         for PcdFromModule in self._NonDynaPcdList_:
   1367             # If a PCD is not listed in the DSC file, but binary INF files used by 

   1368             # this platform all (that use this PCD) list the PCD in a [PatchPcds] 

   1369             # section, AND all source INF files used by this platform the build 

   1370             # that use the PCD list the PCD in either a [Pcds] or [PatchPcds] 

   1371             # section, then the tools must NOT add the PCD to the Platform's PCD

   1372             # Database; the build must assign the access method for this PCD as 

   1373             # PcdsPatchableInModule.

   1374             if PcdFromModule not in self._DynaPcdList_:
   1375                 continue
   1376             Index = self._DynaPcdList_.index(PcdFromModule)
   1377             if PcdFromModule.IsFromDsc == False and \
   1378                 PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE and \
   1379                 PcdFromModule.IsFromBinaryInf == True and \
   1380                 self._DynaPcdList_[Index].IsFromBinaryInf == False:
   1381                 Index = self._DynaPcdList_.index(PcdFromModule)
   1382                 self._DynaPcdList_.remove (self._DynaPcdList_[Index])
   1383 
   1384         # print out error information and break the build, if error found

   1385         if len(NoDatumTypePcdList) > 0:
   1386             NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)
   1387             EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
   1388                             File=self.MetaFile,
   1389                             ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
   1390                                       % NoDatumTypePcdListString)
   1391         self._NonDynamicPcdList = self._NonDynaPcdList_
   1392         self._DynamicPcdList = self._DynaPcdList_
   1393         #

   1394         # Sort dynamic PCD list to:

   1395         # 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should 

   1396         #    try to be put header of dynamicd List

   1397         # 2) If PCD is HII type, the PCD item should be put after unicode type PCD

   1398         #

   1399         # The reason of sorting is make sure the unicode string is in double-byte alignment in string table.

   1400         #

   1401         UnicodePcdArray = []
   1402         HiiPcdArray     = []
   1403         OtherPcdArray   = []
   1404         VpdPcdDict      = {}
   1405         VpdFile               = VpdInfoFile.VpdInfoFile()
   1406         NeedProcessVpdMapFile = False
   1407 
   1408         for pcd in self.Platform.Pcds.keys():
   1409             if pcd not in self._PlatformPcds.keys():
   1410                 self._PlatformPcds[pcd] = self.Platform.Pcds[pcd]
   1411 
   1412         if (self.Workspace.ArchList[-1] == self.Arch): 
   1413             for Pcd in self._DynamicPcdList:
   1414                 # just pick the a value to determine whether is unicode string type

   1415                 Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
   1416                 Sku.VpdOffset = Sku.VpdOffset.strip()
   1417 
   1418                 PcdValue = Sku.DefaultValue
   1419                 if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):
   1420                     # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex

   1421                     UnicodePcdArray.append(Pcd)
   1422                 elif len(Sku.VariableName) > 0:
   1423                     # if found HII type PCD then insert to right of UnicodeIndex

   1424                     HiiPcdArray.append(Pcd)
   1425                 else:
   1426                     OtherPcdArray.append(Pcd)
   1427                 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
   1428                     VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd
   1429 
   1430             PlatformPcds = self._PlatformPcds.keys()
   1431             PlatformPcds.sort()
   1432             #

   1433             # Add VPD type PCD into VpdFile and determine whether the VPD PCD need to be fixed up.

   1434             #

   1435             for PcdKey in PlatformPcds:
   1436                 Pcd = self._PlatformPcds[PcdKey]
   1437                 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \
   1438                    PcdKey in VpdPcdDict:
   1439                     Pcd = VpdPcdDict[PcdKey]
   1440                     for (SkuName,Sku) in Pcd.SkuInfoList.items():
   1441                         Sku.VpdOffset = Sku.VpdOffset.strip()
   1442                         PcdValue = Sku.DefaultValue
   1443                         if PcdValue == "":
   1444                             PcdValue  = Pcd.DefaultValue
   1445                         if Sku.VpdOffset != '*':
   1446                             if PcdValue.startswith("{"):
   1447                                 Alignment = 8
   1448                             elif PcdValue.startswith("L"):
   1449                                 Alignment = 2
   1450                             else:
   1451                                 Alignment = 1
   1452                             try:
   1453                                 VpdOffset = int(Sku.VpdOffset)
   1454                             except:
   1455                                 try:
   1456                                     VpdOffset = int(Sku.VpdOffset, 16)
   1457                                 except:
   1458                                     EdkLogger.error("build", FORMAT_INVALID, "Invalid offset value %s for PCD %s.%s." % (Sku.VpdOffset, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
   1459                             if VpdOffset % Alignment != 0:
   1460                                 if PcdValue.startswith("{"):
   1461                                     EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(Pcd.TokenSpaceGuidCName, Pcd.TokenCName), File=self.MetaFile)
   1462                                 else:
   1463                                     EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Alignment))
   1464                         VpdFile.Add(Pcd, Sku.VpdOffset)
   1465                         # if the offset of a VPD is *, then it need to be fixed up by third party tool.

   1466                         if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
   1467                             NeedProcessVpdMapFile = True
   1468                             if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':
   1469                                 EdkLogger.error("Build", FILE_NOT_FOUND, \
   1470                                                 "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
   1471 
   1472 
   1473             #

   1474             # Fix the PCDs define in VPD PCD section that never referenced by module.

   1475             # An example is PCD for signature usage.

   1476             #            

   1477             for DscPcd in PlatformPcds:
   1478                 DscPcdEntry = self._PlatformPcds[DscPcd]
   1479                 if DscPcdEntry.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
   1480                     if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''):
   1481                         FoundFlag = False
   1482                         for VpdPcd in VpdFile._VpdArray.keys():
   1483                             # This PCD has been referenced by module

   1484                             if (VpdPcd.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \
   1485                                (VpdPcd.TokenCName == DscPcdEntry.TokenCName):
   1486                                     FoundFlag = True
   1487 
   1488                         # Not found, it should be signature

   1489                         if not FoundFlag :
   1490                             # just pick the a value to determine whether is unicode string type

   1491                             for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items():
   1492                                 Sku.VpdOffset = Sku.VpdOffset.strip() 
   1493                                 
   1494                                 # Need to iterate DEC pcd information to get the value & datumtype

   1495                                 for eachDec in self.PackageList:
   1496                                     for DecPcd in eachDec.Pcds:
   1497                                         DecPcdEntry = eachDec.Pcds[DecPcd]
   1498                                         if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \
   1499                                            (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName):
   1500                                             # Print warning message to let the developer make a determine.

   1501                                             EdkLogger.warn("build", "Unreferenced vpd pcd used!",
   1502                                                             File=self.MetaFile, \
   1503                                                             ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \
   1504                                                             %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path))  
   1505                                                                                   
   1506                                             DscPcdEntry.DatumType    = DecPcdEntry.DatumType
   1507                                             DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue
   1508                                             DscPcdEntry.TokenValue = DecPcdEntry.TokenValue
   1509                                             DscPcdEntry.TokenSpaceGuidValue = eachDec.Guids[DecPcdEntry.TokenSpaceGuidCName]
   1510                                             # Only fix the value while no value provided in DSC file.

   1511                                             if (Sku.DefaultValue == "" or Sku.DefaultValue==None):
   1512                                                 DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue
   1513                                                                                                                     
   1514                                 if DscPcdEntry not in self._DynamicPcdList:
   1515                                     self._DynamicPcdList.append(DscPcdEntry)
   1516 #                                Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]

   1517                                 Sku.VpdOffset = Sku.VpdOffset.strip()
   1518                                 PcdValue = Sku.DefaultValue
   1519                                 if PcdValue == "":
   1520                                     PcdValue  = DscPcdEntry.DefaultValue
   1521                                 if Sku.VpdOffset != '*':
   1522                                     if PcdValue.startswith("{"):
   1523                                         Alignment = 8
   1524                                     elif PcdValue.startswith("L"):
   1525                                         Alignment = 2
   1526                                     else:
   1527                                         Alignment = 1
   1528                                     try:
   1529                                         VpdOffset = int(Sku.VpdOffset)
   1530                                     except:
   1531                                         try:
   1532                                             VpdOffset = int(Sku.VpdOffset, 16)
   1533                                         except:
   1534                                             EdkLogger.error("build", FORMAT_INVALID, "Invalid offset value %s for PCD %s.%s." % (Sku.VpdOffset, DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName))
   1535                                     if VpdOffset % Alignment != 0:
   1536                                         if PcdValue.startswith("{"):
   1537                                             EdkLogger.warn("build", "The offset value of PCD %s.%s is not 8-byte aligned!" %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName), File=self.MetaFile)
   1538                                         else:
   1539                                             EdkLogger.error("build", FORMAT_INVALID, 'The offset value of PCD %s.%s should be %s-byte aligned.' % (DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, Alignment))
   1540                                 VpdFile.Add(DscPcdEntry, Sku.VpdOffset)
   1541                                 if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
   1542                                     NeedProcessVpdMapFile = True 
   1543                             if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"):
   1544                                 UnicodePcdArray.append(DscPcdEntry)
   1545                             elif len(Sku.VariableName) > 0:
   1546                                 HiiPcdArray.append(DscPcdEntry)
   1547                             else:
   1548                                 OtherPcdArray.append(DscPcdEntry)
   1549                                 
   1550                                 # if the offset of a VPD is *, then it need to be fixed up by third party tool.

   1551                                                        
   1552                     
   1553                     
   1554             if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \
   1555                VpdFile.GetCount() != 0:
   1556                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, 
   1557                                 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile))
   1558 
   1559             if VpdFile.GetCount() != 0:
   1560                 FvPath = os.path.join(self.BuildDir, "FV")
   1561                 if not os.path.exists(FvPath):
   1562                     try:
   1563                         os.makedirs(FvPath)
   1564                     except:
   1565                         EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir)
   1566 
   1567                 VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)
   1568 
   1569                 if VpdFile.Write(VpdFilePath):
   1570                     # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.

   1571                     BPDGToolName = None
   1572                     for ToolDef in self.ToolDefinition.values():
   1573                         if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid:
   1574                             if not ToolDef.has_key("PATH"):
   1575                                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid)
   1576                             BPDGToolName = ToolDef["PATH"]
   1577                             break
   1578                     # Call third party GUID BPDG tool.

   1579                     if BPDGToolName != None:
   1580                         VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath)
   1581                     else:
   1582                         EdkLogger.error("Build", FILE_NOT_FOUND, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
   1583 
   1584                 # Process VPD map file generated by third party BPDG tool

   1585                 if NeedProcessVpdMapFile:
   1586                     VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid)
   1587                     if os.path.exists(VpdMapFilePath):
   1588                         VpdFile.Read(VpdMapFilePath)
   1589 
   1590                         # Fixup "*" offset

   1591                         for Pcd in self._DynamicPcdList:
   1592                             # just pick the a value to determine whether is unicode string type

   1593                             i = 0
   1594                             for (SkuName,Sku) in Pcd.SkuInfoList.items():                        
   1595                                 if Sku.VpdOffset == "*":
   1596                                     Sku.VpdOffset = VpdFile.GetOffset(Pcd)[i].strip()
   1597                                 i += 1
   1598                     else:
   1599                         EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)
   1600 
   1601             # Delete the DynamicPcdList At the last time enter into this function 

   1602             del self._DynamicPcdList[:]
   1603         self._DynamicPcdList.extend(UnicodePcdArray)
   1604         self._DynamicPcdList.extend(HiiPcdArray)
   1605         self._DynamicPcdList.extend(OtherPcdArray)
   1606         self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList
   1607         
   1608     ## Return the platform build data object

   1609     def _GetPlatform(self):
   1610         if self._Platform == None:
   1611             self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
   1612         return self._Platform
   1613 
   1614     ## Return platform name

   1615     def _GetName(self):
   1616         return self.Platform.PlatformName
   1617 
   1618     ## Return the meta file GUID

   1619     def _GetGuid(self):
   1620         return self.Platform.Guid
   1621 
   1622     ## Return the platform version

   1623     def _GetVersion(self):
   1624         return self.Platform.Version
   1625 
   1626     ## Return the FDF file name

   1627     def _GetFdfFile(self):
   1628         if self._FdfFile == None:
   1629             if self.Workspace.FdfFile != "":
   1630                 self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile)
   1631             else:
   1632                 self._FdfFile = ''
   1633         return self._FdfFile
   1634 
   1635     ## Return the build output directory platform specifies

   1636     def _GetOutputDir(self):
   1637         return self.Platform.OutputDirectory
   1638 
   1639     ## Return the directory to store all intermediate and final files built

   1640     def _GetBuildDir(self):
   1641         if self._BuildDir == None:
   1642             if os.path.isabs(self.OutputDir):
   1643                 self._BuildDir = path.join(
   1644                                             path.abspath(self.OutputDir),
   1645                                             self.BuildTarget + "_" + self.ToolChain,
   1646                                             )
   1647             else:
   1648                 self._BuildDir = path.join(
   1649                                             self.WorkspaceDir,
   1650                                             self.OutputDir,
   1651                                             self.BuildTarget + "_" + self.ToolChain,
   1652                                             )
   1653         return self._BuildDir
   1654 
   1655     ## Return directory of platform makefile

   1656     #

   1657     #   @retval     string  Makefile directory

   1658     #

   1659     def _GetMakeFileDir(self):
   1660         if self._MakeFileDir == None:
   1661             self._MakeFileDir = path.join(self.BuildDir, self.Arch)
   1662         return self._MakeFileDir
   1663 
   1664     ## Return build command string

   1665     #

   1666     #   @retval     string  Build command string

   1667     #

   1668     def _GetBuildCommand(self):
   1669         if self._BuildCommand == None:
   1670             self._BuildCommand = []
   1671             if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:
   1672                 self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])
   1673                 if "FLAGS" in self.ToolDefinition["MAKE"]:
   1674                     NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()
   1675                     if NewOption != '':
   1676                         self._BuildCommand += SplitOption(NewOption)
   1677         return self._BuildCommand
   1678 
   1679     ## Get tool chain definition

   1680     #

   1681     #  Get each tool defition for given tool chain from tools_def.txt and platform

   1682     #

   1683     def _GetToolDefinition(self):
   1684         if self._ToolDefinitions == None:
   1685             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary
   1686             if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:
   1687                 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",
   1688                                 ExtraData="[%s]" % self.MetaFile)
   1689             self._ToolDefinitions = {}
   1690             DllPathList = set()
   1691             for Def in ToolDefinition:
   1692                 Target, Tag, Arch, Tool, Attr = Def.split("_")
   1693                 if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
   1694                     continue
   1695 
   1696                 Value = ToolDefinition[Def]
   1697                 # don't record the DLL

   1698                 if Attr == "DLL":
   1699                     DllPathList.add(Value)
   1700                     continue
   1701 
   1702                 if Tool not in self._ToolDefinitions:
   1703                     self._ToolDefinitions[Tool] = {}
   1704                 self._ToolDefinitions[Tool][Attr] = Value
   1705 
   1706             ToolsDef = ''
   1707             MakePath = ''
   1708             if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:
   1709                 if "FLAGS" not in self._ToolDefinitions["MAKE"]:
   1710                     self._ToolDefinitions["MAKE"]["FLAGS"] = ""
   1711                 self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"
   1712             MakeFlags = ''
   1713             for Tool in self._ToolDefinitions:
   1714                 for Attr in self._ToolDefinitions[Tool]:
   1715                     Value = self._ToolDefinitions[Tool][Attr]
   1716                     if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:
   1717                         # check if override is indicated

   1718                         if self.BuildOption[Tool][Attr].startswith('='):
   1719                             Value = self.BuildOption[Tool][Attr][1:]
   1720                         else:
   1721                             Value += " " + self.BuildOption[Tool][Attr]
   1722 
   1723                     if Attr == "PATH":
   1724                         # Don't put MAKE definition in the file

   1725                         if Tool == "MAKE":
   1726                             MakePath = Value
   1727                         else:
   1728                             ToolsDef += "%s = %s\n" % (Tool, Value)
   1729                     elif Attr != "DLL":
   1730                         # Don't put MAKE definition in the file

   1731                         if Tool == "MAKE":
   1732                             if Attr == "FLAGS":
   1733                                 MakeFlags = Value
   1734                         else:
   1735                             ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)
   1736                 ToolsDef += "\n"
   1737 
   1738             SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)
   1739             for DllPath in DllPathList:
   1740                 os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]
   1741             os.environ["MAKE_FLAGS"] = MakeFlags
   1742 
   1743         return self._ToolDefinitions
   1744 
   1745     ## Return the paths of tools

   1746     def _GetToolDefFile(self):
   1747         if self._ToolDefFile == None:
   1748             self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)
   1749         return self._ToolDefFile
   1750 
   1751     ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.

   1752     def _GetToolChainFamily(self):
   1753         if self._ToolChainFamily == None:
   1754             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
   1755             if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
   1756                or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
   1757                or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:
   1758                 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
   1759                                    % self.ToolChain)
   1760                 self._ToolChainFamily = "MSFT"
   1761             else:
   1762                 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]
   1763         return self._ToolChainFamily
   1764 
   1765     def _GetBuildRuleFamily(self):
   1766         if self._BuildRuleFamily == None:
   1767             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
   1768             if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \
   1769                or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \
   1770                or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:
   1771                 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
   1772                                    % self.ToolChain)
   1773                 self._BuildRuleFamily = "MSFT"
   1774             else:
   1775                 self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]
   1776         return self._BuildRuleFamily
   1777 
   1778     ## Return the build options specific for all modules in this platform

   1779     def _GetBuildOptions(self):
   1780         if self._BuildOption == None:
   1781             self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)
   1782         return self._BuildOption
   1783 
   1784     ## Return the build options specific for EDK modules in this platform

   1785     def _GetEdkBuildOptions(self):
   1786         if self._EdkBuildOption == None:
   1787             self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME)
   1788         return self._EdkBuildOption
   1789 
   1790     ## Return the build options specific for EDKII modules in this platform

   1791     def _GetEdkIIBuildOptions(self):
   1792         if self._EdkIIBuildOption == None:
   1793             self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)
   1794         return self._EdkIIBuildOption
   1795 
   1796     ## Parse build_rule.txt in Conf Directory.

   1797     #

   1798     #   @retval     BuildRule object

   1799     #

   1800     def _GetBuildRule(self):
   1801         if self._BuildRule == None:
   1802             BuildRuleFile = None
   1803             if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:
   1804                 BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
   1805             if BuildRuleFile in [None, '']:
   1806                 BuildRuleFile = gDefaultBuildRuleFile
   1807             self._BuildRule = BuildRule(BuildRuleFile)
   1808             if self._BuildRule._FileVersion == "":
   1809                 self._BuildRule._FileVersion = AutoGenReqBuildRuleVerNum
   1810             else:
   1811                 if self._BuildRule._FileVersion < AutoGenReqBuildRuleVerNum :
   1812                     # If Build Rule's version is less than the version number required by the tools, halting the build.

   1813                     EdkLogger.error("build", AUTOGEN_ERROR,
   1814                                     ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\
   1815                                      % (self._BuildRule._FileVersion, AutoGenReqBuildRuleVerNum))
   1816 
   1817         return self._BuildRule
   1818 
   1819     ## Summarize the packages used by modules in this platform

   1820     def _GetPackageList(self):
   1821         if self._PackageList == None:
   1822             self._PackageList = set()
   1823             for La in self.LibraryAutoGenList:
   1824                 self._PackageList.update(La.DependentPackageList)
   1825             for Ma in self.ModuleAutoGenList:
   1826                 self._PackageList.update(Ma.DependentPackageList)
   1827             #Collect package set information from INF of FDF

   1828             PkgSet = set()
   1829             for ModuleFile in self._AsBuildModuleList:
   1830                 if ModuleFile in self.Platform.Modules:
   1831                     continue
   1832                 ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain]
   1833                 PkgSet.update(ModuleData.Packages)
   1834             self._PackageList = list(self._PackageList) + list (PkgSet)
   1835         return self._PackageList
   1836 
   1837     def _GetNonDynamicPcdDict(self):
   1838         if self._NonDynamicPcdDict:
   1839             return self._NonDynamicPcdDict
   1840         for Pcd in self.NonDynamicPcdList:
   1841             self._NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)] = Pcd
   1842         return self._NonDynamicPcdDict
   1843 
   1844     ## Get list of non-dynamic PCDs

   1845     def _GetNonDynamicPcdList(self):
   1846         if self._NonDynamicPcdList == None:
   1847             self.CollectPlatformDynamicPcds()
   1848         return self._NonDynamicPcdList
   1849 
   1850     ## Get list of dynamic PCDs

   1851     def _GetDynamicPcdList(self):
   1852         if self._DynamicPcdList == None:
   1853             self.CollectPlatformDynamicPcds()
   1854         return self._DynamicPcdList
   1855 
   1856     ## Generate Token Number for all PCD

   1857     def _GetPcdTokenNumbers(self):
   1858         if self._PcdTokenNumber == None:
   1859             self._PcdTokenNumber = sdict()
   1860             TokenNumber = 1
   1861             #

   1862             # Make the Dynamic and DynamicEx PCD use within different TokenNumber area. 

   1863             # Such as:

   1864             # 

   1865             # Dynamic PCD:

   1866             # TokenNumber 0 ~ 10

   1867             # DynamicEx PCD:

   1868             # TokeNumber 11 ~ 20

   1869             #

   1870             for Pcd in self.DynamicPcdList:
   1871                 if Pcd.Phase == "PEI":
   1872                     if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
   1873                         EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
   1874                         self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1875                         TokenNumber += 1
   1876 
   1877             for Pcd in self.DynamicPcdList:
   1878                 if Pcd.Phase == "PEI":
   1879                     if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
   1880                         EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
   1881                         self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1882                         TokenNumber += 1
   1883 
   1884             for Pcd in self.DynamicPcdList:
   1885                 if Pcd.Phase == "DXE":
   1886                     if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
   1887                         EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
   1888                         self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1889                         TokenNumber += 1
   1890 
   1891             for Pcd in self.DynamicPcdList:
   1892                 if Pcd.Phase == "DXE":
   1893                     if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
   1894                         EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
   1895                         self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1896                         TokenNumber += 1
   1897 
   1898             for Pcd in self.NonDynamicPcdList:
   1899                 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1900                 TokenNumber += 1
   1901         return self._PcdTokenNumber
   1902 
   1903     ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform

   1904     def _GetAutoGenObjectList(self):
   1905         self._ModuleAutoGenList = []
   1906         self._LibraryAutoGenList = []
   1907         for ModuleFile in self.Platform.Modules:
   1908             Ma = ModuleAutoGen(
   1909                     self.Workspace,
   1910                     ModuleFile,
   1911                     self.BuildTarget,
   1912                     self.ToolChain,
   1913                     self.Arch,
   1914                     self.MetaFile
   1915                     )
   1916             if Ma not in self._ModuleAutoGenList:
   1917                 self._ModuleAutoGenList.append(Ma)
   1918             for La in Ma.LibraryAutoGenList:
   1919                 if La not in self._LibraryAutoGenList:
   1920                     self._LibraryAutoGenList.append(La)
   1921                 if Ma not in La._ReferenceModules:
   1922                     La._ReferenceModules.append(Ma)
   1923 
   1924     ## Summarize ModuleAutoGen objects of all modules to be built for this platform

   1925     def _GetModuleAutoGenList(self):
   1926         if self._ModuleAutoGenList == None:
   1927             self._GetAutoGenObjectList()
   1928         return self._ModuleAutoGenList
   1929 
   1930     ## Summarize ModuleAutoGen objects of all libraries to be built for this platform

   1931     def _GetLibraryAutoGenList(self):
   1932         if self._LibraryAutoGenList == None:
   1933             self._GetAutoGenObjectList()
   1934         return self._LibraryAutoGenList
   1935 
   1936     ## Test if a module is supported by the platform

   1937     #

   1938     #  An error will be raised directly if the module or its arch is not supported

   1939     #  by the platform or current configuration

   1940     #

   1941     def ValidModule(self, Module):
   1942         return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances \
   1943             or Module in self._AsBuildModuleList
   1944 
   1945     ## Resolve the library classes in a module to library instances

   1946     #

   1947     # This method will not only resolve library classes but also sort the library

   1948     # instances according to the dependency-ship.

   1949     #

   1950     #   @param  Module      The module from which the library classes will be resolved

   1951     #

   1952     #   @retval library_list    List of library instances sorted

   1953     #

   1954     def ApplyLibraryInstance(self, Module):
   1955         # Cover the case that the binary INF file is list in the FDF file but not DSC file, return empty list directly

   1956         if str(Module) not in self.Platform.Modules:
   1957             return []
   1958 
   1959         ModuleType = Module.ModuleType
   1960 
   1961         # for overridding library instances with module specific setting

   1962         PlatformModule = self.Platform.Modules[str(Module)]
   1963 
   1964         # add forced library instances (specified under LibraryClasses sections)

   1965         #

   1966         # If a module has a MODULE_TYPE of USER_DEFINED,

   1967         # do not link in NULL library class instances from the global [LibraryClasses.*] sections.

   1968         #

   1969         if Module.ModuleType != SUP_MODULE_USER_DEFINED:
   1970             for LibraryClass in self.Platform.LibraryClasses.GetKeys():
   1971                 if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]:
   1972                     Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]
   1973 
   1974         # add forced library instances (specified in module overrides)

   1975         for LibraryClass in PlatformModule.LibraryClasses:
   1976             if LibraryClass.startswith("NULL"):
   1977                 Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
   1978 
   1979         # EdkII module

   1980         LibraryConsumerList = [Module]
   1981         Constructor         = []
   1982         ConsumedByList      = sdict()
   1983         LibraryInstance     = sdict()
   1984 
   1985         EdkLogger.verbose("")
   1986         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
   1987         while len(LibraryConsumerList) > 0:
   1988             M = LibraryConsumerList.pop()
   1989             for LibraryClassName in M.LibraryClasses:
   1990                 if LibraryClassName not in LibraryInstance:
   1991                     # override library instance for this module

   1992                     if LibraryClassName in PlatformModule.LibraryClasses:
   1993                         LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]
   1994                     else:
   1995                         LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
   1996                     if LibraryPath == None or LibraryPath == "":
   1997                         LibraryPath = M.LibraryClasses[LibraryClassName]
   1998                         if LibraryPath == None or LibraryPath == "":
   1999                             EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
   2000                                             "Instance of library class [%s] is not found" % LibraryClassName,
   2001                                             File=self.MetaFile,
   2002                                             ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))
   2003 
   2004                     LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain]
   2005                     # for those forced library instance (NULL library), add a fake library class

   2006                     if LibraryClassName.startswith("NULL"):
   2007                         LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
   2008                     elif LibraryModule.LibraryClass == None \
   2009                          or len(LibraryModule.LibraryClass) == 0 \
   2010                          or (ModuleType != 'USER_DEFINED'
   2011                              and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
   2012                         # only USER_DEFINED can link against any library instance despite of its SupModList

   2013                         EdkLogger.error("build", OPTION_MISSING,
   2014                                         "Module type [%s] is not supported by library instance [%s]" \
   2015                                         % (ModuleType, LibraryPath), File=self.MetaFile,
   2016                                         ExtraData="consumed by [%s]" % str(Module))
   2017 
   2018                     LibraryInstance[LibraryClassName] = LibraryModule
   2019                     LibraryConsumerList.append(LibraryModule)
   2020                     EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
   2021                 else:
   2022                     LibraryModule = LibraryInstance[LibraryClassName]
   2023 
   2024                 if LibraryModule == None:
   2025                     continue
   2026 
   2027                 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
   2028                     Constructor.append(LibraryModule)
   2029 
   2030                 if LibraryModule not in ConsumedByList:
   2031                     ConsumedByList[LibraryModule] = []
   2032                 # don't add current module itself to consumer list

   2033                 if M != Module:
   2034                     if M in ConsumedByList[LibraryModule]:
   2035                         continue
   2036                     ConsumedByList[LibraryModule].append(M)
   2037         #

   2038         # Initialize the sorted output list to the empty set

   2039         #

   2040         SortedLibraryList = []
   2041         #

   2042         # Q <- Set of all nodes with no incoming edges

   2043         #

   2044         LibraryList = [] #LibraryInstance.values()

   2045         Q = []
   2046         for LibraryClassName in LibraryInstance:
   2047             M = LibraryInstance[LibraryClassName]
   2048             LibraryList.append(M)
   2049             if ConsumedByList[M] == []:
   2050                 Q.append(M)
   2051 
   2052         #

   2053         # start the  DAG algorithm

   2054         #

   2055         while True:
   2056             EdgeRemoved = True
   2057             while Q == [] and EdgeRemoved:
   2058                 EdgeRemoved = False
   2059                 # for each node Item with a Constructor

   2060                 for Item in LibraryList:
   2061                     if Item not in Constructor:
   2062                         continue
   2063                     # for each Node without a constructor with an edge e from Item to Node

   2064                     for Node in ConsumedByList[Item]:
   2065                         if Node in Constructor:
   2066                             continue
   2067                         # remove edge e from the graph if Node has no constructor

   2068                         ConsumedByList[Item].remove(Node)
   2069                         EdgeRemoved = True
   2070                         if ConsumedByList[Item] == []:
   2071                             # insert Item into Q

   2072                             Q.insert(0, Item)
   2073                             break
   2074                     if Q != []:
   2075                         break
   2076             # DAG is done if there's no more incoming edge for all nodes

   2077             if Q == []:
   2078                 break
   2079 
   2080             # remove node from Q

   2081             Node = Q.pop()
   2082             # output Node

   2083             SortedLibraryList.append(Node)
   2084 
   2085             # for each node Item with an edge e from Node to Item do

   2086             for Item in LibraryList:
   2087                 if Node not in ConsumedByList[Item]:
   2088                     continue
   2089                 # remove edge e from the graph

   2090                 ConsumedByList[Item].remove(Node)
   2091 
   2092                 if ConsumedByList[Item] != []:
   2093                     continue
   2094                 # insert Item into Q, if Item has no other incoming edges

   2095                 Q.insert(0, Item)
   2096 
   2097         #

   2098         # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle

   2099         #

   2100         for Item in LibraryList:
   2101             if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
   2102                 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])
   2103                 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
   2104                                 ExtraData=ErrorMessage, File=self.MetaFile)
   2105             if Item not in SortedLibraryList:
   2106                 SortedLibraryList.append(Item)
   2107 
   2108         #

   2109         # Build the list of constructor and destructir names

   2110         # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order

   2111         #

   2112         SortedLibraryList.reverse()
   2113         return SortedLibraryList
   2114 
   2115 
   2116     ## Override PCD setting (type, value, ...)

   2117     #

   2118     #   @param  ToPcd       The PCD to be overrided

   2119     #   @param  FromPcd     The PCD overrideing from

   2120     #

   2121     def _OverridePcd(self, ToPcd, FromPcd, Module=""):
   2122         #

   2123         # in case there's PCDs coming from FDF file, which have no type given.

   2124         # at this point, ToPcd.Type has the type found from dependent

   2125         # package

   2126         #

   2127         TokenCName = ToPcd.TokenCName
   2128         for PcdItem in GlobalData.MixedPcd:
   2129             if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
   2130                 TokenCName = PcdItem[0]
   2131                 break
   2132         if FromPcd != None:
   2133             if GlobalData.BuildOptionPcd:
   2134                 for pcd in GlobalData.BuildOptionPcd:
   2135                     if (FromPcd.TokenSpaceGuidCName, FromPcd.TokenCName) == (pcd[0], pcd[1]):
   2136                         FromPcd.DefaultValue = pcd[2]
   2137                         break
   2138             if ToPcd.Pending and FromPcd.Type not in [None, '']:
   2139                 ToPcd.Type = FromPcd.Type
   2140             elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\
   2141                 and (ToPcd.Type != FromPcd.Type) and (ToPcd.Type in FromPcd.Type):
   2142                 if ToPcd.Type.strip() == "DynamicEx":
   2143                     ToPcd.Type = FromPcd.Type
   2144             elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \
   2145                 and ToPcd.Type != FromPcd.Type:
   2146                 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
   2147                                 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
   2148                                           % (ToPcd.TokenSpaceGuidCName, TokenCName,
   2149                                              ToPcd.Type, Module, FromPcd.Type),
   2150                                           File=self.MetaFile)
   2151 
   2152             if FromPcd.MaxDatumSize not in [None, '']:
   2153                 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
   2154             if FromPcd.DefaultValue not in [None, '']:
   2155                 ToPcd.DefaultValue = FromPcd.DefaultValue
   2156             if FromPcd.TokenValue not in [None, '']:
   2157                 ToPcd.TokenValue = FromPcd.TokenValue
   2158             if FromPcd.MaxDatumSize not in [None, '']:
   2159                 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
   2160             if FromPcd.DatumType not in [None, '']:
   2161                 ToPcd.DatumType = FromPcd.DatumType
   2162             if FromPcd.SkuInfoList not in [None, '', []]:
   2163                 ToPcd.SkuInfoList = FromPcd.SkuInfoList
   2164 
   2165             # check the validation of datum

   2166             IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
   2167             if not IsValid:
   2168                 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
   2169                                 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, TokenCName))
   2170             ToPcd.validateranges = FromPcd.validateranges
   2171             ToPcd.validlists = FromPcd.validlists
   2172             ToPcd.expressions = FromPcd.expressions
   2173 
   2174         if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
   2175             EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
   2176                             % (ToPcd.TokenSpaceGuidCName, TokenCName))
   2177             Value = ToPcd.DefaultValue
   2178             if Value in [None, '']:
   2179                 ToPcd.MaxDatumSize = '1'
   2180             elif Value[0] == 'L':
   2181                 ToPcd.MaxDatumSize = str((len(Value) - 2) * 2)
   2182             elif Value[0] == '{':
   2183                 ToPcd.MaxDatumSize = str(len(Value.split(',')))
   2184             else:
   2185                 ToPcd.MaxDatumSize = str(len(Value) - 1)
   2186 
   2187         # apply default SKU for dynamic PCDS if specified one is not available

   2188         if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \
   2189             and ToPcd.SkuInfoList in [None, {}, '']:
   2190             if self.Platform.SkuName in self.Platform.SkuIds:
   2191                 SkuName = self.Platform.SkuName
   2192             else:
   2193                 SkuName = 'DEFAULT'
   2194             ToPcd.SkuInfoList = {
   2195                 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)
   2196             }
   2197 
   2198     ## Apply PCD setting defined platform to a module

   2199     #

   2200     #   @param  Module  The module from which the PCD setting will be overrided

   2201     #

   2202     #   @retval PCD_list    The list PCDs with settings from platform

   2203     #

   2204     def ApplyPcdSetting(self, Module, Pcds):
   2205         # for each PCD in module

   2206         for Name, Guid in Pcds:
   2207             PcdInModule = Pcds[Name, Guid]
   2208             # find out the PCD setting in platform

   2209             if (Name, Guid) in self.Platform.Pcds:
   2210                 PcdInPlatform = self.Platform.Pcds[Name, Guid]
   2211             else:
   2212                 PcdInPlatform = None
   2213             # then override the settings if any

   2214             self._OverridePcd(PcdInModule, PcdInPlatform, Module)
   2215             # resolve the VariableGuid value

   2216             for SkuId in PcdInModule.SkuInfoList:
   2217                 Sku = PcdInModule.SkuInfoList[SkuId]
   2218                 if Sku.VariableGuid == '': continue
   2219                 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path)
   2220                 if Sku.VariableGuidValue == None:
   2221                     PackageList = "\n\t".join([str(P) for P in self.PackageList])
   2222                     EdkLogger.error(
   2223                                 'build',
   2224                                 RESOURCE_NOT_AVAILABLE,
   2225                                 "Value of GUID [%s] is not found in" % Sku.VariableGuid,
   2226                                 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
   2227                                                         % (Guid, Name, str(Module)),
   2228                                 File=self.MetaFile
   2229                                 )
   2230 
   2231         # override PCD settings with module specific setting

   2232         if Module in self.Platform.Modules:
   2233             PlatformModule = self.Platform.Modules[str(Module)]
   2234             for Key  in PlatformModule.Pcds:
   2235                 if Key in Pcds:
   2236                     self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)
   2237         return Pcds.values()
   2238 
   2239     ## Resolve library names to library modules

   2240     #

   2241     # (for Edk.x modules)

   2242     #

   2243     #   @param  Module  The module from which the library names will be resolved

   2244     #

   2245     #   @retval library_list    The list of library modules

   2246     #

   2247     def ResolveLibraryReference(self, Module):
   2248         EdkLogger.verbose("")
   2249         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
   2250         LibraryConsumerList = [Module]
   2251 
   2252         # "CompilerStub" is a must for Edk modules

   2253         if Module.Libraries:
   2254             Module.Libraries.append("CompilerStub")
   2255         LibraryList = []
   2256         while len(LibraryConsumerList) > 0:
   2257             M = LibraryConsumerList.pop()
   2258             for LibraryName in M.Libraries:
   2259                 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']
   2260                 if Library == None:
   2261                     for Key in self.Platform.LibraryClasses.data.keys():
   2262                         if LibraryName.upper() == Key.upper():
   2263                             Library = self.Platform.LibraryClasses[Key, ':dummy:']
   2264                             break
   2265                     if Library == None:
   2266                         EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),
   2267                             ExtraData="\t%s [%s]" % (str(Module), self.Arch))
   2268                         continue
   2269 
   2270                 if Library not in LibraryList:
   2271                     LibraryList.append(Library)
   2272                     LibraryConsumerList.append(Library)
   2273                     EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))
   2274         return LibraryList
   2275 
   2276     ## Calculate the priority value of the build option

   2277     #

   2278     # @param    Key    Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE

   2279     #

   2280     # @retval   Value  Priority value based on the priority list.

   2281     #

   2282     def CalculatePriorityValue(self, Key):
   2283         Target, ToolChain, Arch, CommandType, Attr = Key.split('_')
   2284         PriorityValue = 0x11111
   2285         if Target == "*":
   2286             PriorityValue &= 0x01111
   2287         if ToolChain == "*":
   2288             PriorityValue &= 0x10111
   2289         if Arch == "*":
   2290             PriorityValue &= 0x11011
   2291         if CommandType == "*":
   2292             PriorityValue &= 0x11101
   2293         if Attr == "*":
   2294             PriorityValue &= 0x11110
   2295 
   2296         return self.PrioList["0x%0.5x" % PriorityValue]
   2297 
   2298 
   2299     ## Expand * in build option key

   2300     #

   2301     #   @param  Options     Options to be expanded

   2302     #

   2303     #   @retval options     Options expanded

   2304     #      

   2305     def _ExpandBuildOption(self, Options, ModuleStyle=None):
   2306         BuildOptions = {}
   2307         FamilyMatch  = False
   2308         FamilyIsNull = True
   2309 
   2310         OverrideList = {}
   2311         #

   2312         # Construct a list contain the build options which need override.

   2313         #

   2314         for Key in Options:
   2315             #

   2316             # Key[0] -- tool family

   2317             # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE

   2318             #

   2319             if (Key[0] == self.BuildRuleFamily and
   2320                 (ModuleStyle == None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):
   2321                 Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_')
   2322                 if Target == self.BuildTarget or Target == "*":
   2323                     if ToolChain == self.ToolChain or ToolChain == "*":
   2324                         if Arch == self.Arch or Arch == "*":
   2325                             if Options[Key].startswith("="):
   2326                                 if OverrideList.get(Key[1]) != None:
   2327                                     OverrideList.pop(Key[1])
   2328                                 OverrideList[Key[1]] = Options[Key]
   2329         
   2330         #

   2331         # Use the highest priority value. 

   2332         #

   2333         if (len(OverrideList) >= 2):
   2334             KeyList = OverrideList.keys()
   2335             for Index in range(len(KeyList)):
   2336                 NowKey = KeyList[Index]
   2337                 Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_")
   2338                 for Index1 in range(len(KeyList) - Index - 1):
   2339                     NextKey = KeyList[Index1 + Index + 1]
   2340                     #

   2341                     # Compare two Key, if one is included by another, choose the higher priority one

   2342                     #                    

   2343                     Target2, ToolChain2, Arch2, CommandType2, Attr2 = NextKey.split("_")
   2344                     if Target1 == Target2 or Target1 == "*" or Target2 == "*":
   2345                         if ToolChain1 == ToolChain2 or ToolChain1 == "*" or ToolChain2 == "*":
   2346                             if Arch1 == Arch2 or Arch1 == "*" or Arch2 == "*":
   2347                                 if CommandType1 == CommandType2 or CommandType1 == "*" or CommandType2 == "*":
   2348                                     if Attr1 == Attr2 or Attr1 == "*" or Attr2 == "*":
   2349                                         if self.CalculatePriorityValue(NowKey) > self.CalculatePriorityValue(NextKey):
   2350                                             if Options.get((self.BuildRuleFamily, NextKey)) != None:
   2351                                                 Options.pop((self.BuildRuleFamily, NextKey))
   2352                                         else:
   2353                                             if Options.get((self.BuildRuleFamily, NowKey)) != None:
   2354                                                 Options.pop((self.BuildRuleFamily, NowKey))
   2355                                                            
   2356         for Key in Options:
   2357             if ModuleStyle != None and len (Key) > 2:
   2358                 # Check Module style is EDK or EDKII.

   2359                 # Only append build option for the matched style module.

   2360                 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
   2361                     continue
   2362                 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
   2363                     continue
   2364             Family = Key[0]
   2365             Target, Tag, Arch, Tool, Attr = Key[1].split("_")
   2366             # if tool chain family doesn't match, skip it

   2367             if Tool in self.ToolDefinition and Family != "":
   2368                 FamilyIsNull = False
   2369                 if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
   2370                     if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
   2371                         continue
   2372                 elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
   2373                     continue
   2374                 FamilyMatch = True
   2375             # expand any wildcard

   2376             if Target == "*" or Target == self.BuildTarget:
   2377                 if Tag == "*" or Tag == self.ToolChain:
   2378                     if Arch == "*" or Arch == self.Arch:
   2379                         if Tool not in BuildOptions:
   2380                             BuildOptions[Tool] = {}
   2381                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
   2382                             BuildOptions[Tool][Attr] = Options[Key]
   2383                         else:
   2384                             # append options for the same tool

   2385                             BuildOptions[Tool][Attr] += " " + Options[Key]
   2386         # Build Option Family has been checked, which need't to be checked again for family.

   2387         if FamilyMatch or FamilyIsNull:
   2388             return BuildOptions
   2389 
   2390         for Key in Options:
   2391             if ModuleStyle != None and len (Key) > 2:
   2392                 # Check Module style is EDK or EDKII.

   2393                 # Only append build option for the matched style module.

   2394                 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
   2395                     continue
   2396                 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
   2397                     continue
   2398             Family = Key[0]
   2399             Target, Tag, Arch, Tool, Attr = Key[1].split("_")
   2400             # if tool chain family doesn't match, skip it

   2401             if Tool not in self.ToolDefinition or Family == "":
   2402                 continue
   2403             # option has been added before

   2404             if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
   2405                 continue
   2406 
   2407             # expand any wildcard

   2408             if Target == "*" or Target == self.BuildTarget:
   2409                 if Tag == "*" or Tag == self.ToolChain:
   2410                     if Arch == "*" or Arch == self.Arch:
   2411                         if Tool not in BuildOptions:
   2412                             BuildOptions[Tool] = {}
   2413                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
   2414                             BuildOptions[Tool][Attr] = Options[Key]
   2415                         else:
   2416                             # append options for the same tool

   2417                             BuildOptions[Tool][Attr] += " " + Options[Key]
   2418         return BuildOptions
   2419 
   2420     ## Append build options in platform to a module

   2421     #

   2422     #   @param  Module  The module to which the build options will be appened

   2423     #

   2424     #   @retval options     The options appended with build options in platform

   2425     #

   2426     def ApplyBuildOption(self, Module):
   2427         # Get the different options for the different style module

   2428         if Module.AutoGenVersion < 0x00010005:
   2429             PlatformOptions = self.EdkBuildOption
   2430             ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDK_NAME, Module.ModuleType)
   2431         else:
   2432             PlatformOptions = self.EdkIIBuildOption
   2433             ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDKII_NAME, Module.ModuleType)
   2434         ModuleTypeOptions = self._ExpandBuildOption(ModuleTypeOptions)
   2435         ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)
   2436         if Module in self.Platform.Modules:
   2437             PlatformModule = self.Platform.Modules[str(Module)]
   2438             PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)
   2439         else:
   2440             PlatformModuleOptions = {}
   2441 
   2442         BuildRuleOrder = None
   2443         for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
   2444             for Tool in Options:
   2445                 for Attr in Options[Tool]:
   2446                     if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
   2447                         BuildRuleOrder = Options[Tool][Attr]
   2448 
   2449         AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() +
   2450                        PlatformModuleOptions.keys() + ModuleTypeOptions.keys() +
   2451                        self.ToolDefinition.keys())
   2452         BuildOptions = {}
   2453         for Tool in AllTools:
   2454             if Tool not in BuildOptions:
   2455                 BuildOptions[Tool] = {}
   2456 
   2457             for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
   2458                 if Tool not in Options:
   2459                     continue
   2460                 for Attr in Options[Tool]:
   2461                     Value = Options[Tool][Attr]
   2462                     #

   2463                     # Do not generate it in Makefile

   2464                     #

   2465                     if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
   2466                         continue
   2467                     if Attr not in BuildOptions[Tool]:
   2468                         BuildOptions[Tool][Attr] = ""
   2469                     # check if override is indicated

   2470                     if Value.startswith('='):
   2471                         ToolPath = Value[1:]
   2472                         ToolPath = mws.handleWsMacro(ToolPath)
   2473                         BuildOptions[Tool][Attr] = ToolPath
   2474                     else:
   2475                         Value = mws.handleWsMacro(Value)
   2476                         BuildOptions[Tool][Attr] += " " + Value
   2477         if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None:
   2478             #

   2479             # Override UNI flag only for EDK module.

   2480             #

   2481             if 'BUILD' not in BuildOptions:
   2482                 BuildOptions['BUILD'] = {}
   2483             BuildOptions['BUILD']['FLAGS'] = self.Workspace.UniFlag
   2484         return BuildOptions, BuildRuleOrder
   2485 
   2486     Platform            = property(_GetPlatform)
   2487     Name                = property(_GetName)
   2488     Guid                = property(_GetGuid)
   2489     Version             = property(_GetVersion)
   2490 
   2491     OutputDir           = property(_GetOutputDir)
   2492     BuildDir            = property(_GetBuildDir)
   2493     MakeFileDir         = property(_GetMakeFileDir)
   2494     FdfFile             = property(_GetFdfFile)
   2495 
   2496     PcdTokenNumber      = property(_GetPcdTokenNumbers)    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber

   2497     DynamicPcdList      = property(_GetDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]

   2498     NonDynamicPcdList   = property(_GetNonDynamicPcdList)    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]

   2499     NonDynamicPcdDict   = property(_GetNonDynamicPcdDict)
   2500     PackageList         = property(_GetPackageList)
   2501 
   2502     ToolDefinition      = property(_GetToolDefinition)    # toolcode : tool path

   2503     ToolDefinitionFile  = property(_GetToolDefFile)    # toolcode : lib path

   2504     ToolChainFamily     = property(_GetToolChainFamily)
   2505     BuildRuleFamily     = property(_GetBuildRuleFamily)
   2506     BuildOption         = property(_GetBuildOptions)    # toolcode : option

   2507     EdkBuildOption      = property(_GetEdkBuildOptions)   # edktoolcode : option

   2508     EdkIIBuildOption    = property(_GetEdkIIBuildOptions) # edkiitoolcode : option

   2509 
   2510     BuildCommand        = property(_GetBuildCommand)
   2511     BuildRule           = property(_GetBuildRule)
   2512     ModuleAutoGenList   = property(_GetModuleAutoGenList)
   2513     LibraryAutoGenList  = property(_GetLibraryAutoGenList)
   2514     GenFdsCommand       = property(_GenFdsCommand)
   2515 
   2516 ## ModuleAutoGen class

   2517 #

   2518 # This class encapsules the AutoGen behaviors for the build tools. In addition to

   2519 # the generation of AutoGen.h and AutoGen.c, it will generate *.depex file according

   2520 # to the [depex] section in module's inf file.

   2521 #

   2522 class ModuleAutoGen(AutoGen):
   2523     ## The real constructor of ModuleAutoGen

   2524     #

   2525     #  This method is not supposed to be called by users of ModuleAutoGen. It's

   2526     #  only used by factory method __new__() to do real initialization work for an

   2527     #  object of ModuleAutoGen

   2528     #

   2529     #   @param      Workspace           EdkIIWorkspaceBuild object

   2530     #   @param      ModuleFile          The path of module file

   2531     #   @param      Target              Build target (DEBUG, RELEASE)

   2532     #   @param      Toolchain           Name of tool chain

   2533     #   @param      Arch                The arch the module supports

   2534     #   @param      PlatformFile        Platform meta-file

   2535     #

   2536     def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):
   2537         EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))
   2538         GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)
   2539 
   2540         self.Workspace = Workspace
   2541         self.WorkspaceDir = Workspace.WorkspaceDir
   2542 
   2543         self.MetaFile = ModuleFile
   2544         self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)
   2545         # check if this module is employed by active platform

   2546         if not self.PlatformInfo.ValidModule(self.MetaFile):
   2547             EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \
   2548                               % (self.MetaFile, Arch))
   2549             return False
   2550 
   2551         self.SourceDir = self.MetaFile.SubDir
   2552         self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir)
   2553 
   2554         self.SourceOverrideDir = None
   2555         # use overrided path defined in DSC file

   2556         if self.MetaFile.Key in GlobalData.gOverrideDir:
   2557             self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]
   2558 
   2559         self.ToolChain = Toolchain
   2560         self.BuildTarget = Target
   2561         self.Arch = Arch
   2562         self.ToolChainFamily = self.PlatformInfo.ToolChainFamily
   2563         self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily
   2564 
   2565         self.IsMakeFileCreated = False
   2566         self.IsCodeFileCreated = False
   2567         self.IsAsBuiltInfCreated = False
   2568         self.DepexGenerated = False
   2569 
   2570         self.BuildDatabase = self.Workspace.BuildDatabase
   2571         self.BuildRuleOrder = None
   2572 
   2573         self._Module          = None
   2574         self._Name            = None
   2575         self._Guid            = None
   2576         self._Version         = None
   2577         self._ModuleType      = None
   2578         self._ComponentType   = None
   2579         self._PcdIsDriver     = None
   2580         self._AutoGenVersion  = None
   2581         self._LibraryFlag     = None
   2582         self._CustomMakefile  = None
   2583         self._Macro           = None
   2584 
   2585         self._BuildDir        = None
   2586         self._OutputDir       = None
   2587         self._DebugDir        = None
   2588         self._MakeFileDir     = None
   2589 
   2590         self._IncludePathList = None
   2591         self._IncludePathLength = 0
   2592         self._AutoGenFileList = None
   2593         self._UnicodeFileList = None
   2594         self._IdfFileList = None
   2595         self._SourceFileList  = None
   2596         self._ObjectFileList  = None
   2597         self._BinaryFileList  = None
   2598 
   2599         self._DependentPackageList    = None
   2600         self._DependentLibraryList    = None
   2601         self._LibraryAutoGenList      = None
   2602         self._DerivedPackageList      = None
   2603         self._ModulePcdList           = None
   2604         self._LibraryPcdList          = None
   2605         self._PcdComments = sdict()
   2606         self._GuidList                = None
   2607         self._GuidsUsedByPcd = None
   2608         self._GuidComments = sdict()
   2609         self._ProtocolList            = None
   2610         self._ProtocolComments = sdict()
   2611         self._PpiList                 = None
   2612         self._PpiComments = sdict()
   2613         self._DepexList               = None
   2614         self._DepexExpressionList     = None
   2615         self._BuildOption             = None
   2616         self._BuildOptionIncPathList  = None
   2617         self._BuildTargets            = None
   2618         self._IntroBuildTargetList    = None
   2619         self._FinalBuildTargetList    = None
   2620         self._FileTypes               = None
   2621         self._BuildRules              = None
   2622         
   2623         ## The Modules referenced to this Library

   2624         #  Only Library has this attribute

   2625         self._ReferenceModules        = []        
   2626         
   2627         ## Store the FixedAtBuild Pcds

   2628         #  

   2629         self._FixedAtBuildPcds         = []
   2630         self.ConstPcd                  = {}
   2631         return True
   2632 
   2633     def __repr__(self):
   2634         return "%s [%s]" % (self.MetaFile, self.Arch)
   2635 
   2636     # Get FixedAtBuild Pcds of this Module

   2637     def _GetFixedAtBuildPcds(self):
   2638         if self._FixedAtBuildPcds:
   2639             return self._FixedAtBuildPcds
   2640         for Pcd in self.ModulePcdList:
   2641             if self.IsLibrary:
   2642                 if not (Pcd.Pending == False and Pcd.Type == "FixedAtBuild"):
   2643                     continue
   2644             elif Pcd.Type != "FixedAtBuild":
   2645                 continue
   2646             if Pcd not in self._FixedAtBuildPcds:
   2647                 self._FixedAtBuildPcds.append(Pcd)
   2648                 
   2649         return self._FixedAtBuildPcds        
   2650 
   2651     def _GetUniqueBaseName(self):
   2652         BaseName = self.Name
   2653         for Module in self.PlatformInfo.ModuleAutoGenList:
   2654             if Module.MetaFile == self.MetaFile:
   2655                 continue
   2656             if Module.Name == self.Name:
   2657                 if uuid.UUID(Module.Guid) == uuid.UUID(self.Guid):
   2658                     EdkLogger.error("build", FILE_DUPLICATED, 'Modules have same BaseName and FILE_GUID:\n'
   2659                                     '  %s\n  %s' % (Module.MetaFile, self.MetaFile))
   2660                 BaseName = '%s_%s' % (self.Name, self.Guid)
   2661         return BaseName
   2662 
   2663     # Macros could be used in build_rule.txt (also Makefile)

   2664     def _GetMacros(self):
   2665         if self._Macro == None:
   2666             self._Macro = sdict()
   2667             self._Macro["WORKSPACE"             ] = self.WorkspaceDir
   2668             self._Macro["MODULE_NAME"           ] = self.Name
   2669             self._Macro["MODULE_NAME_GUID"      ] = self._GetUniqueBaseName()
   2670             self._Macro["MODULE_GUID"           ] = self.Guid
   2671             self._Macro["MODULE_VERSION"        ] = self.Version
   2672             self._Macro["MODULE_TYPE"           ] = self.ModuleType
   2673             self._Macro["MODULE_FILE"           ] = str(self.MetaFile)
   2674             self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName
   2675             self._Macro["MODULE_RELATIVE_DIR"   ] = self.SourceDir
   2676             self._Macro["MODULE_DIR"            ] = self.SourceDir
   2677 
   2678             self._Macro["BASE_NAME"             ] = self.Name
   2679 
   2680             self._Macro["ARCH"                  ] = self.Arch
   2681             self._Macro["TOOLCHAIN"             ] = self.ToolChain
   2682             self._Macro["TOOLCHAIN_TAG"         ] = self.ToolChain
   2683             self._Macro["TOOL_CHAIN_TAG"        ] = self.ToolChain
   2684             self._Macro["TARGET"                ] = self.BuildTarget
   2685 
   2686             self._Macro["BUILD_DIR"             ] = self.PlatformInfo.BuildDir
   2687             self._Macro["BIN_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
   2688             self._Macro["LIB_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
   2689             self._Macro["MODULE_BUILD_DIR"      ] = self.BuildDir
   2690             self._Macro["OUTPUT_DIR"            ] = self.OutputDir
   2691             self._Macro["DEBUG_DIR"             ] = self.DebugDir
   2692             self._Macro["DEST_DIR_OUTPUT"       ] = self.OutputDir
   2693             self._Macro["DEST_DIR_DEBUG"        ] = self.DebugDir
   2694             self._Macro["PLATFORM_NAME"         ] = self.PlatformInfo.Name
   2695             self._Macro["PLATFORM_GUID"         ] = self.PlatformInfo.Guid
   2696             self._Macro["PLATFORM_VERSION"      ] = self.PlatformInfo.Version
   2697             self._Macro["PLATFORM_RELATIVE_DIR" ] = self.PlatformInfo.SourceDir
   2698             self._Macro["PLATFORM_DIR"          ] = mws.join(self.WorkspaceDir, self.PlatformInfo.SourceDir)
   2699             self._Macro["PLATFORM_OUTPUT_DIR"   ] = self.PlatformInfo.OutputDir
   2700         return self._Macro
   2701 
   2702     ## Return the module build data object

   2703     def _GetModule(self):
   2704         if self._Module == None:
   2705             self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
   2706         return self._Module
   2707 
   2708     ## Return the module name

   2709     def _GetBaseName(self):
   2710         return self.Module.BaseName
   2711 
   2712     ## Return the module DxsFile if exist

   2713     def _GetDxsFile(self):
   2714         return self.Module.DxsFile
   2715 
   2716     ## Return the module SourceOverridePath

   2717     def _GetSourceOverridePath(self):
   2718         return self.Module.SourceOverridePath
   2719 
   2720     ## Return the module meta-file GUID

   2721     def _GetGuid(self):
   2722         #

   2723         # To build same module more than once, the module path with FILE_GUID overridden has

   2724         # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path

   2725         # in DSC. The overridden GUID can be retrieved from file name

   2726         #

   2727         if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path):
   2728             #

   2729             # Length of GUID is 36

   2730             #

   2731             return os.path.basename(self.MetaFile.Path)[:36]
   2732         return self.Module.Guid
   2733 
   2734     ## Return the module version

   2735     def _GetVersion(self):
   2736         return self.Module.Version
   2737 
   2738     ## Return the module type

   2739     def _GetModuleType(self):
   2740         return self.Module.ModuleType
   2741 
   2742     ## Return the component type (for Edk.x style of module)

   2743     def _GetComponentType(self):
   2744         return self.Module.ComponentType
   2745 
   2746     ## Return the build type

   2747     def _GetBuildType(self):
   2748         return self.Module.BuildType
   2749 
   2750     ## Return the PCD_IS_DRIVER setting

   2751     def _GetPcdIsDriver(self):
   2752         return self.Module.PcdIsDriver
   2753 
   2754     ## Return the autogen version, i.e. module meta-file version

   2755     def _GetAutoGenVersion(self):
   2756         return self.Module.AutoGenVersion
   2757 
   2758     ## Check if the module is library or not

   2759     def _IsLibrary(self):
   2760         if self._LibraryFlag == None:
   2761             if self.Module.LibraryClass != None and self.Module.LibraryClass != []:
   2762                 self._LibraryFlag = True
   2763             else:
   2764                 self._LibraryFlag = False
   2765         return self._LibraryFlag
   2766 
   2767     ## Check if the module is binary module or not

   2768     def _IsBinaryModule(self):
   2769         return self.Module.IsBinaryModule
   2770 
   2771     ## Return the directory to store intermediate files of the module

   2772     def _GetBuildDir(self):
   2773         if self._BuildDir == None:
   2774             self._BuildDir = path.join(
   2775                                     self.PlatformInfo.BuildDir,
   2776                                     self.Arch,
   2777                                     self.SourceDir,
   2778                                     self.MetaFile.BaseName
   2779                                     )
   2780             CreateDirectory(self._BuildDir)
   2781         return self._BuildDir
   2782 
   2783     ## Return the directory to store the intermediate object files of the mdoule

   2784     def _GetOutputDir(self):
   2785         if self._OutputDir == None:
   2786             self._OutputDir = path.join(self.BuildDir, "OUTPUT")
   2787             CreateDirectory(self._OutputDir)
   2788         return self._OutputDir
   2789 
   2790     ## Return the directory to store auto-gened source files of the mdoule

   2791     def _GetDebugDir(self):
   2792         if self._DebugDir == None:
   2793             self._DebugDir = path.join(self.BuildDir, "DEBUG")
   2794             CreateDirectory(self._DebugDir)
   2795         return self._DebugDir
   2796 
   2797     ## Return the path of custom file

   2798     def _GetCustomMakefile(self):
   2799         if self._CustomMakefile == None:
   2800             self._CustomMakefile = {}
   2801             for Type in self.Module.CustomMakefile:
   2802                 if Type in gMakeTypeMap:
   2803                     MakeType = gMakeTypeMap[Type]
   2804                 else:
   2805                     MakeType = 'nmake'
   2806                 if self.SourceOverrideDir != None:
   2807                     File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])
   2808                     if not os.path.exists(File):
   2809                         File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
   2810                 else:
   2811                     File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
   2812                 self._CustomMakefile[MakeType] = File
   2813         return self._CustomMakefile
   2814 
   2815     ## Return the directory of the makefile

   2816     #

   2817     #   @retval     string  The directory string of module's makefile

   2818     #

   2819     def _GetMakeFileDir(self):
   2820         return self.BuildDir
   2821 
   2822     ## Return build command string

   2823     #

   2824     #   @retval     string  Build command string

   2825     #

   2826     def _GetBuildCommand(self):
   2827         return self.PlatformInfo.BuildCommand
   2828 
   2829     ## Get object list of all packages the module and its dependent libraries belong to

   2830     #

   2831     #   @retval     list    The list of package object

   2832     #

   2833     def _GetDerivedPackageList(self):
   2834         PackageList = []
   2835         for M in [self.Module] + self.DependentLibraryList:
   2836             for Package in M.Packages:
   2837                 if Package in PackageList:
   2838                     continue
   2839                 PackageList.append(Package)
   2840         return PackageList
   2841     
   2842     ## Get the depex string

   2843     #

   2844     # @return : a string contain all depex expresion.

   2845     def _GetDepexExpresionString(self):
   2846         DepexStr = ''
   2847         DepexList = []
   2848         ## DPX_SOURCE IN Define section.

   2849         if self.Module.DxsFile:
   2850             return DepexStr
   2851         for M in [self.Module] + self.DependentLibraryList:
   2852             Filename = M.MetaFile.Path
   2853             InfObj = InfSectionParser.InfSectionParser(Filename)
   2854             DepexExpresionList = InfObj.GetDepexExpresionList()
   2855             for DepexExpresion in DepexExpresionList:
   2856                 for key in DepexExpresion.keys():
   2857                     Arch, ModuleType = key
   2858                     DepexExpr = [x for x in DepexExpresion[key] if not str(x).startswith('#')]
   2859                     # the type of build module is USER_DEFINED.

   2860                     # All different DEPEX section tags would be copied into the As Built INF file

   2861                     # and there would be separate DEPEX section tags

   2862                     if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:
   2863                         if (Arch.upper() == self.Arch.upper()) and (ModuleType.upper() != TAB_ARCH_COMMON):
   2864                             DepexList.append({(Arch, ModuleType): DepexExpr})
   2865                     else:
   2866                         if Arch.upper() == TAB_ARCH_COMMON or \
   2867                           (Arch.upper() == self.Arch.upper() and \
   2868                           ModuleType.upper() in [TAB_ARCH_COMMON, self.ModuleType.upper()]):
   2869                             DepexList.append({(Arch, ModuleType): DepexExpr})
   2870         
   2871         #the type of build module is USER_DEFINED.

   2872         if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:
   2873             for Depex in DepexList:
   2874                 for key in Depex.keys():
   2875                     DepexStr += '[Depex.%s.%s]\n' % key
   2876                     DepexStr += '\n'.join(['# '+ val for val in Depex[key]])
   2877                     DepexStr += '\n\n'
   2878             if not DepexStr:
   2879                 return '[Depex.%s]\n' % self.Arch
   2880             return DepexStr
   2881         
   2882         #the type of build module not is USER_DEFINED.

   2883         Count = 0
   2884         for Depex in DepexList:
   2885             Count += 1
   2886             if DepexStr != '':
   2887                 DepexStr += ' AND '
   2888             DepexStr += '('
   2889             for D in Depex.values():
   2890                 DepexStr += ' '.join([val for val in D])
   2891             Index = DepexStr.find('END')
   2892             if Index > -1 and Index == len(DepexStr) - 3:
   2893                 DepexStr = DepexStr[:-3]
   2894             DepexStr = DepexStr.strip()
   2895             DepexStr += ')'
   2896         if Count == 1:
   2897             DepexStr = DepexStr.lstrip('(').rstrip(')').strip()
   2898         if not DepexStr:
   2899             return '[Depex.%s]\n' % self.Arch
   2900         return '[Depex.%s]\n#  ' % self.Arch + DepexStr
   2901     
   2902     ## Merge dependency expression

   2903     #

   2904     #   @retval     list    The token list of the dependency expression after parsed

   2905     #

   2906     def _GetDepexTokenList(self):
   2907         if self._DepexList == None:
   2908             self._DepexList = {}
   2909             if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
   2910                 return self._DepexList
   2911 
   2912             self._DepexList[self.ModuleType] = []
   2913 
   2914             for ModuleType in self._DepexList:
   2915                 DepexList = self._DepexList[ModuleType]
   2916                 #

   2917                 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion

   2918                 #

   2919                 for M in [self.Module] + self.DependentLibraryList:
   2920                     Inherited = False
   2921                     for D in M.Depex[self.Arch, ModuleType]:
   2922                         if DepexList != []:
   2923                             DepexList.append('AND')
   2924                         DepexList.append('(')
   2925                         DepexList.extend(D)
   2926                         if DepexList[-1] == 'END':  # no need of a END at this time

   2927                             DepexList.pop()
   2928                         DepexList.append(')')
   2929                         Inherited = True
   2930                     if Inherited:
   2931                         EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))
   2932                     if 'BEFORE' in DepexList or 'AFTER' in DepexList:
   2933                         break
   2934                 if len(DepexList) > 0:
   2935                     EdkLogger.verbose('')
   2936         return self._DepexList
   2937 
   2938     ## Merge dependency expression

   2939     #

   2940     #   @retval     list    The token list of the dependency expression after parsed

   2941     #

   2942     def _GetDepexExpressionTokenList(self):
   2943         if self._DepexExpressionList == None:
   2944             self._DepexExpressionList = {}
   2945             if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
   2946                 return self._DepexExpressionList
   2947 
   2948             self._DepexExpressionList[self.ModuleType] = ''
   2949 
   2950             for ModuleType in self._DepexExpressionList:
   2951                 DepexExpressionList = self._DepexExpressionList[ModuleType]
   2952                 #

   2953                 # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion

   2954                 #

   2955                 for M in [self.Module] + self.DependentLibraryList:
   2956                     Inherited = False
   2957                     for D in M.DepexExpression[self.Arch, ModuleType]:
   2958                         if DepexExpressionList != '':
   2959                             DepexExpressionList += ' AND '
   2960                         DepexExpressionList += '('
   2961                         DepexExpressionList += D
   2962                         DepexExpressionList = DepexExpressionList.rstrip('END').strip()
   2963                         DepexExpressionList += ')'
   2964                         Inherited = True
   2965                     if Inherited:
   2966                         EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))
   2967                     if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:
   2968                         break
   2969                 if len(DepexExpressionList) > 0:
   2970                     EdkLogger.verbose('')
   2971                 self._DepexExpressionList[ModuleType] = DepexExpressionList
   2972         return self._DepexExpressionList
   2973 
   2974     ## Return the list of specification version required for the module

   2975     #

   2976     #   @retval     list    The list of specification defined in module file

   2977     #

   2978     def _GetSpecification(self):
   2979         return self.Module.Specification
   2980 
   2981     ## Tool option for the module build

   2982     #

   2983     #   @param      PlatformInfo    The object of PlatformBuildInfo

   2984     #   @retval     dict            The dict containing valid options

   2985     #

   2986     def _GetModuleBuildOption(self):
   2987         if self._BuildOption == None:
   2988             self._BuildOption, self.BuildRuleOrder = self.PlatformInfo.ApplyBuildOption(self.Module)
   2989             if self.BuildRuleOrder:
   2990                 self.BuildRuleOrder = ['.%s' % Ext for Ext in self.BuildRuleOrder.split()]
   2991         return self._BuildOption
   2992 
   2993     ## Get include path list from tool option for the module build

   2994     #

   2995     #   @retval     list            The include path list

   2996     #

   2997     def _GetBuildOptionIncPathList(self):
   2998         if self._BuildOptionIncPathList == None:
   2999             #

   3000             # Regular expression for finding Include Directories, the difference between MSFT and INTEL/GCC/RVCT

   3001             # is the former use /I , the Latter used -I to specify include directories

   3002             #

   3003             if self.PlatformInfo.ToolChainFamily in ('MSFT'):
   3004                 gBuildOptIncludePattern = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)
   3005             elif self.PlatformInfo.ToolChainFamily in ('INTEL', 'GCC', 'RVCT'):
   3006                 gBuildOptIncludePattern = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)
   3007             else:
   3008                 #

   3009                 # New ToolChainFamily, don't known whether there is option to specify include directories

   3010                 #

   3011                 self._BuildOptionIncPathList = []
   3012                 return self._BuildOptionIncPathList
   3013             
   3014             BuildOptionIncPathList = []
   3015             for Tool in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):
   3016                 Attr = 'FLAGS'
   3017                 try:
   3018                     FlagOption = self.BuildOption[Tool][Attr]
   3019                 except KeyError:
   3020                     FlagOption = ''
   3021                 
   3022                 if self.PlatformInfo.ToolChainFamily != 'RVCT':
   3023                     IncPathList = [NormPath(Path, self.Macros) for Path in gBuildOptIncludePattern.findall(FlagOption)]
   3024                 else:
   3025                     #

   3026                     # RVCT may specify a list of directory seperated by commas

   3027                     #

   3028                     IncPathList = []
   3029                     for Path in gBuildOptIncludePattern.findall(FlagOption):
   3030                         PathList = GetSplitList(Path, TAB_COMMA_SPLIT)
   3031                         IncPathList += [NormPath(PathEntry, self.Macros) for PathEntry in PathList]
   3032 
   3033                 #

   3034                 # EDK II modules must not reference header files outside of the packages they depend on or 

   3035                 # within the module's directory tree. Report error if violation.

   3036                 #

   3037                 if self.AutoGenVersion >= 0x00010005 and len(IncPathList) > 0:
   3038                     for Path in IncPathList:
   3039                         if (Path not in self.IncludePathList) and (CommonPath([Path, self.MetaFile.Dir]) != self.MetaFile.Dir):
   3040                             ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path, Tool, FlagOption)
   3041                             EdkLogger.error("build",
   3042                                             PARAMETER_INVALID,
   3043                                             ExtraData=ErrMsg,
   3044                                             File=str(self.MetaFile))
   3045 
   3046                 
   3047                 BuildOptionIncPathList += IncPathList
   3048             
   3049             self._BuildOptionIncPathList = BuildOptionIncPathList
   3050         
   3051         return self._BuildOptionIncPathList
   3052         
   3053     ## Return a list of files which can be built from source

   3054     #

   3055     #  What kind of files can be built is determined by build rules in

   3056     #  $(CONF_DIRECTORY)/build_rule.txt and toolchain family.

   3057     #

   3058     def _GetSourceFileList(self):
   3059         if self._SourceFileList == None:
   3060             self._SourceFileList = []
   3061             for F in self.Module.Sources:
   3062                 # match tool chain

   3063                 if F.TagName not in ("", "*", self.ToolChain):
   3064                     EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "
   3065                                     "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))
   3066                     continue
   3067                 # match tool chain family

   3068                 if F.ToolChainFamily not in ("", "*", self.ToolChainFamily):
   3069                     EdkLogger.debug(
   3070                                 EdkLogger.DEBUG_0,
   3071                                 "The file [%s] must be built by tools of [%s], " \
   3072                                 "but current toolchain family is [%s]" \
   3073                                     % (str(F), F.ToolChainFamily, self.ToolChainFamily))
   3074                     continue
   3075 
   3076                 # add the file path into search path list for file including

   3077                 if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:
   3078                     self.IncludePathList.insert(0, F.Dir)
   3079                 self._SourceFileList.append(F)
   3080 
   3081             self._MatchBuildRuleOrder(self._SourceFileList)
   3082 
   3083             for F in self._SourceFileList:
   3084                 self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)
   3085         return self._SourceFileList
   3086 
   3087     def _MatchBuildRuleOrder(self, FileList):
   3088         Order_Dict = {}
   3089         self._GetModuleBuildOption()
   3090         for SingleFile in FileList:
   3091             if self.BuildRuleOrder and SingleFile.Ext in self.BuildRuleOrder and SingleFile.Ext in self.BuildRules:
   3092                 key = SingleFile.Path.split(SingleFile.Ext)[0]
   3093                 if key in Order_Dict:
   3094                     Order_Dict[key].append(SingleFile.Ext)
   3095                 else:
   3096                     Order_Dict[key] = [SingleFile.Ext]
   3097 
   3098         RemoveList = []
   3099         for F in Order_Dict:
   3100             if len(Order_Dict[F]) > 1:
   3101                 Order_Dict[F].sort(key=lambda i: self.BuildRuleOrder.index(i))
   3102                 for Ext in Order_Dict[F][1:]:
   3103                     RemoveList.append(F + Ext)
   3104                    
   3105         for item in RemoveList:
   3106             FileList.remove(item)
   3107 
   3108         return FileList
   3109 
   3110     ## Return the list of unicode files

   3111     def _GetUnicodeFileList(self):
   3112         if self._UnicodeFileList == None:
   3113             if TAB_UNICODE_FILE in self.FileTypes:
   3114                 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]
   3115             else:
   3116                 self._UnicodeFileList = []
   3117         return self._UnicodeFileList
   3118 
   3119     ## Return the list of Image Definition files

   3120     def _GetIdfFileList(self):
   3121         if self._IdfFileList == None:
   3122             if TAB_IMAGE_FILE in self.FileTypes:
   3123                 self._IdfFileList = self.FileTypes[TAB_IMAGE_FILE]
   3124             else:
   3125                 self._IdfFileList = []
   3126         return self._IdfFileList
   3127 
   3128     ## Return a list of files which can be built from binary

   3129     #

   3130     #  "Build" binary files are just to copy them to build directory.

   3131     #

   3132     #   @retval     list            The list of files which can be built later

   3133     #

   3134     def _GetBinaryFiles(self):
   3135         if self._BinaryFileList == None:
   3136             self._BinaryFileList = []
   3137             for F in self.Module.Binaries:
   3138                 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:
   3139                     continue
   3140                 self._BinaryFileList.append(F)
   3141                 self._ApplyBuildRule(F, F.Type)
   3142         return self._BinaryFileList
   3143 
   3144     def _GetBuildRules(self):
   3145         if self._BuildRules == None:
   3146             BuildRules = {}
   3147             BuildRuleDatabase = self.PlatformInfo.BuildRule
   3148             for Type in BuildRuleDatabase.FileTypeList:
   3149                 #first try getting build rule by BuildRuleFamily

   3150                 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]
   3151                 if not RuleObject:
   3152                     # build type is always module type, but ...

   3153                     if self.ModuleType != self.BuildType:
   3154                         RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.BuildRuleFamily]
   3155                 #second try getting build rule by ToolChainFamily

   3156                 if not RuleObject:
   3157                     RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]
   3158                     if not RuleObject:
   3159                         # build type is always module type, but ...

   3160                         if self.ModuleType != self.BuildType:
   3161                             RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]
   3162                 if not RuleObject:
   3163                     continue
   3164                 RuleObject = RuleObject.Instantiate(self.Macros)
   3165                 BuildRules[Type] = RuleObject
   3166                 for Ext in RuleObject.SourceFileExtList:
   3167                     BuildRules[Ext] = RuleObject
   3168             self._BuildRules = BuildRules
   3169         return self._BuildRules
   3170 
   3171     def _ApplyBuildRule(self, File, FileType):
   3172         if self._BuildTargets == None:
   3173             self._IntroBuildTargetList = set()
   3174             self._FinalBuildTargetList = set()
   3175             self._BuildTargets = {}
   3176             self._FileTypes = {}
   3177 
   3178         SubDirectory = os.path.join(self.OutputDir, File.SubDir)
   3179         if not os.path.exists(SubDirectory):
   3180             CreateDirectory(SubDirectory)
   3181         LastTarget = None
   3182         RuleChain = []
   3183         SourceList = [File]
   3184         Index = 0
   3185         #

   3186         # Make sure to get build rule order value

   3187         #

   3188         self._GetModuleBuildOption()
   3189 
   3190         while Index < len(SourceList):
   3191             Source = SourceList[Index]
   3192             Index = Index + 1
   3193 
   3194             if Source != File:
   3195                 CreateDirectory(Source.Dir)
   3196 
   3197             if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:
   3198                 # Skip all files that are not binary libraries

   3199                 if not self.IsLibrary:
   3200                     continue
   3201                 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
   3202             elif FileType in self.BuildRules:
   3203                 RuleObject = self.BuildRules[FileType]
   3204             elif Source.Ext in self.BuildRules:
   3205                 RuleObject = self.BuildRules[Source.Ext]
   3206             else:
   3207                 # stop at no more rules

   3208                 if LastTarget:
   3209                     self._FinalBuildTargetList.add(LastTarget)
   3210                 break
   3211 
   3212             FileType = RuleObject.SourceFileType
   3213             if FileType not in self._FileTypes:
   3214                 self._FileTypes[FileType] = set()
   3215             self._FileTypes[FileType].add(Source)
   3216 
   3217             # stop at STATIC_LIBRARY for library

   3218             if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:
   3219                 if LastTarget:
   3220                     self._FinalBuildTargetList.add(LastTarget)
   3221                 break
   3222 
   3223             Target = RuleObject.Apply(Source, self.BuildRuleOrder)
   3224             if not Target:
   3225                 if LastTarget:
   3226                     self._FinalBuildTargetList.add(LastTarget)
   3227                 break
   3228             elif not Target.Outputs:
   3229                 # Only do build for target with outputs

   3230                 self._FinalBuildTargetList.add(Target)
   3231 
   3232             if FileType not in self._BuildTargets:
   3233                 self._BuildTargets[FileType] = set()
   3234             self._BuildTargets[FileType].add(Target)
   3235 
   3236             if not Source.IsBinary and Source == File:
   3237                 self._IntroBuildTargetList.add(Target)
   3238 
   3239             # to avoid cyclic rule

   3240             if FileType in RuleChain:
   3241                 break
   3242 
   3243             RuleChain.append(FileType)
   3244             SourceList.extend(Target.Outputs)
   3245             LastTarget = Target
   3246             FileType = TAB_UNKNOWN_FILE
   3247 
   3248     def _GetTargets(self):
   3249         if self._BuildTargets == None:
   3250             self._IntroBuildTargetList = set()
   3251             self._FinalBuildTargetList = set()
   3252             self._BuildTargets = {}
   3253             self._FileTypes = {}
   3254 
   3255         #TRICK: call _GetSourceFileList to apply build rule for source files

   3256         if self.SourceFileList:
   3257             pass
   3258 
   3259         #TRICK: call _GetBinaryFileList to apply build rule for binary files

   3260         if self.BinaryFileList:
   3261             pass
   3262 
   3263         return self._BuildTargets
   3264 
   3265     def _GetIntroTargetList(self):
   3266         self._GetTargets()
   3267         return self._IntroBuildTargetList
   3268 
   3269     def _GetFinalTargetList(self):
   3270         self._GetTargets()
   3271         return self._FinalBuildTargetList
   3272 
   3273     def _GetFileTypes(self):
   3274         self._GetTargets()
   3275         return self._FileTypes
   3276 
   3277     ## Get the list of package object the module depends on

   3278     #

   3279     #   @retval     list    The package object list

   3280     #

   3281     def _GetDependentPackageList(self):
   3282         return self.Module.Packages
   3283 
   3284     ## Return the list of auto-generated code file

   3285     #

   3286     #   @retval     list        The list of auto-generated file

   3287     #

   3288     def _GetAutoGenFileList(self):
   3289         UniStringAutoGenC = True
   3290         IdfStringAutoGenC = True
   3291         UniStringBinBuffer = StringIO()
   3292         IdfGenBinBuffer = StringIO()
   3293         if self.BuildType == 'UEFI_HII':
   3294             UniStringAutoGenC = False
   3295             IdfStringAutoGenC = False
   3296         if self._AutoGenFileList == None:
   3297             self._AutoGenFileList = {}
   3298             AutoGenC = TemplateString()
   3299             AutoGenH = TemplateString()
   3300             StringH = TemplateString()
   3301             StringIdf = TemplateString()
   3302             GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer, StringIdf, IdfStringAutoGenC, IdfGenBinBuffer)
   3303             #

   3304             # AutoGen.c is generated if there are library classes in inf, or there are object files

   3305             #

   3306             if str(AutoGenC) != "" and (len(self.Module.LibraryClasses) > 0
   3307                                         or TAB_OBJECT_FILE in self.FileTypes):
   3308                 AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)
   3309                 self._AutoGenFileList[AutoFile] = str(AutoGenC)
   3310                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   3311             if str(AutoGenH) != "":
   3312                 AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)
   3313                 self._AutoGenFileList[AutoFile] = str(AutoGenH)
   3314                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   3315             if str(StringH) != "":
   3316                 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)
   3317                 self._AutoGenFileList[AutoFile] = str(StringH)
   3318                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   3319             if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":
   3320                 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)
   3321                 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()
   3322                 AutoFile.IsBinary = True
   3323                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   3324             if UniStringBinBuffer != None:
   3325                 UniStringBinBuffer.close()
   3326             if str(StringIdf) != "":
   3327                 AutoFile = PathClass(gAutoGenImageDefFileName % {"module_name":self.Name}, self.DebugDir)
   3328                 self._AutoGenFileList[AutoFile] = str(StringIdf)
   3329                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   3330             if IdfGenBinBuffer != None and IdfGenBinBuffer.getvalue() != "":
   3331                 AutoFile = PathClass(gAutoGenIdfFileName % {"module_name":self.Name}, self.OutputDir)
   3332                 self._AutoGenFileList[AutoFile] = IdfGenBinBuffer.getvalue()
   3333                 AutoFile.IsBinary = True
   3334                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   3335             if IdfGenBinBuffer != None:
   3336                 IdfGenBinBuffer.close()
   3337         return self._AutoGenFileList
   3338 
   3339     ## Return the list of library modules explicitly or implicityly used by this module

   3340     def _GetLibraryList(self):
   3341         if self._DependentLibraryList == None:
   3342             # only merge library classes and PCD for non-library module

   3343             if self.IsLibrary:
   3344                 self._DependentLibraryList = []
   3345             else:
   3346                 if self.AutoGenVersion < 0x00010005:
   3347                     self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)
   3348                 else:
   3349                     self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)
   3350         return self._DependentLibraryList
   3351 
   3352     @staticmethod
   3353     def UpdateComments(Recver, Src):
   3354         for Key in Src:
   3355             if Key not in Recver:
   3356                 Recver[Key] = []
   3357             Recver[Key].extend(Src[Key])
   3358     ## Get the list of PCDs from current module

   3359     #

   3360     #   @retval     list                    The list of PCD

   3361     #

   3362     def _GetModulePcdList(self):
   3363         if self._ModulePcdList == None:
   3364             # apply PCD settings from platform

   3365             self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)
   3366             self.UpdateComments(self._PcdComments, self.Module.PcdComments)
   3367         return self._ModulePcdList
   3368 
   3369     ## Get the list of PCDs from dependent libraries

   3370     #

   3371     #   @retval     list                    The list of PCD

   3372     #

   3373     def _GetLibraryPcdList(self):
   3374         if self._LibraryPcdList == None:
   3375             Pcds = sdict()
   3376             if not self.IsLibrary:
   3377                 # get PCDs from dependent libraries

   3378                 for Library in self.DependentLibraryList:
   3379                     self.UpdateComments(self._PcdComments, Library.PcdComments)
   3380                     for Key in Library.Pcds:
   3381                         # skip duplicated PCDs

   3382                         if Key in self.Module.Pcds or Key in Pcds:
   3383                             continue
   3384                         Pcds[Key] = copy.copy(Library.Pcds[Key])
   3385                 # apply PCD settings from platform

   3386                 self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)
   3387             else:
   3388                 self._LibraryPcdList = []
   3389         return self._LibraryPcdList
   3390 
   3391     ## Get the GUID value mapping

   3392     #

   3393     #   @retval     dict    The mapping between GUID cname and its value

   3394     #

   3395     def _GetGuidList(self):
   3396         if self._GuidList == None:
   3397             self._GuidList = sdict()
   3398             self._GuidList.update(self.Module.Guids)
   3399             for Library in self.DependentLibraryList:
   3400                 self._GuidList.update(Library.Guids)
   3401                 self.UpdateComments(self._GuidComments, Library.GuidComments)
   3402             self.UpdateComments(self._GuidComments, self.Module.GuidComments)
   3403         return self._GuidList
   3404 
   3405     def GetGuidsUsedByPcd(self):
   3406         if self._GuidsUsedByPcd == None:
   3407             self._GuidsUsedByPcd = sdict()
   3408             self._GuidsUsedByPcd.update(self.Module.GetGuidsUsedByPcd())
   3409             for Library in self.DependentLibraryList:
   3410                 self._GuidsUsedByPcd.update(Library.GetGuidsUsedByPcd())
   3411         return self._GuidsUsedByPcd
   3412     ## Get the protocol value mapping

   3413     #

   3414     #   @retval     dict    The mapping between protocol cname and its value

   3415     #

   3416     def _GetProtocolList(self):
   3417         if self._ProtocolList == None:
   3418             self._ProtocolList = sdict()
   3419             self._ProtocolList.update(self.Module.Protocols)
   3420             for Library in self.DependentLibraryList:
   3421                 self._ProtocolList.update(Library.Protocols)
   3422                 self.UpdateComments(self._ProtocolComments, Library.ProtocolComments)
   3423             self.UpdateComments(self._ProtocolComments, self.Module.ProtocolComments)
   3424         return self._ProtocolList
   3425 
   3426     ## Get the PPI value mapping

   3427     #

   3428     #   @retval     dict    The mapping between PPI cname and its value

   3429     #

   3430     def _GetPpiList(self):
   3431         if self._PpiList == None:
   3432             self._PpiList = sdict()
   3433             self._PpiList.update(self.Module.Ppis)
   3434             for Library in self.DependentLibraryList:
   3435                 self._PpiList.update(Library.Ppis)
   3436                 self.UpdateComments(self._PpiComments, Library.PpiComments)
   3437             self.UpdateComments(self._PpiComments, self.Module.PpiComments)
   3438         return self._PpiList
   3439 
   3440     ## Get the list of include search path

   3441     #

   3442     #   @retval     list                    The list path

   3443     #

   3444     def _GetIncludePathList(self):
   3445         if self._IncludePathList == None:
   3446             self._IncludePathList = []
   3447             if self.AutoGenVersion < 0x00010005:
   3448                 for Inc in self.Module.Includes:
   3449                     if Inc not in self._IncludePathList:
   3450                         self._IncludePathList.append(Inc)
   3451                     # for Edk modules

   3452                     Inc = path.join(Inc, self.Arch.capitalize())
   3453                     if os.path.exists(Inc) and Inc not in self._IncludePathList:
   3454                         self._IncludePathList.append(Inc)
   3455                 # Edk module needs to put DEBUG_DIR at the end of search path and not to use SOURCE_DIR all the time

   3456                 self._IncludePathList.append(self.DebugDir)
   3457             else:
   3458                 self._IncludePathList.append(self.MetaFile.Dir)
   3459                 self._IncludePathList.append(self.DebugDir)
   3460 
   3461             for Package in self.Module.Packages:
   3462                 PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)
   3463                 if PackageDir not in self._IncludePathList:
   3464                     self._IncludePathList.append(PackageDir)
   3465                 IncludesList = Package.Includes
   3466                 if Package._PrivateIncludes:
   3467                     if not self.MetaFile.Path.startswith(PackageDir):
   3468                         IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes)))
   3469                 for Inc in IncludesList:
   3470                     if Inc not in self._IncludePathList:
   3471                         self._IncludePathList.append(str(Inc))
   3472         return self._IncludePathList
   3473 
   3474     def _GetIncludePathLength(self):
   3475         self._IncludePathLength = 0
   3476         if self._IncludePathList:
   3477             for inc in self._IncludePathList:
   3478                 self._IncludePathLength += len(' ' + inc)
   3479         return self._IncludePathLength
   3480 
   3481     ## Get HII EX PCDs which maybe used by VFR

   3482     #

   3483     #  efivarstore used by VFR may relate with HII EX PCDs

   3484     #  Get the variable name and GUID from efivarstore and HII EX PCD

   3485     #  List the HII EX PCDs in As Built INF if both name and GUID match.

   3486     #

   3487     #  @retval    list    HII EX PCDs

   3488     #

   3489     def _GetPcdsMaybeUsedByVfr(self):
   3490         if not self.SourceFileList:
   3491             return []
   3492 
   3493         NameGuids = []
   3494         for SrcFile in self.SourceFileList:
   3495             if SrcFile.Ext.lower() != '.vfr':
   3496                 continue
   3497             Vfri = os.path.join(self.OutputDir, SrcFile.BaseName + '.i')
   3498             if not os.path.exists(Vfri):
   3499                 continue
   3500             VfriFile = open(Vfri, 'r')
   3501             Content = VfriFile.read()
   3502             VfriFile.close()
   3503             Pos = Content.find('efivarstore')
   3504             while Pos != -1:
   3505                 #

   3506                 # Make sure 'efivarstore' is the start of efivarstore statement

   3507                 # In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'

   3508                 #

   3509                 Index = Pos - 1
   3510                 while Index >= 0 and Content[Index] in ' \t\r\n':
   3511                     Index -= 1
   3512                 if Index >= 0 and Content[Index] != ';':
   3513                     Pos = Content.find('efivarstore', Pos + len('efivarstore'))
   3514                     continue
   3515                 #

   3516                 # 'efivarstore' must be followed by name and guid

   3517                 #

   3518                 Name = gEfiVarStoreNamePattern.search(Content, Pos)
   3519                 if not Name:
   3520                     break
   3521                 Guid = gEfiVarStoreGuidPattern.search(Content, Pos)
   3522                 if not Guid:
   3523                     break
   3524                 NameArray = ConvertStringToByteArray('L"' + Name.group(1) + '"')
   3525                 NameGuids.append((NameArray, GuidStructureStringToGuidString(Guid.group(1))))
   3526                 Pos = Content.find('efivarstore', Name.end())
   3527         if not NameGuids:
   3528             return []
   3529         HiiExPcds = []
   3530         for Pcd in self.PlatformInfo.Platform.Pcds.values():
   3531             if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII:
   3532                 continue
   3533             for SkuName in Pcd.SkuInfoList:
   3534                 SkuInfo = Pcd.SkuInfoList[SkuName]
   3535                 Name = ConvertStringToByteArray(SkuInfo.VariableName)
   3536                 Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList, self.MetaFile.Path)
   3537                 if not Value:
   3538                     continue
   3539                 Guid = GuidStructureStringToGuidString(Value)
   3540                 if (Name, Guid) in NameGuids and Pcd not in HiiExPcds:
   3541                     HiiExPcds.append(Pcd)
   3542                     break
   3543 
   3544         return HiiExPcds
   3545 
   3546     def _GenOffsetBin(self):
   3547         VfrUniBaseName = {}
   3548         for SourceFile in self.Module.Sources:
   3549             if SourceFile.Type.upper() == ".VFR" :
   3550                 #

   3551                 # search the .map file to find the offset of vfr binary in the PE32+/TE file. 

   3552                 #

   3553                 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")
   3554             if SourceFile.Type.upper() == ".UNI" :
   3555                 #

   3556                 # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. 

   3557                 #

   3558                 VfrUniBaseName["UniOffsetName"] = (self.Name + "Strings")
   3559 
   3560         if len(VfrUniBaseName) == 0:
   3561             return None
   3562         MapFileName = os.path.join(self.OutputDir, self.Name + ".map")
   3563         EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi")
   3564         VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())
   3565         if not VfrUniOffsetList:
   3566             return None
   3567 
   3568         OutputName = '%sOffset.bin' % self.Name
   3569         UniVfrOffsetFileName    =  os.path.join( self.OutputDir, OutputName)
   3570 
   3571         try:
   3572             fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
   3573         except:
   3574             EdkLogger.error("build", FILE_OPEN_FAILURE, "File open failed for %s" % UniVfrOffsetFileName,None)
   3575 
   3576         # Use a instance of StringIO to cache data

   3577         fStringIO = StringIO('')  
   3578 
   3579         for Item in VfrUniOffsetList:
   3580             if (Item[0].find("Strings") != -1):
   3581                 #

   3582                 # UNI offset in image.

   3583                 # GUID + Offset

   3584                 # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }

   3585                 #

   3586                 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
   3587                 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
   3588                 fStringIO.write(''.join(UniGuid))            
   3589                 UniValue = pack ('Q', int (Item[1], 16))
   3590                 fStringIO.write (UniValue)
   3591             else:
   3592                 #

   3593                 # VFR binary offset in image.

   3594                 # GUID + Offset

   3595                 # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };

   3596                 #

   3597                 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
   3598                 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
   3599                 fStringIO.write(''.join(VfrGuid))                   
   3600                 type (Item[1]) 
   3601                 VfrValue = pack ('Q', int (Item[1], 16))
   3602                 fStringIO.write (VfrValue)
   3603         #

   3604         # write data into file.

   3605         #

   3606         try :  
   3607             fInputfile.write (fStringIO.getvalue())
   3608         except:
   3609             EdkLogger.error("build", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the "
   3610                             "file been locked or using by other applications." %UniVfrOffsetFileName,None)
   3611 
   3612         fStringIO.close ()
   3613         fInputfile.close ()
   3614         return OutputName
   3615 
   3616     ## Create AsBuilt INF file the module

   3617     #

   3618     def CreateAsBuiltInf(self):
   3619         if self.IsAsBuiltInfCreated:
   3620             return
   3621             
   3622         # Skip the following code for EDK I inf

   3623         if self.AutoGenVersion < 0x00010005:
   3624             return
   3625             
   3626         # Skip the following code for libraries

   3627         if self.IsLibrary:
   3628             return
   3629             
   3630         # Skip the following code for modules with no source files

   3631         if self.SourceFileList == None or self.SourceFileList == []:
   3632             return
   3633 
   3634         # Skip the following code for modules without any binary files

   3635         if self.BinaryFileList <> None and self.BinaryFileList <> []:
   3636             return
   3637             
   3638         ### TODO: How to handles mixed source and binary modules

   3639 
   3640         # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries

   3641         # Also find all packages that the DynamicEx PCDs depend on

   3642         Pcds = []
   3643         PatchablePcds = []
   3644         Packages = []
   3645         PcdCheckList = []
   3646         PcdTokenSpaceList = []
   3647         for Pcd in self.ModulePcdList + self.LibraryPcdList:
   3648             if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
   3649                 PatchablePcds += [Pcd]
   3650                 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'PatchableInModule'))
   3651             elif Pcd.Type in GenC.gDynamicExPcd:
   3652                 if Pcd not in Pcds:
   3653                     Pcds += [Pcd]
   3654                     PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx'))
   3655                     PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic'))
   3656                     PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName)
   3657         GuidList = sdict()
   3658         GuidList.update(self.GuidList)
   3659         for TokenSpace in self.GetGuidsUsedByPcd():
   3660             # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list

   3661             # The GUIDs in GUIDs section should really be the GUIDs in source INF or referred by Ex an patch PCDs

   3662             if TokenSpace not in PcdTokenSpaceList and TokenSpace in GuidList:
   3663                 GuidList.pop(TokenSpace)
   3664         CheckList = (GuidList, self.PpiList, self.ProtocolList, PcdCheckList)
   3665         for Package in self.DerivedPackageList:
   3666             if Package in Packages:
   3667                 continue
   3668             BeChecked = (Package.Guids, Package.Ppis, Package.Protocols, Package.Pcds)
   3669             Found = False
   3670             for Index in range(len(BeChecked)):
   3671                 for Item in CheckList[Index]:
   3672                     if Item in BeChecked[Index]:
   3673                         Packages += [Package]
   3674                         Found = True
   3675                         break
   3676                 if Found: break
   3677 
   3678         VfrPcds = self._GetPcdsMaybeUsedByVfr()
   3679         for Pkg in self.PlatformInfo.PackageList:
   3680             if Pkg in Packages:
   3681                 continue
   3682             for VfrPcd in VfrPcds:
   3683                 if ((VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'DynamicEx') in Pkg.Pcds or
   3684                     (VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'Dynamic') in Pkg.Pcds):
   3685                     Packages += [Pkg]
   3686                     break
   3687 
   3688         ModuleType = self.ModuleType
   3689         if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated:
   3690             ModuleType = 'DXE_DRIVER'
   3691 
   3692         DriverType = ''
   3693         if self.PcdIsDriver != '':
   3694             DriverType = self.PcdIsDriver
   3695 
   3696         Guid = self.Guid
   3697         MDefs = self.Module.Defines
   3698 
   3699         AsBuiltInfDict = {
   3700           'module_name'                       : self.Name,
   3701           'module_guid'                       : Guid,
   3702           'module_module_type'                : ModuleType,
   3703           'module_version_string'             : [MDefs['VERSION_STRING']] if 'VERSION_STRING' in MDefs else [],
   3704           'pcd_is_driver_string'              : [],
   3705           'module_uefi_specification_version' : [],
   3706           'module_pi_specification_version'   : [],
   3707           'module_entry_point'                : self.Module.ModuleEntryPointList,
   3708           'module_unload_image'               : self.Module.ModuleUnloadImageList,
   3709           'module_constructor'                : self.Module.ConstructorList,
   3710           'module_destructor'                 : self.Module.DestructorList,
   3711           'module_shadow'                     : [MDefs['SHADOW']] if 'SHADOW' in MDefs else [],
   3712           'module_pci_vendor_id'              : [MDefs['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs else [],
   3713           'module_pci_device_id'              : [MDefs['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs else [],
   3714           'module_pci_class_code'             : [MDefs['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs else [],
   3715           'module_pci_revision'               : [MDefs['PCI_REVISION']] if 'PCI_REVISION' in MDefs else [],
   3716           'module_build_number'               : [MDefs['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs else [],
   3717           'module_spec'                       : [MDefs['SPEC']] if 'SPEC' in MDefs else [],
   3718           'module_uefi_hii_resource_section'  : [MDefs['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs else [],
   3719           'module_uni_file'                   : [MDefs['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs else [],
   3720           'module_arch'                       : self.Arch,
   3721           'package_item'                      : ['%s' % (Package.MetaFile.File.replace('\\', '/')) for Package in Packages],
   3722           'binary_item'                       : [],
   3723           'patchablepcd_item'                 : [],
   3724           'pcd_item'                          : [],
   3725           'protocol_item'                     : [],
   3726           'ppi_item'                          : [],
   3727           'guid_item'                         : [],
   3728           'flags_item'                        : [],
   3729           'libraryclasses_item'               : []
   3730         }
   3731 
   3732         if self.AutoGenVersion > int(gInfSpecVersion, 0):
   3733             AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion
   3734         else:
   3735             AsBuiltInfDict['module_inf_version'] = gInfSpecVersion
   3736 
   3737         if DriverType:
   3738             AsBuiltInfDict['pcd_is_driver_string'] += [DriverType]
   3739 
   3740         if 'UEFI_SPECIFICATION_VERSION' in self.Specification:
   3741             AsBuiltInfDict['module_uefi_specification_version'] += [self.Specification['UEFI_SPECIFICATION_VERSION']]
   3742         if 'PI_SPECIFICATION_VERSION' in self.Specification:
   3743             AsBuiltInfDict['module_pi_specification_version'] += [self.Specification['PI_SPECIFICATION_VERSION']]
   3744 
   3745         OutputDir = self.OutputDir.replace('\\', '/').strip('/')
   3746 
   3747         for Item in self.CodaTargetList:
   3748             File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/')
   3749             if Item.Target.Ext.lower() == '.aml':
   3750                 AsBuiltInfDict['binary_item'] += ['ASL|' + File]
   3751             elif Item.Target.Ext.lower() == '.acpi':
   3752                 AsBuiltInfDict['binary_item'] += ['ACPI|' + File]
   3753             elif Item.Target.Ext.lower() == '.efi':
   3754                 AsBuiltInfDict['binary_item'] += ['PE32|' + self.Name + '.efi']
   3755             else:
   3756                 AsBuiltInfDict['binary_item'] += ['BIN|' + File]
   3757         if self.DepexGenerated:
   3758             if self.ModuleType in ['PEIM']:
   3759                 AsBuiltInfDict['binary_item'] += ['PEI_DEPEX|' + self.Name + '.depex']
   3760             if self.ModuleType in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']:
   3761                 AsBuiltInfDict['binary_item'] += ['DXE_DEPEX|' + self.Name + '.depex']
   3762             if self.ModuleType in ['DXE_SMM_DRIVER']:
   3763                 AsBuiltInfDict['binary_item'] += ['SMM_DEPEX|' + self.Name + '.depex']
   3764 
   3765         Bin = self._GenOffsetBin()
   3766         if Bin:
   3767             AsBuiltInfDict['binary_item'] += ['BIN|%s' % Bin]
   3768 
   3769         for Root, Dirs, Files in os.walk(OutputDir):
   3770             for File in Files:
   3771                 if File.lower().endswith('.pdb'):
   3772                     AsBuiltInfDict['binary_item'] += ['DISPOSABLE|' + File]
   3773         HeaderComments = self.Module.HeaderComments
   3774         StartPos = 0
   3775         for Index in range(len(HeaderComments)):
   3776             if HeaderComments[Index].find('@BinaryHeader') != -1:
   3777                 HeaderComments[Index] = HeaderComments[Index].replace('@BinaryHeader', '@file')
   3778                 StartPos = Index
   3779                 break
   3780         AsBuiltInfDict['header_comments'] = '\n'.join(HeaderComments[StartPos:]).replace(':#', '://')

   3781         AsBuiltInfDict['tail_comments'] = '\n'.join(self.Module.TailComments)
   3782 
   3783         GenList = [
   3784             (self.ProtocolList, self._ProtocolComments, 'protocol_item'),
   3785             (self.PpiList, self._PpiComments, 'ppi_item'),
   3786             (GuidList, self._GuidComments, 'guid_item')
   3787         ]
   3788         for Item in GenList:
   3789             for CName in Item[0]:
   3790                 Comments = ''
   3791                 if CName in Item[1]:
   3792                     Comments = '\n  '.join(Item[1][CName])
   3793                 Entry = CName
   3794                 if Comments:
   3795                     Entry = Comments + '\n  ' + CName
   3796                 AsBuiltInfDict[Item[2]].append(Entry)
   3797         PatchList = parsePcdInfoFromMapFile(
   3798                             os.path.join(self.OutputDir, self.Name + '.map'),
   3799                             os.path.join(self.OutputDir, self.Name + '.efi')
   3800                         )
   3801         if PatchList:
   3802             for Pcd in PatchablePcds:
   3803                 TokenCName = Pcd.TokenCName
   3804                 for PcdItem in GlobalData.MixedPcd:
   3805                     if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
   3806                         TokenCName = PcdItem[0]
   3807                         break
   3808                 for PatchPcd in PatchList:
   3809                     if TokenCName == PatchPcd[0]:
   3810                         break
   3811                 else:
   3812                     continue
   3813                 PcdValue = ''
   3814                 if Pcd.DatumType != 'VOID*':
   3815                     HexFormat = '0x%02x'
   3816                     if Pcd.DatumType == 'UINT16':
   3817                         HexFormat = '0x%04x'
   3818                     elif Pcd.DatumType == 'UINT32':
   3819                         HexFormat = '0x%08x'
   3820                     elif Pcd.DatumType == 'UINT64':
   3821                         HexFormat = '0x%016x'
   3822                     PcdValue = HexFormat % int(Pcd.DefaultValue, 0)
   3823                 else:
   3824                     if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
   3825                         EdkLogger.error("build", AUTOGEN_ERROR,
   3826                                         "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, TokenCName)
   3827                                         )
   3828                     ArraySize = int(Pcd.MaxDatumSize, 0)
   3829                     PcdValue = Pcd.DefaultValue
   3830                     if PcdValue[0] != '{':
   3831                         Unicode = False
   3832                         if PcdValue[0] == 'L':
   3833                             Unicode = True
   3834                         PcdValue = PcdValue.lstrip('L')
   3835                         PcdValue = eval(PcdValue)
   3836                         NewValue = '{'
   3837                         for Index in range(0, len(PcdValue)):
   3838                             if Unicode:
   3839                                 CharVal = ord(PcdValue[Index])
   3840                                 NewValue = NewValue + '0x%02x' % (CharVal & 0x00FF) + ', ' \
   3841                                         + '0x%02x' % (CharVal >> 8) + ', '
   3842                             else:
   3843                                 NewValue = NewValue + '0x%02x' % (ord(PcdValue[Index]) % 0x100) + ', '
   3844                         Padding = '0x00, '
   3845                         if Unicode:
   3846                             Padding = Padding * 2
   3847                             ArraySize = ArraySize / 2
   3848                         if ArraySize < (len(PcdValue) + 1):
   3849                             EdkLogger.error("build", AUTOGEN_ERROR,
   3850                                             "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)
   3851                                             )
   3852                         if ArraySize > len(PcdValue) + 1:
   3853                             NewValue = NewValue + Padding * (ArraySize - len(PcdValue) - 1)
   3854                         PcdValue = NewValue + Padding.strip().rstrip(',') + '}'
   3855                     elif len(PcdValue.split(',')) <= ArraySize:
   3856                         PcdValue = PcdValue.rstrip('}') + ', 0x00' * (ArraySize - len(PcdValue.split(',')))
   3857                         PcdValue += '}'
   3858                     else:
   3859                         EdkLogger.error("build", AUTOGEN_ERROR,
   3860                                         "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, TokenCName)
   3861                                         )
   3862                 PcdItem = '%s.%s|%s|0x%X' % \
   3863                     (Pcd.TokenSpaceGuidCName, TokenCName, PcdValue, PatchPcd[1])
   3864                 PcdComments = ''
   3865                 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
   3866                     PcdComments = '\n  '.join(self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName])
   3867                 if PcdComments:
   3868                     PcdItem = PcdComments + '\n  ' + PcdItem
   3869                 AsBuiltInfDict['patchablepcd_item'].append(PcdItem)
   3870 
   3871         HiiPcds = []
   3872         for Pcd in Pcds + VfrPcds:
   3873             PcdComments = ''
   3874             PcdCommentList = []
   3875             HiiInfo = ''
   3876             SkuId = ''
   3877             TokenCName = Pcd.TokenCName
   3878             for PcdItem in GlobalData.MixedPcd:
   3879                 if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName) in GlobalData.MixedPcd[PcdItem]:
   3880                     TokenCName = PcdItem[0]
   3881                     break
   3882             if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII:
   3883                 for SkuName in Pcd.SkuInfoList:
   3884                     SkuInfo = Pcd.SkuInfoList[SkuName]
   3885                     SkuId = SkuInfo.SkuId
   3886                     HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset)
   3887                     break
   3888             if SkuId:
   3889                 #

   3890                 # Don't generate duplicated HII PCD

   3891                 #

   3892                 if (SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in HiiPcds:
   3893                     continue
   3894                 else:
   3895                     HiiPcds.append((SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
   3896             if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
   3897                 PcdCommentList = self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName][:]
   3898             if HiiInfo:
   3899                 UsageIndex = -1
   3900                 UsageStr = ''
   3901                 for Index, Comment in enumerate(PcdCommentList):
   3902                     for Usage in UsageList:
   3903                         if Comment.find(Usage) != -1:
   3904                             UsageStr = Usage
   3905                             UsageIndex = Index
   3906                             break
   3907                 if UsageIndex != -1:
   3908                     PcdCommentList[UsageIndex] = '## %s %s %s' % (UsageStr, HiiInfo, PcdCommentList[UsageIndex].replace(UsageStr, '')) 
   3909                 else:
   3910                     PcdCommentList.append('## UNDEFINED ' + HiiInfo)
   3911             PcdComments = '\n  '.join(PcdCommentList)
   3912             PcdEntry = Pcd.TokenSpaceGuidCName + '.' + TokenCName
   3913             if PcdComments:
   3914                 PcdEntry = PcdComments + '\n  ' + PcdEntry
   3915             AsBuiltInfDict['pcd_item'] += [PcdEntry]
   3916         for Item in self.BuildOption:
   3917             if 'FLAGS' in self.BuildOption[Item]:
   3918                 AsBuiltInfDict['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self.ToolChainFamily, self.BuildTarget, self.ToolChain, self.Arch, Item, self.BuildOption[Item]['FLAGS'].strip())]
   3919 
   3920         # Generated LibraryClasses section in comments.

   3921         for Library in self.LibraryAutoGenList:
   3922             AsBuiltInfDict['libraryclasses_item'] += [Library.MetaFile.File.replace('\\', '/')]
   3923         
   3924         # Generated depex expression section in comments.
   3925         AsBuiltInfDict['depexsection_item'] = ''
   3926         DepexExpresion = self._GetDepexExpresionString()
   3927         if DepexExpresion:
   3928             AsBuiltInfDict['depexsection_item'] = DepexExpresion
   3929         
   3930         AsBuiltInf = TemplateString()
   3931         AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict))
   3932         
   3933         SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False)
   3934         
   3935         self.IsAsBuiltInfCreated = True
   3936         
   3937     ## Create makefile for the module and its dependent libraries
   3938     #
   3939     #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of
   3940     #                                       dependent libraries will be created
   3941     #
   3942     def CreateMakeFile(self, CreateLibraryMakeFile=True):
   3943         # Ignore generating makefile when it is a binary module
   3944         if self.IsBinaryModule:
   3945             return
   3946 
   3947         if self.IsMakeFileCreated:
   3948             return
   3949 
   3950         if not self.IsLibrary and CreateLibraryMakeFile:
   3951             for LibraryAutoGen in self.LibraryAutoGenList:
   3952                 LibraryAutoGen.CreateMakeFile()
   3953 
   3954         if len(self.CustomMakefile) == 0:
   3955             Makefile = GenMake.ModuleMakefile(self)
   3956         else:
   3957             Makefile = GenMake.CustomMakefile(self)
   3958         if Makefile.Generate():
   3959             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %
   3960                             (self.Name, self.Arch))
   3961         else:
   3962             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %
   3963                             (self.Name, self.Arch))
   3964 
   3965         self.IsMakeFileCreated = True
   3966 
   3967     def CopyBinaryFiles(self):
   3968         for File in self.Module.Binaries:
   3969             SrcPath = File.Path
   3970             DstPath = os.path.join(self.OutputDir , os.path.basename(SrcPath))
   3971             CopyLongFilePath(SrcPath, DstPath)
   3972     ## Create autogen code for the module and its dependent libraries
   3973     #
   3974     #   @param      CreateLibraryCodeFile   Flag indicating if or not the code of
   3975     #                                       dependent libraries will be created
   3976     #
   3977     def CreateCodeFile(self, CreateLibraryCodeFile=True):
   3978         if self.IsCodeFileCreated:
   3979             return
   3980 
   3981         # Need to generate PcdDatabase even PcdDriver is binarymodule
   3982         if self.IsBinaryModule and self.PcdIsDriver != '':
   3983             CreatePcdDatabaseCode(self, TemplateString(), TemplateString())
   3984             return
   3985         if self.IsBinaryModule:
   3986             if self.IsLibrary:
   3987                 self.CopyBinaryFiles()
   3988             return
   3989 
   3990         if not self.IsLibrary and CreateLibraryCodeFile:
   3991             for LibraryAutoGen in self.LibraryAutoGenList:
   3992                 LibraryAutoGen.CreateCodeFile()
   3993 
   3994         AutoGenList = []
   3995         IgoredAutoGenList = []
   3996 
   3997         for File in self.AutoGenFileList:
   3998             if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):
   3999                 #Ignore Edk AutoGen.c
   4000                 if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':
   4001                         continue
   4002 
   4003                 AutoGenList.append(str(File))
   4004             else:
   4005                 IgoredAutoGenList.append(str(File))
   4006 
   4007         # Skip the following code for EDK I inf
   4008         if self.AutoGenVersion < 0x00010005:
   4009             return
   4010 
   4011         for ModuleType in self.DepexList:
   4012             # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module
   4013             if len(self.DepexList[ModuleType]) == 0 or ModuleType == "USER_DEFINED":
   4014                 continue
   4015 
   4016             Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)
   4017             DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
   4018 
   4019             if len(Dpx.PostfixNotation) <> 0:
   4020                 self.DepexGenerated = True
   4021 
   4022             if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
   4023                 AutoGenList.append(str(DpxFile))
   4024             else:
   4025                 IgoredAutoGenList.append(str(DpxFile))
   4026 
   4027         if IgoredAutoGenList == []:
   4028             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %
   4029                             (" ".join(AutoGenList), self.Name, self.Arch))
   4030         elif AutoGenList == []:
   4031             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %
   4032                             (" ".join(IgoredAutoGenList), self.Name, self.Arch))
   4033         else:
   4034             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %
   4035                             (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))
   4036 
   4037         self.IsCodeFileCreated = True
   4038         return AutoGenList
   4039 
   4040     ## Summarize the ModuleAutoGen objects of all libraries used by this module
   4041     def _GetLibraryAutoGenList(self):
   4042         if self._LibraryAutoGenList == None:
   4043             self._LibraryAutoGenList = []
   4044             for Library in self.DependentLibraryList:
   4045                 La = ModuleAutoGen(
   4046                         self.Workspace,
   4047                         Library.MetaFile,
   4048                         self.BuildTarget,
   4049                         self.ToolChain,
   4050                         self.Arch,
   4051                         self.PlatformInfo.MetaFile
   4052                         )
   4053                 if La not in self._LibraryAutoGenList:
   4054                     self._LibraryAutoGenList.append(La)
   4055                     for Lib in La.CodaTargetList:
   4056                         self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)
   4057         return self._LibraryAutoGenList
   4058 
   4059     Module          = property(_GetModule)
   4060     Name            = property(_GetBaseName)
   4061     Guid            = property(_GetGuid)
   4062     Version         = property(_GetVersion)
   4063     ModuleType      = property(_GetModuleType)
   4064     ComponentType   = property(_GetComponentType)
   4065     BuildType       = property(_GetBuildType)
   4066     PcdIsDriver     = property(_GetPcdIsDriver)
   4067     AutoGenVersion  = property(_GetAutoGenVersion)
   4068     Macros          = property(_GetMacros)
   4069     Specification   = property(_GetSpecification)
   4070 
   4071     IsLibrary       = property(_IsLibrary)
   4072     IsBinaryModule  = property(_IsBinaryModule)
   4073     BuildDir        = property(_GetBuildDir)
   4074     OutputDir       = property(_GetOutputDir)
   4075     DebugDir        = property(_GetDebugDir)
   4076     MakeFileDir     = property(_GetMakeFileDir)
   4077     CustomMakefile  = property(_GetCustomMakefile)
   4078 
   4079     IncludePathList = property(_GetIncludePathList)
   4080     IncludePathLength = property(_GetIncludePathLength)
   4081     AutoGenFileList = property(_GetAutoGenFileList)
   4082     UnicodeFileList = property(_GetUnicodeFileList)
   4083     SourceFileList  = property(_GetSourceFileList)
   4084     BinaryFileList  = property(_GetBinaryFiles) # FileType : [File List]
   4085     Targets         = property(_GetTargets)
   4086     IntroTargetList = property(_GetIntroTargetList)
   4087     CodaTargetList  = property(_GetFinalTargetList)
   4088     FileTypes       = property(_GetFileTypes)
   4089     BuildRules      = property(_GetBuildRules)
   4090     IdfFileList     = property(_GetIdfFileList)
   4091 
   4092     DependentPackageList    = property(_GetDependentPackageList)
   4093     DependentLibraryList    = property(_GetLibraryList)
   4094     LibraryAutoGenList      = property(_GetLibraryAutoGenList)
   4095     DerivedPackageList      = property(_GetDerivedPackageList)
   4096 
   4097     ModulePcdList           = property(_GetModulePcdList)
   4098     LibraryPcdList          = property(_GetLibraryPcdList)
   4099     GuidList                = property(_GetGuidList)
   4100     ProtocolList            = property(_GetProtocolList)
   4101     PpiList                 = property(_GetPpiList)
   4102     DepexList               = property(_GetDepexTokenList)
   4103     DxsFile                 = property(_GetDxsFile)
   4104     DepexExpressionList     = property(_GetDepexExpressionTokenList)
   4105     BuildOption             = property(_GetModuleBuildOption)
   4106     BuildOptionIncPathList  = property(_GetBuildOptionIncPathList)
   4107     BuildCommand            = property(_GetBuildCommand)
   4108     
   4109     FixedAtBuildPcds         = property(_GetFixedAtBuildPcds)
   4110 
   4111 # This acts like the main() function for the script, unless it is 'import'ed into another script.
   4112 if __name__ == '__main__':
   4113     pass
   4114 
   4115