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

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

      3 #

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

      5 # This program and the accompanying materials

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

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

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

      9 #

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

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

     12 #

     13 
     14 ## Import Modules

     15 #

     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 
     76 gInfSpecVersion = "0x00010017"
     77 
     78 #

     79 # Template string to generic AsBuilt INF

     80 #

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

    149 #

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

    151 #

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

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

    155 
    156     ## Factory method

    157     #

    158     #   @param  Class           class object of real AutoGen class

    159     #                           (WorkspaceAutoGen, ModuleAutoGen or PlatformAutoGen)

    160     #   @param  Workspace       Workspace directory or WorkspaceAutoGen object

    161     #   @param  MetaFile        The path of meta file

    162     #   @param  Target          Build target

    163     #   @param  Toolchain       Tool chain name

    164     #   @param  Arch            Target arch

    165     #   @param  *args           The specific class related parameters

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

    167     #

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

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

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

    188     #

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

    190     #

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

    192     #

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

    197     #

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

    199     #

    200     #   @retval string  String of platform file path

    201     #

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

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

    210 #

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

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

    213 #

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

    216     #

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

    218     # (in super class's __new__ method)

    219     #

    220     #   @param  WorkspaceDir            Root directory of workspace

    221     #   @param  ActivePlatform          Meta-file of active platform

    222     #   @param  Target                  Build target

    223     #   @param  Toolchain               Tool chain name

    224     #   @param  ArchList                List of architecture of current build

    225     #   @param  MetaFileDb              Database containing meta-files

    226     #   @param  BuildConfig             Configuration of build

    227     #   @param  ToolDefinition          Tool chain definitions

    228     #   @param  FlashDefinitionFile     File of flash definition

    229     #   @param  Fds                     FD list to be generated

    230     #   @param  Fvs                     FV list to be generated

    231     #   @param  Caps                    Capsule list to be generated

    232     #   @param  SkuId                   SKU id from command line

    233     #

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

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

    266         # Merge Arch

    267         #

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

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

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

    312             # Mark now build in AutoGen Phase

    313             #

    314             GlobalData.gAutoGenPhase = True
    315             Fdf = FdfParser(self.FdfFile.Path)
    316             Fdf.ParseFile()
    317             GlobalData.gFdfParser = Fdf
    318             GlobalData.gAutoGenPhase = False
    319             PcdSet = Fdf.Profile.PcdDict
    320             ModuleList = Fdf.Profile.InfList
    321             self.FdfProfile = Fdf.Profile
    322             for fvname in self.FvTargetList:
    323                 if fvname.upper() not in self.FdfProfile.FvDict:
    324                     EdkLogger.error("build", OPTION_VALUE_INVALID,
    325                                     "No such an FV in FDF file: %s" % fvname)
    326         else:
    327             PcdSet = {}
    328             ModuleList = []
    329             self.FdfProfile = None
    330             if self.FdTargetList:
    331                 EdkLogger.info("No flash definition file found. FD [%s] will be ignored." % " ".join(self.FdTargetList))
    332                 self.FdTargetList = []
    333             if self.FvTargetList:
    334                 EdkLogger.info("No flash definition file found. FV [%s] will be ignored." % " ".join(self.FvTargetList))
    335                 self.FvTargetList = []
    336             if self.CapTargetList:
    337                 EdkLogger.info("No flash definition file found. Capsule [%s] will be ignored." % " ".join(self.CapTargetList))
    338                 self.CapTargetList = []
    339 
    340         # apply SKU and inject PCDs from Flash Definition file

    341         for Arch in self.ArchList:
    342             Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
    343 
    344             DecPcds = {}
    345             DecPcdsKey = set()
    346             PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
    347             #Collect package set information from INF of FDF

    348             PkgSet = set()
    349             for Inf in ModuleList:
    350                 ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)
    351                 if ModuleFile in Platform.Modules:
    352                     continue
    353                 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
    354                 PkgSet.update(ModuleData.Packages)
    355             Pkgs = list(PkgSet) + list(PGen.PackageList)
    356             for Pkg in Pkgs:
    357                 for Pcd in Pkg.Pcds:
    358                     DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
    359                     DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))
    360 
    361             Platform.SkuName = self.SkuId
    362             for Name, Guid in PcdSet:
    363                 if (Name, Guid) not in DecPcds:
    364                     EdkLogger.error(
    365                         'build',
    366                         PARSER_ERROR,
    367                         "PCD (%s.%s) used in FDF is not declared in DEC files." % (Guid, Name),
    368                         File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],
    369                         Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]
    370                     )
    371                 else:
    372                     # Check whether Dynamic or DynamicEx PCD used in FDF file. If used, build break and give a error message.

    373                     if (Name, Guid, TAB_PCDS_FIXED_AT_BUILD) in DecPcdsKey \
    374                         or (Name, Guid, TAB_PCDS_PATCHABLE_IN_MODULE) in DecPcdsKey \
    375                         or (Name, Guid, TAB_PCDS_FEATURE_FLAG) in DecPcdsKey:
    376                         Platform.AddPcd(Name, Guid, PcdSet[Name, Guid])
    377                         continue
    378                     elif (Name, Guid, TAB_PCDS_DYNAMIC) in DecPcdsKey or (Name, Guid, TAB_PCDS_DYNAMIC_EX) in DecPcdsKey:
    379                         EdkLogger.error(
    380                                 'build',
    381                                 PARSER_ERROR,
    382                                 "Using Dynamic or DynamicEx type of PCD [%s.%s] in FDF file is not allowed." % (Guid, Name),
    383                                 File = self.FdfProfile.PcdFileLineDict[Name, Guid][0],
    384                                 Line = self.FdfProfile.PcdFileLineDict[Name, Guid][1]
    385                         )
    386 
    387             Pa = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
    388             #

    389             # Explicitly collect platform's dynamic PCDs

    390             #

    391             Pa.CollectPlatformDynamicPcds()
    392             Pa.CollectFixedAtBuildPcds()
    393             self.AutoGenObjectList.append(Pa)
    394 
    395         #

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

    397         #

    398         self._CheckAllPcdsTokenValueConflict()
    399 
    400         #

    401         # Check PCD type and definition between DSC and DEC

    402         #

    403         self._CheckPcdDefineAndType()
    404 
    405 #         if self.FdfFile:

    406 #             self._CheckDuplicateInFV(Fdf)

    407 
    408         self._BuildDir = None
    409         self._FvDir = None
    410         self._MakeFileDir = None
    411         self._BuildCommand = None
    412 
    413         return True
    414 
    415     ## _CheckDuplicateInFV() method

    416     #

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

    418     # The check base on the file GUID;

    419     #

    420     def _CheckDuplicateInFV(self, Fdf):
    421         for Fv in Fdf.Profile.FvDict:
    422             _GuidDict = {}
    423             for FfsFile in Fdf.Profile.FvDict[Fv].FfsList:
    424                 if FfsFile.InfFileName and FfsFile.NameGuid == None:
    425                     #

    426                     # Get INF file GUID

    427                     #

    428                     InfFoundFlag = False
    429                     for Pa in self.AutoGenObjectList:
    430                         if InfFoundFlag:
    431                             break
    432                         for Module in Pa.ModuleAutoGenList:
    433                             if path.normpath(Module.MetaFile.File) == path.normpath(FfsFile.InfFileName):
    434                                 InfFoundFlag = True
    435                                 if not Module.Guid.upper() in _GuidDict.keys():
    436                                     _GuidDict[Module.Guid.upper()] = FfsFile
    437                                     break
    438                                 else:
    439                                     EdkLogger.error("build",
    440                                                     FORMAT_INVALID,
    441                                                     "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
    442                                                                                                                                    FfsFile.CurrentLineContent,
    443                                                                                                                                    _GuidDict[Module.Guid.upper()].CurrentLineNum,
    444                                                                                                                                    _GuidDict[Module.Guid.upper()].CurrentLineContent,
    445                                                                                                                                    Module.Guid.upper()),
    446                                                     ExtraData=self.FdfFile)
    447                     #

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

    449                     #

    450                     if not InfFoundFlag:
    451                         if FfsFile.InfFileName.find('$') == -1:
    452                             InfPath = NormPath(FfsFile.InfFileName)
    453                             if not os.path.exists(InfPath):
    454                                 EdkLogger.error('build', GENFDS_ERROR, "Non-existant Module %s !" % (FfsFile.InfFileName))
    455 
    456                             PathClassObj = PathClass(FfsFile.InfFileName, self.WorkspaceDir)
    457                             #

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

    459                             # BuildObject from one of AutoGenObjectList is enough.

    460                             #

    461                             InfObj = self.AutoGenObjectList[0].BuildDatabase.WorkspaceDb.BuildObject[PathClassObj, 'COMMON', self.BuildTarget, self.ToolChain]
    462                             if not InfObj.Guid.upper() in _GuidDict.keys():
    463                                 _GuidDict[InfObj.Guid.upper()] = FfsFile
    464                             else:
    465                                 EdkLogger.error("build",
    466                                                 FORMAT_INVALID,
    467                                                 "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
    468                                                                                                                                FfsFile.CurrentLineContent,
    469                                                                                                                                _GuidDict[InfObj.Guid.upper()].CurrentLineNum,
    470                                                                                                                                _GuidDict[InfObj.Guid.upper()].CurrentLineContent,
    471                                                                                                                                InfObj.Guid.upper()),
    472                                                 ExtraData=self.FdfFile)
    473                         InfFoundFlag = False
    474 
    475                 if FfsFile.NameGuid != None:
    476                     _CheckPCDAsGuidPattern = re.compile("^PCD\(.+\..+\)$")
    477 
    478                     #

    479                     # If the NameGuid reference a PCD name. 

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

    481                     #

    482                     if _CheckPCDAsGuidPattern.match(FfsFile.NameGuid):
    483                         #

    484                         # Replace the PCD value.

    485                         #

    486                         _PcdName = FfsFile.NameGuid.lstrip("PCD(").rstrip(")")
    487                         PcdFoundFlag = False
    488                         for Pa in self.AutoGenObjectList:
    489                             if not PcdFoundFlag:
    490                                 for PcdItem in Pa.AllPcdList:
    491                                     if (PcdItem.TokenSpaceGuidCName + "." + PcdItem.TokenCName) == _PcdName:
    492                                         #

    493                                         # First convert from CFormatGuid to GUID string

    494                                         #

    495                                         _PcdGuidString = GuidStructureStringToGuidString(PcdItem.DefaultValue)
    496 
    497                                         if not _PcdGuidString:
    498                                             #

    499                                             # Then try Byte array.

    500                                             #

    501                                             _PcdGuidString = GuidStructureByteArrayToGuidString(PcdItem.DefaultValue)
    502 
    503                                         if not _PcdGuidString:
    504                                             #

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

    506                                             #

    507                                             EdkLogger.error("build",
    508                                                             FORMAT_INVALID,
    509                                                             "The format of PCD value is incorrect. PCD: %s , Value: %s\n" % (_PcdName, PcdItem.DefaultValue),
    510                                                             ExtraData=self.FdfFile)
    511 
    512                                         if not _PcdGuidString.upper() in _GuidDict.keys():
    513                                             _GuidDict[_PcdGuidString.upper()] = FfsFile
    514                                             PcdFoundFlag = True
    515                                             break
    516                                         else:
    517                                             EdkLogger.error("build",
    518                                                             FORMAT_INVALID,
    519                                                             "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
    520                                                                                                                                            FfsFile.CurrentLineContent,
    521                                                                                                                                            _GuidDict[_PcdGuidString.upper()].CurrentLineNum,
    522                                                                                                                                            _GuidDict[_PcdGuidString.upper()].CurrentLineContent,
    523                                                                                                                                            FfsFile.NameGuid.upper()),
    524                                                             ExtraData=self.FdfFile)
    525 
    526                     if not FfsFile.NameGuid.upper() in _GuidDict.keys():
    527                         _GuidDict[FfsFile.NameGuid.upper()] = FfsFile
    528                     else:
    529                         #

    530                         # Two raw file GUID conflict.

    531                         #

    532                         EdkLogger.error("build",
    533                                         FORMAT_INVALID,
    534                                         "Duplicate GUID found for these lines: Line %d: %s and Line %d: %s. GUID: %s" % (FfsFile.CurrentLineNum,
    535                                                                                                                        FfsFile.CurrentLineContent,
    536                                                                                                                        _GuidDict[FfsFile.NameGuid.upper()].CurrentLineNum,
    537                                                                                                                        _GuidDict[FfsFile.NameGuid.upper()].CurrentLineContent,
    538                                                                                                                        FfsFile.NameGuid.upper()),
    539                                         ExtraData=self.FdfFile)
    540 
    541 
    542     def _CheckPcdDefineAndType(self):
    543         PcdTypeList = [
    544             "FixedAtBuild", "PatchableInModule", "FeatureFlag",
    545             "Dynamic", #"DynamicHii", "DynamicVpd",

    546             "DynamicEx", # "DynamicExHii", "DynamicExVpd"

    547         ]
    548 
    549         # This dict store PCDs which are not used by any modules with specified arches

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

    553             for Pcd in Pa.Platform.Pcds:
    554                 PcdType = Pa.Platform.Pcds[Pcd].Type
    555 
    556                 # If no PCD type, this PCD comes from FDF 

    557                 if not PcdType:
    558                     continue
    559 
    560                 # Try to remove Hii and Vpd suffix

    561                 if PcdType.startswith("DynamicEx"):
    562                     PcdType = "DynamicEx"
    563                 elif PcdType.startswith("Dynamic"):
    564                     PcdType = "Dynamic"
    565 
    566                 for Package in Pa.PackageList:
    567                     # Key of DEC's Pcds dictionary is PcdCName, TokenSpaceGuid, PcdType

    568                     if (Pcd[0], Pcd[1], PcdType) in Package.Pcds:
    569                         break
    570                     for Type in PcdTypeList:
    571                         if (Pcd[0], Pcd[1], Type) in Package.Pcds:
    572                             EdkLogger.error(
    573                                 'build',
    574                                 FORMAT_INVALID,
    575                                 "Type [%s] of PCD [%s.%s] in DSC file doesn't match the type [%s] defined in DEC file." \
    576                                 % (Pa.Platform.Pcds[Pcd].Type, Pcd[1], Pcd[0], Type),
    577                                 ExtraData=None
    578                             )
    579                             return
    580                 else:
    581                     UnusedPcd.setdefault(Pcd, []).append(Pa.Arch)
    582 
    583         for Pcd in UnusedPcd:
    584             EdkLogger.warn(
    585                 'build',
    586                 "The PCD was not specified by any INF module in the platform for the given architecture.\n"
    587                 "\tPCD: [%s.%s]\n\tPlatform: [%s]\n\tArch: %s"
    588                 % (Pcd[1], Pcd[0], os.path.basename(str(self.MetaFile)), str(UnusedPcd[Pcd])),
    589                 ExtraData=None
    590             )
    591 
    592     def __repr__(self):
    593         return "%s [%s]" % (self.MetaFile, ", ".join(self.ArchList))
    594 
    595     ## Return the directory to store FV files

    596     def _GetFvDir(self):
    597         if self._FvDir == None:
    598             self._FvDir = path.join(self.BuildDir, 'FV')
    599         return self._FvDir
    600 
    601     ## Return the directory to store all intermediate and final files built

    602     def _GetBuildDir(self):
    603         return self.AutoGenObjectList[0].BuildDir
    604 
    605     ## Return the build output directory platform specifies

    606     def _GetOutputDir(self):
    607         return self.Platform.OutputDirectory
    608 
    609     ## Return platform name

    610     def _GetName(self):
    611         return self.Platform.PlatformName
    612 
    613     ## Return meta-file GUID

    614     def _GetGuid(self):
    615         return self.Platform.Guid
    616 
    617     ## Return platform version

    618     def _GetVersion(self):
    619         return self.Platform.Version
    620 
    621     ## Return paths of tools

    622     def _GetToolDefinition(self):
    623         return self.AutoGenObjectList[0].ToolDefinition
    624 
    625     ## Return directory of platform makefile

    626     #

    627     #   @retval     string  Makefile directory

    628     #

    629     def _GetMakeFileDir(self):
    630         if self._MakeFileDir == None:
    631             self._MakeFileDir = self.BuildDir
    632         return self._MakeFileDir
    633 
    634     ## Return build command string

    635     #

    636     #   @retval     string  Build command string

    637     #

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

    641             self._BuildCommand = self.AutoGenObjectList[0].BuildCommand
    642         return self._BuildCommand
    643 
    644     ## Check the PCDs token value conflict in each DEC file.

    645     #

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

    647     # 

    648     # @return  None

    649     #

    650     def _CheckAllPcdsTokenValueConflict(self):
    651         for Pa in self.AutoGenObjectList:
    652             for Package in Pa.PackageList:
    653                 PcdList = Package.Pcds.values()
    654                 PcdList.sort(lambda x, y: cmp(int(x.TokenValue, 0), int(y.TokenValue, 0))) 
    655                 Count = 0
    656                 while (Count < len(PcdList) - 1) :
    657                     Item = PcdList[Count]
    658                     ItemNext = PcdList[Count + 1]
    659                     #

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

    661                     #

    662                     if (int(Item.TokenValue, 0) == int(ItemNext.TokenValue, 0)):
    663                         SameTokenValuePcdList = []
    664                         SameTokenValuePcdList.append(Item)
    665                         SameTokenValuePcdList.append(ItemNext)
    666                         RemainPcdListLength = len(PcdList) - Count - 2
    667                         for ValueSameCount in range(RemainPcdListLength):
    668                             if int(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount].TokenValue, 0) == int(Item.TokenValue, 0):
    669                                 SameTokenValuePcdList.append(PcdList[len(PcdList) - RemainPcdListLength + ValueSameCount])
    670                             else:
    671                                 break;
    672                         #

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

    674                         #

    675                         SameTokenValuePcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))
    676                         SameTokenValuePcdListCount = 0
    677                         while (SameTokenValuePcdListCount < len(SameTokenValuePcdList) - 1):
    678                             TemListItem = SameTokenValuePcdList[SameTokenValuePcdListCount]
    679                             TemListItemNext = SameTokenValuePcdList[SameTokenValuePcdListCount + 1]
    680 
    681                             if (TemListItem.TokenSpaceGuidCName == TemListItemNext.TokenSpaceGuidCName) and (TemListItem.TokenCName != TemListItemNext.TokenCName):
    682                                 EdkLogger.error(
    683                                             'build',
    684                                             FORMAT_INVALID,
    685                                             "The TokenValue [%s] of PCD [%s.%s] is conflict with: [%s.%s] in %s"\
    686                                             % (TemListItem.TokenValue, TemListItem.TokenSpaceGuidCName, TemListItem.TokenCName, TemListItemNext.TokenSpaceGuidCName, TemListItemNext.TokenCName, Package),
    687                                             ExtraData=None
    688                                             )
    689                             SameTokenValuePcdListCount += 1
    690                         Count += SameTokenValuePcdListCount
    691                     Count += 1
    692 
    693                 PcdList = Package.Pcds.values()
    694                 PcdList.sort(lambda x, y: cmp("%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName), "%s.%s" % (y.TokenSpaceGuidCName, y.TokenCName)))
    695                 Count = 0
    696                 while (Count < len(PcdList) - 1) :
    697                     Item = PcdList[Count]
    698                     ItemNext = PcdList[Count + 1]
    699                     #

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

    701                     #

    702                     if (Item.TokenSpaceGuidCName == ItemNext.TokenSpaceGuidCName) and (Item.TokenCName == ItemNext.TokenCName) and (int(Item.TokenValue, 0) != int(ItemNext.TokenValue, 0)):
    703                         EdkLogger.error(
    704                                     'build',
    705                                     FORMAT_INVALID,
    706                                     "The TokenValue [%s] of PCD [%s.%s] in %s defined in two places should be same as well."\
    707                                     % (Item.TokenValue, Item.TokenSpaceGuidCName, Item.TokenCName, Package),
    708                                     ExtraData=None
    709                                     )
    710                     Count += 1
    711     ## Generate fds command

    712     def _GenFdsCommand(self):
    713         return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip()
    714 
    715     ## Create makefile for the platform and modules in it

    716     #

    717     #   @param      CreateDepsMakeFile      Flag indicating if the makefile for

    718     #                                       modules will be created as well

    719     #

    720     def CreateMakeFile(self, CreateDepsMakeFile=False):
    721         if CreateDepsMakeFile:
    722             for Pa in self.AutoGenObjectList:
    723                 Pa.CreateMakeFile(CreateDepsMakeFile)
    724 
    725     ## Create autogen code for platform and modules

    726     #

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

    728     #  if CreateModuleCodeFile is set to False.

    729     #

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

    731     #                                       autogen code file or not

    732     #

    733     def CreateCodeFile(self, CreateDepsCodeFile=False):
    734         if not CreateDepsCodeFile:
    735             return
    736         for Pa in self.AutoGenObjectList:
    737             Pa.CreateCodeFile(CreateDepsCodeFile)
    738 
    739     ## Create AsBuilt INF file the platform

    740     #

    741     def CreateAsBuiltInf(self):
    742         return
    743 
    744     Name                = property(_GetName)
    745     Guid                = property(_GetGuid)
    746     Version             = property(_GetVersion)
    747     OutputDir           = property(_GetOutputDir)
    748 
    749     ToolDefinition      = property(_GetToolDefinition)       # toolcode : tool path

    750 
    751     BuildDir            = property(_GetBuildDir)
    752     FvDir               = property(_GetFvDir)
    753     MakeFileDir         = property(_GetMakeFileDir)
    754     BuildCommand        = property(_GetBuildCommand)
    755     GenFdsCommand       = property(_GenFdsCommand)
    756 
    757 ## AutoGen class for platform

    758 #

    759 #  PlatformAutoGen class will process the original information in platform

    760 #  file in order to generate makefile for platform.

    761 #

    762 class PlatformAutoGen(AutoGen):
    763     #

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

    765     # correct PCD database

    766     # 

    767     _DynaPcdList_ = []
    768     _NonDynaPcdList_ = []
    769     
    770     #

    771     # The priority list while override build option 

    772     #

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    789 
    790     ## The real constructor of PlatformAutoGen

    791     #

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

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

    794     #  object of PlatformAutoGen

    795     #

    796     #   @param      Workspace       WorkspaceAutoGen object

    797     #   @param      PlatformFile    Platform file (DSC file)

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

    799     #   @param      Toolchain       Name of tool chain

    800     #   @param      Arch            arch of the platform supports

    801     #

    802     def _Init(self, Workspace, PlatformFile, Target, Toolchain, Arch):
    803         EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen platform [%s] [%s]" % (PlatformFile, Arch))
    804         GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (PlatformFile, Arch, Toolchain, Target)
    805 
    806         self.MetaFile = PlatformFile
    807         self.Workspace = Workspace
    808         self.WorkspaceDir = Workspace.WorkspaceDir
    809         self.ToolChain = Toolchain
    810         self.BuildTarget = Target
    811         self.Arch = Arch
    812         self.SourceDir = PlatformFile.SubDir
    813         self.SourceOverrideDir = None
    814         self.FdTargetList = self.Workspace.FdTargetList
    815         self.FvTargetList = self.Workspace.FvTargetList
    816         self.AllPcdList = []
    817         # get the original module/package/platform objects

    818         self.BuildDatabase = Workspace.BuildDatabase
    819 
    820         # flag indicating if the makefile/C-code file has been created or not

    821         self.IsMakeFileCreated  = False
    822         self.IsCodeFileCreated  = False
    823 
    824         self._Platform   = None
    825         self._Name       = None
    826         self._Guid       = None
    827         self._Version    = None
    828 
    829         self._BuildRule = None
    830         self._SourceDir = None
    831         self._BuildDir = None
    832         self._OutputDir = None
    833         self._FvDir = None
    834         self._MakeFileDir = None
    835         self._FdfFile = None
    836 
    837         self._PcdTokenNumber = None    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber

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

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

    840         self._NonDynamicPcdDict = {}
    841 
    842         self._ToolDefinitions = None
    843         self._ToolDefFile = None          # toolcode : tool path

    844         self._ToolChainFamily = None
    845         self._BuildRuleFamily = None
    846         self._BuildOption = None          # toolcode : option

    847         self._EdkBuildOption = None       # edktoolcode : option

    848         self._EdkIIBuildOption = None     # edkiitoolcode : option

    849         self._PackageList = None
    850         self._ModuleAutoGenList  = None
    851         self._LibraryAutoGenList = None
    852         self._BuildCommand = None
    853         self._AsBuildInfList = []
    854         self._AsBuildModuleList = []
    855         if GlobalData.gFdfParser != None:
    856             self._AsBuildInfList = GlobalData.gFdfParser.Profile.InfList
    857             for Inf in self._AsBuildInfList:
    858                 InfClass = PathClass(NormPath(Inf), GlobalData.gWorkspace, self.Arch)
    859                 M = self.BuildDatabase[InfClass, self.Arch, self.BuildTarget, self.ToolChain]
    860                 if not M.IsSupportedArch:
    861                     continue
    862                 self._AsBuildModuleList.append(InfClass)
    863         # get library/modules for build

    864         self.LibraryBuildDirectoryList = []
    865         self.ModuleBuildDirectoryList = []
    866         return True
    867 
    868     def __repr__(self):
    869         return "%s [%s]" % (self.MetaFile, self.Arch)
    870 
    871     ## Create autogen code for platform and modules

    872     #

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

    874     #  if CreateModuleCodeFile is set to False.

    875     #

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

    877     #                                       autogen code file or not

    878     #

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

    881         if self.IsCodeFileCreated or not CreateModuleCodeFile:
    882             return
    883 
    884         for Ma in self.ModuleAutoGenList:
    885             Ma.CreateCodeFile(True)
    886 
    887         # don't do this twice

    888         self.IsCodeFileCreated = True
    889 
    890     ## Generate Fds Command

    891     def _GenFdsCommand(self):
    892         return self.Workspace.GenFdsCommand
    893 		
    894     ## Create makefile for the platform and mdoules in it

    895     #

    896     #   @param      CreateModuleMakeFile    Flag indicating if the makefile for

    897     #                                       modules will be created as well

    898     #

    899     def CreateMakeFile(self, CreateModuleMakeFile=False):
    900         if CreateModuleMakeFile:
    901             for ModuleFile in self.Platform.Modules:
    902                 Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,
    903                                    self.ToolChain, self.Arch, self.MetaFile)
    904                 Ma.CreateMakeFile(True)
    905                 #Ma.CreateAsBuiltInf()

    906 
    907         # no need to create makefile for the platform more than once

    908         if self.IsMakeFileCreated:
    909             return
    910 
    911         # create library/module build dirs for platform

    912         Makefile = GenMake.PlatformMakefile(self)
    913         self.LibraryBuildDirectoryList = Makefile.GetLibraryBuildDirectoryList()
    914         self.ModuleBuildDirectoryList = Makefile.GetModuleBuildDirectoryList()
    915 
    916         self.IsMakeFileCreated = True
    917 
    918     ## Deal with Shared FixedAtBuild Pcds

    919     #

    920     def CollectFixedAtBuildPcds(self):
    921         for LibAuto in self.LibraryAutoGenList:
    922             FixedAtBuildPcds = {}  
    923             ShareFixedAtBuildPcdsSameValue = {} 
    924             for Module in LibAuto._ReferenceModules:                
    925                 for Pcd in Module.FixedAtBuildPcds + LibAuto.FixedAtBuildPcds:
    926                     key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))  
    927                     if key not in FixedAtBuildPcds:
    928                         ShareFixedAtBuildPcdsSameValue[key] = True
    929                         FixedAtBuildPcds[key] = Pcd.DefaultValue
    930                     else:
    931                         if FixedAtBuildPcds[key] != Pcd.DefaultValue:
    932                             ShareFixedAtBuildPcdsSameValue[key] = False      
    933             for Pcd in LibAuto.FixedAtBuildPcds:
    934                 key = ".".join((Pcd.TokenSpaceGuidCName,Pcd.TokenCName))
    935                 if (Pcd.TokenCName,Pcd.TokenSpaceGuidCName) not in self.NonDynamicPcdDict:
    936                     continue
    937                 else:
    938                     DscPcd = self.NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)]
    939                     if DscPcd.Type != "FixedAtBuild":
    940                         continue
    941                 if key in ShareFixedAtBuildPcdsSameValue and ShareFixedAtBuildPcdsSameValue[key]:                    
    942                     LibAuto.ConstPcd[key] = Pcd.DefaultValue
    943 
    944     ## Collect dynamic PCDs

    945     #

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

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

    948     #

    949     def CollectPlatformDynamicPcds(self):
    950         # for gathering error information

    951         NoDatumTypePcdList = set()
    952         PcdNotInDb = []
    953         self._GuidValue = {}
    954         FdfModuleList = []
    955         for InfName in self._AsBuildInfList:
    956             InfName = mws.join(self.WorkspaceDir, InfName)
    957             FdfModuleList.append(os.path.normpath(InfName))
    958         for F in self.Platform.Modules.keys():
    959             M = ModuleAutoGen(self.Workspace, F, self.BuildTarget, self.ToolChain, self.Arch, self.MetaFile)
    960             #GuidValue.update(M.Guids)

    961             
    962             self.Platform.Modules[F].M = M
    963 
    964             for PcdFromModule in M.ModulePcdList + M.LibraryPcdList:
    965                 # make sure that the "VOID*" kind of datum has MaxDatumSize set

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

    970                 if M.IsBinaryModule == True:
    971                     PcdFromModule.IsFromBinaryInf = True
    972 
    973                 # Check the PCD from DSC or not 

    974                 if (PcdFromModule.TokenCName, PcdFromModule.TokenSpaceGuidCName) in self.Platform.Pcds.keys():
    975                     PcdFromModule.IsFromDsc = True
    976                 else:
    977                     PcdFromModule.IsFromDsc = False
    978                 if PcdFromModule.Type in GenC.gDynamicPcd or PcdFromModule.Type in GenC.gDynamicExPcd:
    979                     if F.Path not in FdfModuleList:
    980                         # If one of the Source built modules listed in the DSC is not listed 

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

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

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

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

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

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

    987                         # modules that are included in the FDF file.

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

    991                             if PcdFromModule not in PcdNotInDb:
    992                                 PcdNotInDb.append(PcdFromModule)
    993                             continue
    994                         # If one of the Source built modules listed in the DSC is not listed in 

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

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

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

    998                         # PCD to the Platform's PCD Database.

    999                         if PcdFromModule.Type in GenC.gDynamicExPcd:
   1000                             if PcdFromModule not in PcdNotInDb:
   1001                                 PcdNotInDb.append(PcdFromModule)
   1002                             continue
   1003                     #

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

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

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

   1007                     # The default Phase is DXE

   1008                     #

   1009                     if M.ModuleType in ["PEIM", "PEI_CORE"]:
   1010                         PcdFromModule.Phase = "PEI"
   1011                     if PcdFromModule not in self._DynaPcdList_:
   1012                         self._DynaPcdList_.append(PcdFromModule)
   1013                     elif PcdFromModule.Phase == 'PEI':
   1014                         # overwrite any the same PCD existing, if Phase is PEI

   1015                         Index = self._DynaPcdList_.index(PcdFromModule)
   1016                         self._DynaPcdList_[Index] = PcdFromModule
   1017                 elif PcdFromModule not in self._NonDynaPcdList_:
   1018                     self._NonDynaPcdList_.append(PcdFromModule)
   1019                 elif PcdFromModule in self._NonDynaPcdList_ and PcdFromModule.IsFromBinaryInf == True:
   1020                     Index = self._NonDynaPcdList_.index(PcdFromModule)
   1021                     if self._NonDynaPcdList_[Index].IsFromBinaryInf == False:
   1022                         #The PCD from Binary INF will override the same one from source INF

   1023                         self._NonDynaPcdList_.remove (self._NonDynaPcdList_[Index])
   1024                         PcdFromModule.Pending = False
   1025                         self._NonDynaPcdList_.append (PcdFromModule)
   1026         # Parse the DynamicEx PCD from the AsBuild INF module list of FDF.

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

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

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

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

   1038                 if not M.IsSupportedArch:
   1039                     continue
   1040                 # Override the module PCD setting by platform setting

   1041                 ModulePcdList = self.ApplyPcdSetting(M, M.Pcds)
   1042                 for PcdFromModule in ModulePcdList:
   1043                     PcdFromModule.IsFromBinaryInf = True
   1044                     PcdFromModule.IsFromDsc = False
   1045                     # Only allow the DynamicEx and Patchable PCD in AsBuild INF

   1046                     if PcdFromModule.Type not in GenC.gDynamicExPcd and PcdFromModule.Type not in TAB_PCDS_PATCHABLE_IN_MODULE:
   1047                         EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
   1048                                         File=self.MetaFile,
   1049                                         ExtraData="\n\tExisted %s PCD %s in:\n\t\t%s\n"
   1050                                         % (PcdFromModule.Type, PcdFromModule.TokenCName, InfName))
   1051                     # make sure that the "VOID*" kind of datum has MaxDatumSize set

   1052                     if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:
   1053                         NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, InfName))
   1054                     if M.ModuleType in ["PEIM", "PEI_CORE"]:
   1055                         PcdFromModule.Phase = "PEI"
   1056                     if PcdFromModule not in self._DynaPcdList_ and PcdFromModule.Type in GenC.gDynamicExPcd:
   1057                         self._DynaPcdList_.append(PcdFromModule)
   1058                     elif PcdFromModule not in self._NonDynaPcdList_ and PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE:
   1059                         self._NonDynaPcdList_.append(PcdFromModule)
   1060                     if PcdFromModule in self._DynaPcdList_ and PcdFromModule.Phase == 'PEI' and PcdFromModule.Type in GenC.gDynamicExPcd:
   1061                         # Overwrite the phase of any the same PCD existing, if Phase is PEI.

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

   1063                         # module & DXE module at a same time.

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

   1065                         # INF file as DynamicEx. 

   1066                         Index = self._DynaPcdList_.index(PcdFromModule)
   1067                         self._DynaPcdList_[Index].Phase = PcdFromModule.Phase
   1068                         self._DynaPcdList_[Index].Type = PcdFromModule.Type
   1069         for PcdFromModule in self._NonDynaPcdList_:
   1070             # If a PCD is not listed in the DSC file, but binary INF files used by 

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

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

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

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

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

   1076             # PcdsPatchableInModule.

   1077             if PcdFromModule not in self._DynaPcdList_:
   1078                 continue
   1079             Index = self._DynaPcdList_.index(PcdFromModule)
   1080             if PcdFromModule.IsFromDsc == False and \
   1081                 PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE and \
   1082                 PcdFromModule.IsFromBinaryInf == True and \
   1083                 self._DynaPcdList_[Index].IsFromBinaryInf == False:
   1084                 Index = self._DynaPcdList_.index(PcdFromModule)
   1085                 self._DynaPcdList_.remove (self._DynaPcdList_[Index])
   1086 
   1087         # print out error information and break the build, if error found

   1088         if len(NoDatumTypePcdList) > 0:
   1089             NoDatumTypePcdListString = "\n\t\t".join(NoDatumTypePcdList)
   1090             EdkLogger.error("build", AUTOGEN_ERROR, "PCD setting error",
   1091                             File=self.MetaFile,
   1092                             ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"
   1093                                       % NoDatumTypePcdListString)
   1094         self._NonDynamicPcdList = self._NonDynaPcdList_
   1095         self._DynamicPcdList = self._DynaPcdList_
   1096         #

   1097         # Sort dynamic PCD list to:

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

   1099         #    try to be put header of dynamicd List

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

   1101         #

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

   1103         #

   1104         UnicodePcdArray = []
   1105         HiiPcdArray     = []
   1106         OtherPcdArray   = []
   1107         VpdPcdDict      = {}
   1108         VpdFile               = VpdInfoFile.VpdInfoFile()
   1109         NeedProcessVpdMapFile = False                    
   1110         
   1111         if (self.Workspace.ArchList[-1] == self.Arch): 
   1112             for Pcd in self._DynamicPcdList:
   1113                 # just pick the a value to determine whether is unicode string type

   1114                 Sku = Pcd.SkuInfoList[Pcd.SkuInfoList.keys()[0]]
   1115                 Sku.VpdOffset = Sku.VpdOffset.strip()
   1116 
   1117                 PcdValue = Sku.DefaultValue
   1118                 if Pcd.DatumType == 'VOID*' and PcdValue.startswith("L"):
   1119                     # if found PCD which datum value is unicode string the insert to left size of UnicodeIndex

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

   1123                     HiiPcdArray.append(Pcd)
   1124                 else:
   1125                     OtherPcdArray.append(Pcd)
   1126                 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
   1127                     VpdPcdDict[(Pcd.TokenCName, Pcd.TokenSpaceGuidCName)] = Pcd
   1128 
   1129             PlatformPcds = self.Platform.Pcds.keys()
   1130             PlatformPcds.sort()
   1131             #

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

   1133             #

   1134             for PcdKey in PlatformPcds:
   1135                 Pcd = self.Platform.Pcds[PcdKey]
   1136                 if Pcd.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD] and \
   1137                    PcdKey in VpdPcdDict:
   1138                     Pcd = VpdPcdDict[PcdKey]
   1139                     for (SkuName,Sku) in Pcd.SkuInfoList.items():
   1140                         Sku.VpdOffset = Sku.VpdOffset.strip()
   1141                         VpdFile.Add(Pcd, Sku.VpdOffset)
   1142                         # if the offset of a VPD is *, then it need to be fixed up by third party tool.

   1143                         if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
   1144                             NeedProcessVpdMapFile = True
   1145                             if self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == '':
   1146                                 EdkLogger.error("Build", FILE_NOT_FOUND, \
   1147                                                 "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
   1148 
   1149 
   1150             #

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

   1152             # An example is PCD for signature usage.

   1153             #            

   1154             for DscPcd in PlatformPcds:
   1155                 DscPcdEntry = self.Platform.Pcds[DscPcd]
   1156                 if DscPcdEntry.Type in [TAB_PCDS_DYNAMIC_VPD, TAB_PCDS_DYNAMIC_EX_VPD]:
   1157                     if not (self.Platform.VpdToolGuid == None or self.Platform.VpdToolGuid == ''):
   1158                         FoundFlag = False
   1159                         for VpdPcd in VpdFile._VpdArray.keys():
   1160                             # This PCD has been referenced by module

   1161                             if (VpdPcd.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \
   1162                                (VpdPcd.TokenCName == DscPcdEntry.TokenCName):
   1163                                     FoundFlag = True
   1164 
   1165                         # Not found, it should be signature

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

   1168                             for (SkuName,Sku) in DscPcdEntry.SkuInfoList.items():
   1169                                 Sku.VpdOffset = Sku.VpdOffset.strip() 
   1170                                 
   1171                                 # Need to iterate DEC pcd information to get the value & datumtype

   1172                                 for eachDec in self.PackageList:
   1173                                     for DecPcd in eachDec.Pcds:
   1174                                         DecPcdEntry = eachDec.Pcds[DecPcd]
   1175                                         if (DecPcdEntry.TokenSpaceGuidCName == DscPcdEntry.TokenSpaceGuidCName) and \
   1176                                            (DecPcdEntry.TokenCName == DscPcdEntry.TokenCName):
   1177                                             # Print warning message to let the developer make a determine.

   1178                                             EdkLogger.warn("build", "Unreferenced vpd pcd used!",
   1179                                                             File=self.MetaFile, \
   1180                                                             ExtraData = "PCD: %s.%s used in the DSC file %s is unreferenced." \
   1181                                                             %(DscPcdEntry.TokenSpaceGuidCName, DscPcdEntry.TokenCName, self.Platform.MetaFile.Path))  
   1182                                                                                   
   1183                                             DscPcdEntry.DatumType    = DecPcdEntry.DatumType
   1184                                             DscPcdEntry.DefaultValue = DecPcdEntry.DefaultValue
   1185                                             DscPcdEntry.TokenValue = DecPcdEntry.TokenValue
   1186                                             DscPcdEntry.TokenSpaceGuidValue = eachDec.Guids[DecPcdEntry.TokenSpaceGuidCName]
   1187                                             # Only fix the value while no value provided in DSC file.

   1188                                             if (Sku.DefaultValue == "" or Sku.DefaultValue==None):
   1189                                                 DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue
   1190                                                                                                                     
   1191                                 if DscPcdEntry not in self._DynamicPcdList:
   1192                                     self._DynamicPcdList.append(DscPcdEntry)
   1193 #                                Sku = DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]]

   1194                                 Sku.VpdOffset = Sku.VpdOffset.strip()
   1195                                 PcdValue = Sku.DefaultValue
   1196                                 VpdFile.Add(DscPcdEntry, Sku.VpdOffset)
   1197                                 if not NeedProcessVpdMapFile and Sku.VpdOffset == "*":
   1198                                     NeedProcessVpdMapFile = True 
   1199                             if DscPcdEntry.DatumType == 'VOID*' and PcdValue.startswith("L"):
   1200                                 UnicodePcdArray.append(DscPcdEntry)
   1201                             elif len(Sku.VariableName) > 0:
   1202                                 HiiPcdArray.append(DscPcdEntry)
   1203                             else:
   1204                                 OtherPcdArray.append(DscPcdEntry)
   1205                                 
   1206                                 # if the offset of a VPD is *, then it need to be fixed up by third party tool.

   1207                                                        
   1208                     
   1209                     
   1210             if (self.Platform.FlashDefinition == None or self.Platform.FlashDefinition == '') and \
   1211                VpdFile.GetCount() != 0:
   1212                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, 
   1213                                 "Fail to get FLASH_DEFINITION definition in DSC file %s which is required when DSC contains VPD PCD." % str(self.Platform.MetaFile))
   1214 
   1215             if VpdFile.GetCount() != 0:
   1216                 DscTimeStamp = self.Platform.MetaFile.TimeStamp
   1217                 FvPath = os.path.join(self.BuildDir, "FV")
   1218                 if not os.path.exists(FvPath):
   1219                     try:
   1220                         os.makedirs(FvPath)
   1221                     except:
   1222                         EdkLogger.error("build", FILE_WRITE_FAILURE, "Fail to create FV folder under %s" % self.BuildDir)
   1223 
   1224 
   1225                 VpdFilePath = os.path.join(FvPath, "%s.txt" % self.Platform.VpdToolGuid)
   1226 
   1227 
   1228                 if not os.path.exists(VpdFilePath) or os.path.getmtime(VpdFilePath) < DscTimeStamp:
   1229                     VpdFile.Write(VpdFilePath)
   1230 
   1231                     # retrieve BPDG tool's path from tool_def.txt according to VPD_TOOL_GUID defined in DSC file.

   1232                     BPDGToolName = None
   1233                     for ToolDef in self.ToolDefinition.values():
   1234                         if ToolDef.has_key("GUID") and ToolDef["GUID"] == self.Platform.VpdToolGuid:
   1235                             if not ToolDef.has_key("PATH"):
   1236                                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE, "PATH attribute was not provided for BPDG guid tool %s in tools_def.txt" % self.Platform.VpdToolGuid)
   1237                             BPDGToolName = ToolDef["PATH"]
   1238                             break
   1239                     # Call third party GUID BPDG tool.

   1240                     if BPDGToolName != None:
   1241                         VpdInfoFile.CallExtenalBPDGTool(BPDGToolName, VpdFilePath)
   1242                     else:
   1243                         EdkLogger.error("Build", FILE_NOT_FOUND, "Fail to find third-party BPDG tool to process VPD PCDs. BPDG Guid tool need to be defined in tools_def.txt and VPD_TOOL_GUID need to be provided in DSC file.")
   1244 
   1245                 # Process VPD map file generated by third party BPDG tool

   1246                 if NeedProcessVpdMapFile:
   1247                     VpdMapFilePath = os.path.join(self.BuildDir, "FV", "%s.map" % self.Platform.VpdToolGuid)
   1248                     if os.path.exists(VpdMapFilePath):
   1249                         VpdFile.Read(VpdMapFilePath)
   1250 
   1251                         # Fixup "*" offset

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

   1254                             i = 0
   1255                             for (SkuName,Sku) in Pcd.SkuInfoList.items():                        
   1256                                 if Sku.VpdOffset == "*":
   1257                                     Sku.VpdOffset = VpdFile.GetOffset(Pcd)[i].strip()
   1258                                 i += 1
   1259                     else:
   1260                         EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)
   1261 
   1262             # Delete the DynamicPcdList At the last time enter into this function 

   1263             del self._DynamicPcdList[:]
   1264         self._DynamicPcdList.extend(UnicodePcdArray)
   1265         self._DynamicPcdList.extend(HiiPcdArray)
   1266         self._DynamicPcdList.extend(OtherPcdArray)
   1267         self.AllPcdList = self._NonDynamicPcdList + self._DynamicPcdList
   1268         
   1269     ## Return the platform build data object

   1270     def _GetPlatform(self):
   1271         if self._Platform == None:
   1272             self._Platform = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
   1273         return self._Platform
   1274 
   1275     ## Return platform name

   1276     def _GetName(self):
   1277         return self.Platform.PlatformName
   1278 
   1279     ## Return the meta file GUID

   1280     def _GetGuid(self):
   1281         return self.Platform.Guid
   1282 
   1283     ## Return the platform version

   1284     def _GetVersion(self):
   1285         return self.Platform.Version
   1286 
   1287     ## Return the FDF file name

   1288     def _GetFdfFile(self):
   1289         if self._FdfFile == None:
   1290             if self.Workspace.FdfFile != "":
   1291                 self._FdfFile= mws.join(self.WorkspaceDir, self.Workspace.FdfFile)
   1292             else:
   1293                 self._FdfFile = ''
   1294         return self._FdfFile
   1295 
   1296     ## Return the build output directory platform specifies

   1297     def _GetOutputDir(self):
   1298         return self.Platform.OutputDirectory
   1299 
   1300     ## Return the directory to store all intermediate and final files built

   1301     def _GetBuildDir(self):
   1302         if self._BuildDir == None:
   1303             if os.path.isabs(self.OutputDir):
   1304                 self._BuildDir = path.join(
   1305                                             path.abspath(self.OutputDir),
   1306                                             self.BuildTarget + "_" + self.ToolChain,
   1307                                             )
   1308             else:
   1309                 self._BuildDir = path.join(
   1310                                             self.WorkspaceDir,
   1311                                             self.OutputDir,
   1312                                             self.BuildTarget + "_" + self.ToolChain,
   1313                                             )
   1314         return self._BuildDir
   1315 
   1316     ## Return directory of platform makefile

   1317     #

   1318     #   @retval     string  Makefile directory

   1319     #

   1320     def _GetMakeFileDir(self):
   1321         if self._MakeFileDir == None:
   1322             self._MakeFileDir = path.join(self.BuildDir, self.Arch)
   1323         return self._MakeFileDir
   1324 
   1325     ## Return build command string

   1326     #

   1327     #   @retval     string  Build command string

   1328     #

   1329     def _GetBuildCommand(self):
   1330         if self._BuildCommand == None:
   1331             self._BuildCommand = []
   1332             if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:
   1333                 self._BuildCommand += SplitOption(self.ToolDefinition["MAKE"]["PATH"])
   1334                 if "FLAGS" in self.ToolDefinition["MAKE"]:
   1335                     NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()
   1336                     if NewOption != '':
   1337                         self._BuildCommand += SplitOption(NewOption)
   1338         return self._BuildCommand
   1339 
   1340     ## Get tool chain definition

   1341     #

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

   1343     #

   1344     def _GetToolDefinition(self):
   1345         if self._ToolDefinitions == None:
   1346             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDictionary
   1347             if TAB_TOD_DEFINES_COMMAND_TYPE not in self.Workspace.ToolDef.ToolsDefTxtDatabase:
   1348                 EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No tools found in configuration",
   1349                                 ExtraData="[%s]" % self.MetaFile)
   1350             self._ToolDefinitions = {}
   1351             DllPathList = set()
   1352             for Def in ToolDefinition:
   1353                 Target, Tag, Arch, Tool, Attr = Def.split("_")
   1354                 if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:
   1355                     continue
   1356 
   1357                 Value = ToolDefinition[Def]
   1358                 # don't record the DLL

   1359                 if Attr == "DLL":
   1360                     DllPathList.add(Value)
   1361                     continue
   1362 
   1363                 if Tool not in self._ToolDefinitions:
   1364                     self._ToolDefinitions[Tool] = {}
   1365                 self._ToolDefinitions[Tool][Attr] = Value
   1366 
   1367             ToolsDef = ''
   1368             MakePath = ''
   1369             if GlobalData.gOptions.SilentMode and "MAKE" in self._ToolDefinitions:
   1370                 if "FLAGS" not in self._ToolDefinitions["MAKE"]:
   1371                     self._ToolDefinitions["MAKE"]["FLAGS"] = ""
   1372                 self._ToolDefinitions["MAKE"]["FLAGS"] += " -s"
   1373             MakeFlags = ''
   1374             for Tool in self._ToolDefinitions:
   1375                 for Attr in self._ToolDefinitions[Tool]:
   1376                     Value = self._ToolDefinitions[Tool][Attr]
   1377                     if Tool in self.BuildOption and Attr in self.BuildOption[Tool]:
   1378                         # check if override is indicated

   1379                         if self.BuildOption[Tool][Attr].startswith('='):
   1380                             Value = self.BuildOption[Tool][Attr][1:]
   1381                         else:
   1382                             Value += " " + self.BuildOption[Tool][Attr]
   1383 
   1384                     if Attr == "PATH":
   1385                         # Don't put MAKE definition in the file

   1386                         if Tool == "MAKE":
   1387                             MakePath = Value
   1388                         else:
   1389                             ToolsDef += "%s = %s\n" % (Tool, Value)
   1390                     elif Attr != "DLL":
   1391                         # Don't put MAKE definition in the file

   1392                         if Tool == "MAKE":
   1393                             if Attr == "FLAGS":
   1394                                 MakeFlags = Value
   1395                         else:
   1396                             ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)
   1397                 ToolsDef += "\n"
   1398 
   1399             SaveFileOnChange(self.ToolDefinitionFile, ToolsDef)
   1400             for DllPath in DllPathList:
   1401                 os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"]
   1402             os.environ["MAKE_FLAGS"] = MakeFlags
   1403 
   1404         return self._ToolDefinitions
   1405 
   1406     ## Return the paths of tools

   1407     def _GetToolDefFile(self):
   1408         if self._ToolDefFile == None:
   1409             self._ToolDefFile = os.path.join(self.MakeFileDir, "TOOLS_DEF." + self.Arch)
   1410         return self._ToolDefFile
   1411 
   1412     ## Retrieve the toolchain family of given toolchain tag. Default to 'MSFT'.

   1413     def _GetToolChainFamily(self):
   1414         if self._ToolChainFamily == None:
   1415             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
   1416             if TAB_TOD_DEFINES_FAMILY not in ToolDefinition \
   1417                or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_FAMILY] \
   1418                or not ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]:
   1419                 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
   1420                                    % self.ToolChain)
   1421                 self._ToolChainFamily = "MSFT"
   1422             else:
   1423                 self._ToolChainFamily = ToolDefinition[TAB_TOD_DEFINES_FAMILY][self.ToolChain]
   1424         return self._ToolChainFamily
   1425 
   1426     def _GetBuildRuleFamily(self):
   1427         if self._BuildRuleFamily == None:
   1428             ToolDefinition = self.Workspace.ToolDef.ToolsDefTxtDatabase
   1429             if TAB_TOD_DEFINES_BUILDRULEFAMILY not in ToolDefinition \
   1430                or self.ToolChain not in ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY] \
   1431                or not ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]:
   1432                 EdkLogger.verbose("No tool chain family found in configuration for %s. Default to MSFT." \
   1433                                    % self.ToolChain)
   1434                 self._BuildRuleFamily = "MSFT"
   1435             else:
   1436                 self._BuildRuleFamily = ToolDefinition[TAB_TOD_DEFINES_BUILDRULEFAMILY][self.ToolChain]
   1437         return self._BuildRuleFamily
   1438 
   1439     ## Return the build options specific for all modules in this platform

   1440     def _GetBuildOptions(self):
   1441         if self._BuildOption == None:
   1442             self._BuildOption = self._ExpandBuildOption(self.Platform.BuildOptions)
   1443         return self._BuildOption
   1444 
   1445     ## Return the build options specific for EDK modules in this platform

   1446     def _GetEdkBuildOptions(self):
   1447         if self._EdkBuildOption == None:
   1448             self._EdkBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDK_NAME)
   1449         return self._EdkBuildOption
   1450 
   1451     ## Return the build options specific for EDKII modules in this platform

   1452     def _GetEdkIIBuildOptions(self):
   1453         if self._EdkIIBuildOption == None:
   1454             self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)
   1455         return self._EdkIIBuildOption
   1456 
   1457     ## Parse build_rule.txt in Conf Directory.

   1458     #

   1459     #   @retval     BuildRule object

   1460     #

   1461     def _GetBuildRule(self):
   1462         if self._BuildRule == None:
   1463             BuildRuleFile = None
   1464             if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:
   1465                 BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
   1466             if BuildRuleFile in [None, '']:
   1467                 BuildRuleFile = gDefaultBuildRuleFile
   1468             self._BuildRule = BuildRule(BuildRuleFile)
   1469             if self._BuildRule._FileVersion == "":
   1470                 self._BuildRule._FileVersion = AutoGenReqBuildRuleVerNum
   1471             else:
   1472                 if self._BuildRule._FileVersion < AutoGenReqBuildRuleVerNum :
   1473                     # If Build Rule's version is less than the version number required by the tools, halting the build.

   1474                     EdkLogger.error("build", AUTOGEN_ERROR,
   1475                                     ExtraData="The version number [%s] of build_rule.txt is less than the version number required by the AutoGen.(the minimum required version number is [%s])"\
   1476                                      % (self._BuildRule._FileVersion, AutoGenReqBuildRuleVerNum))
   1477 
   1478         return self._BuildRule
   1479 
   1480     ## Summarize the packages used by modules in this platform

   1481     def _GetPackageList(self):
   1482         if self._PackageList == None:
   1483             self._PackageList = set()
   1484             for La in self.LibraryAutoGenList:
   1485                 self._PackageList.update(La.DependentPackageList)
   1486             for Ma in self.ModuleAutoGenList:
   1487                 self._PackageList.update(Ma.DependentPackageList)
   1488             #Collect package set information from INF of FDF

   1489             PkgSet = set()
   1490             for ModuleFile in self._AsBuildModuleList:
   1491                 if ModuleFile in self.Platform.Modules:
   1492                     continue
   1493                 ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain]
   1494                 PkgSet.update(ModuleData.Packages)
   1495             self._PackageList = list(self._PackageList) + list (PkgSet)
   1496         return self._PackageList
   1497 
   1498     def _GetNonDynamicPcdDict(self):
   1499         if self._NonDynamicPcdDict:
   1500             return self._NonDynamicPcdDict
   1501         for Pcd in self.NonDynamicPcdList:
   1502             self._NonDynamicPcdDict[(Pcd.TokenCName,Pcd.TokenSpaceGuidCName)] = Pcd
   1503         return self._NonDynamicPcdDict
   1504 
   1505     ## Get list of non-dynamic PCDs

   1506     def _GetNonDynamicPcdList(self):
   1507         if self._NonDynamicPcdList == None:
   1508             self.CollectPlatformDynamicPcds()
   1509         return self._NonDynamicPcdList
   1510 
   1511     ## Get list of dynamic PCDs

   1512     def _GetDynamicPcdList(self):
   1513         if self._DynamicPcdList == None:
   1514             self.CollectPlatformDynamicPcds()
   1515         return self._DynamicPcdList
   1516 
   1517     ## Generate Token Number for all PCD

   1518     def _GetPcdTokenNumbers(self):
   1519         if self._PcdTokenNumber == None:
   1520             self._PcdTokenNumber = sdict()
   1521             TokenNumber = 1
   1522             #

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

   1524             # Such as:

   1525             # 

   1526             # Dynamic PCD:

   1527             # TokenNumber 0 ~ 10

   1528             # DynamicEx PCD:

   1529             # TokeNumber 11 ~ 20

   1530             #

   1531             for Pcd in self.DynamicPcdList:
   1532                 if Pcd.Phase == "PEI":
   1533                     if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
   1534                         EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
   1535                         self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1536                         TokenNumber += 1
   1537 
   1538             for Pcd in self.DynamicPcdList:
   1539                 if Pcd.Phase == "PEI":
   1540                     if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
   1541                         EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
   1542                         self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1543                         TokenNumber += 1
   1544 
   1545             for Pcd in self.DynamicPcdList:
   1546                 if Pcd.Phase == "DXE":
   1547                     if Pcd.Type in ["Dynamic", "DynamicDefault", "DynamicVpd", "DynamicHii"]:
   1548                         EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
   1549                         self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1550                         TokenNumber += 1
   1551 
   1552             for Pcd in self.DynamicPcdList:
   1553                 if Pcd.Phase == "DXE":
   1554                     if Pcd.Type in ["DynamicEx", "DynamicExDefault", "DynamicExVpd", "DynamicExHii"]:
   1555                         EdkLogger.debug(EdkLogger.DEBUG_5, "%s %s (%s) -> %d" % (Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Pcd.Phase, TokenNumber))
   1556                         self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1557                         TokenNumber += 1
   1558 
   1559             for Pcd in self.NonDynamicPcdList:
   1560                 self._PcdTokenNumber[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber
   1561                 TokenNumber += 1
   1562         return self._PcdTokenNumber
   1563 
   1564     ## Summarize ModuleAutoGen objects of all modules/libraries to be built for this platform

   1565     def _GetAutoGenObjectList(self):
   1566         self._ModuleAutoGenList = []
   1567         self._LibraryAutoGenList = []
   1568         for ModuleFile in self.Platform.Modules:
   1569             Ma = ModuleAutoGen(
   1570                     self.Workspace,
   1571                     ModuleFile,
   1572                     self.BuildTarget,
   1573                     self.ToolChain,
   1574                     self.Arch,
   1575                     self.MetaFile
   1576                     )
   1577             if Ma not in self._ModuleAutoGenList:
   1578                 self._ModuleAutoGenList.append(Ma)
   1579             for La in Ma.LibraryAutoGenList:
   1580                 if La not in self._LibraryAutoGenList:
   1581                     self._LibraryAutoGenList.append(La)
   1582                 if Ma not in La._ReferenceModules:
   1583                     La._ReferenceModules.append(Ma)
   1584 
   1585     ## Summarize ModuleAutoGen objects of all modules to be built for this platform

   1586     def _GetModuleAutoGenList(self):
   1587         if self._ModuleAutoGenList == None:
   1588             self._GetAutoGenObjectList()
   1589         return self._ModuleAutoGenList
   1590 
   1591     ## Summarize ModuleAutoGen objects of all libraries to be built for this platform

   1592     def _GetLibraryAutoGenList(self):
   1593         if self._LibraryAutoGenList == None:
   1594             self._GetAutoGenObjectList()
   1595         return self._LibraryAutoGenList
   1596 
   1597     ## Test if a module is supported by the platform

   1598     #

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

   1600     #  by the platform or current configuration

   1601     #

   1602     def ValidModule(self, Module):
   1603         return Module in self.Platform.Modules or Module in self.Platform.LibraryInstances \
   1604             or Module in self._AsBuildModuleList
   1605 
   1606     ## Resolve the library classes in a module to library instances

   1607     #

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

   1609     # instances according to the dependency-ship.

   1610     #

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

   1612     #

   1613     #   @retval library_list    List of library instances sorted

   1614     #

   1615     def ApplyLibraryInstance(self, Module):
   1616         ModuleType = Module.ModuleType
   1617 
   1618         # for overridding library instances with module specific setting

   1619         PlatformModule = self.Platform.Modules[str(Module)]
   1620 
   1621         # add forced library instances (specified under LibraryClasses sections)

   1622         #

   1623         # If a module has a MODULE_TYPE of USER_DEFINED,

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

   1625         #

   1626         if Module.ModuleType != SUP_MODULE_USER_DEFINED:
   1627             for LibraryClass in self.Platform.LibraryClasses.GetKeys():
   1628                 if LibraryClass.startswith("NULL") and self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]:
   1629                     Module.LibraryClasses[LibraryClass] = self.Platform.LibraryClasses[LibraryClass, Module.ModuleType]
   1630 
   1631         # add forced library instances (specified in module overrides)

   1632         for LibraryClass in PlatformModule.LibraryClasses:
   1633             if LibraryClass.startswith("NULL"):
   1634                 Module.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
   1635 
   1636         # EdkII module

   1637         LibraryConsumerList = [Module]
   1638         Constructor         = []
   1639         ConsumedByList      = sdict()
   1640         LibraryInstance     = sdict()
   1641 
   1642         EdkLogger.verbose("")
   1643         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
   1644         while len(LibraryConsumerList) > 0:
   1645             M = LibraryConsumerList.pop()
   1646             for LibraryClassName in M.LibraryClasses:
   1647                 if LibraryClassName not in LibraryInstance:
   1648                     # override library instance for this module

   1649                     if LibraryClassName in PlatformModule.LibraryClasses:
   1650                         LibraryPath = PlatformModule.LibraryClasses[LibraryClassName]
   1651                     else:
   1652                         LibraryPath = self.Platform.LibraryClasses[LibraryClassName, ModuleType]
   1653                     if LibraryPath == None or LibraryPath == "":
   1654                         LibraryPath = M.LibraryClasses[LibraryClassName]
   1655                         if LibraryPath == None or LibraryPath == "":
   1656                             EdkLogger.error("build", RESOURCE_NOT_AVAILABLE,
   1657                                             "Instance of library class [%s] is not found" % LibraryClassName,
   1658                                             File=self.MetaFile,
   1659                                             ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), self.Arch, str(Module)))
   1660 
   1661                     LibraryModule = self.BuildDatabase[LibraryPath, self.Arch, self.BuildTarget, self.ToolChain]
   1662                     # for those forced library instance (NULL library), add a fake library class

   1663                     if LibraryClassName.startswith("NULL"):
   1664                         LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType]))
   1665                     elif LibraryModule.LibraryClass == None \
   1666                          or len(LibraryModule.LibraryClass) == 0 \
   1667                          or (ModuleType != 'USER_DEFINED'
   1668                              and ModuleType not in LibraryModule.LibraryClass[0].SupModList):
   1669                         # only USER_DEFINED can link against any library instance despite of its SupModList

   1670                         EdkLogger.error("build", OPTION_MISSING,
   1671                                         "Module type [%s] is not supported by library instance [%s]" \
   1672                                         % (ModuleType, LibraryPath), File=self.MetaFile,
   1673                                         ExtraData="consumed by [%s]" % str(Module))
   1674 
   1675                     LibraryInstance[LibraryClassName] = LibraryModule
   1676                     LibraryConsumerList.append(LibraryModule)
   1677                     EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule))
   1678                 else:
   1679                     LibraryModule = LibraryInstance[LibraryClassName]
   1680 
   1681                 if LibraryModule == None:
   1682                     continue
   1683 
   1684                 if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor:
   1685                     Constructor.append(LibraryModule)
   1686 
   1687                 if LibraryModule not in ConsumedByList:
   1688                     ConsumedByList[LibraryModule] = []
   1689                 # don't add current module itself to consumer list

   1690                 if M != Module:
   1691                     if M in ConsumedByList[LibraryModule]:
   1692                         continue
   1693                     ConsumedByList[LibraryModule].append(M)
   1694         #

   1695         # Initialize the sorted output list to the empty set

   1696         #

   1697         SortedLibraryList = []
   1698         #

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

   1700         #

   1701         LibraryList = [] #LibraryInstance.values()

   1702         Q = []
   1703         for LibraryClassName in LibraryInstance:
   1704             M = LibraryInstance[LibraryClassName]
   1705             LibraryList.append(M)
   1706             if ConsumedByList[M] == []:
   1707                 Q.append(M)
   1708 
   1709         #

   1710         # start the  DAG algorithm

   1711         #

   1712         while True:
   1713             EdgeRemoved = True
   1714             while Q == [] and EdgeRemoved:
   1715                 EdgeRemoved = False
   1716                 # for each node Item with a Constructor

   1717                 for Item in LibraryList:
   1718                     if Item not in Constructor:
   1719                         continue
   1720                     # for each Node without a constructor with an edge e from Item to Node

   1721                     for Node in ConsumedByList[Item]:
   1722                         if Node in Constructor:
   1723                             continue
   1724                         # remove edge e from the graph if Node has no constructor

   1725                         ConsumedByList[Item].remove(Node)
   1726                         EdgeRemoved = True
   1727                         if ConsumedByList[Item] == []:
   1728                             # insert Item into Q

   1729                             Q.insert(0, Item)
   1730                             break
   1731                     if Q != []:
   1732                         break
   1733             # DAG is done if there's no more incoming edge for all nodes

   1734             if Q == []:
   1735                 break
   1736 
   1737             # remove node from Q

   1738             Node = Q.pop()
   1739             # output Node

   1740             SortedLibraryList.append(Node)
   1741 
   1742             # for each node Item with an edge e from Node to Item do

   1743             for Item in LibraryList:
   1744                 if Node not in ConsumedByList[Item]:
   1745                     continue
   1746                 # remove edge e from the graph

   1747                 ConsumedByList[Item].remove(Node)
   1748 
   1749                 if ConsumedByList[Item] != []:
   1750                     continue
   1751                 # insert Item into Q, if Item has no other incoming edges

   1752                 Q.insert(0, Item)
   1753 
   1754         #

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

   1756         #

   1757         for Item in LibraryList:
   1758             if ConsumedByList[Item] != [] and Item in Constructor and len(Constructor) > 1:
   1759                 ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join([str(L) for L in ConsumedByList[Item]])
   1760                 EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item),
   1761                                 ExtraData=ErrorMessage, File=self.MetaFile)
   1762             if Item not in SortedLibraryList:
   1763                 SortedLibraryList.append(Item)
   1764 
   1765         #

   1766         # Build the list of constructor and destructir names

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

   1768         #

   1769         SortedLibraryList.reverse()
   1770         return SortedLibraryList
   1771 
   1772 
   1773     ## Override PCD setting (type, value, ...)

   1774     #

   1775     #   @param  ToPcd       The PCD to be overrided

   1776     #   @param  FromPcd     The PCD overrideing from

   1777     #

   1778     def _OverridePcd(self, ToPcd, FromPcd, Module=""):
   1779         #

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

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

   1782         # package

   1783         #

   1784         if FromPcd != None:
   1785             if ToPcd.Pending and FromPcd.Type not in [None, '']:
   1786                 ToPcd.Type = FromPcd.Type
   1787             elif (ToPcd.Type not in [None, '']) and (FromPcd.Type not in [None, ''])\
   1788                 and (ToPcd.Type != FromPcd.Type) and (ToPcd.Type in FromPcd.Type):
   1789                 if ToPcd.Type.strip() == "DynamicEx":
   1790                     ToPcd.Type = FromPcd.Type
   1791             elif ToPcd.Type not in [None, ''] and FromPcd.Type not in [None, ''] \
   1792                 and ToPcd.Type != FromPcd.Type:
   1793                 EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type",
   1794                                 ExtraData="%s.%s is defined as [%s] in module %s, but as [%s] in platform."\
   1795                                           % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName,
   1796                                              ToPcd.Type, Module, FromPcd.Type),
   1797                                           File=self.MetaFile)
   1798 
   1799             if FromPcd.MaxDatumSize not in [None, '']:
   1800                 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
   1801             if FromPcd.DefaultValue not in [None, '']:
   1802                 ToPcd.DefaultValue = FromPcd.DefaultValue
   1803             if FromPcd.TokenValue not in [None, '']:
   1804                 ToPcd.TokenValue = FromPcd.TokenValue
   1805             if FromPcd.MaxDatumSize not in [None, '']:
   1806                 ToPcd.MaxDatumSize = FromPcd.MaxDatumSize
   1807             if FromPcd.DatumType not in [None, '']:
   1808                 ToPcd.DatumType = FromPcd.DatumType
   1809             if FromPcd.SkuInfoList not in [None, '', []]:
   1810                 ToPcd.SkuInfoList = FromPcd.SkuInfoList
   1811 
   1812             # check the validation of datum

   1813             IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue)
   1814             if not IsValid:
   1815                 EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile,
   1816                                 ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
   1817             ToPcd.validateranges = FromPcd.validateranges
   1818             ToPcd.validlists = FromPcd.validlists
   1819             ToPcd.expressions = FromPcd.expressions
   1820 
   1821         if ToPcd.DatumType == "VOID*" and ToPcd.MaxDatumSize in ['', None]:
   1822             EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \
   1823                             % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName))
   1824             Value = ToPcd.DefaultValue
   1825             if Value in [None, '']:
   1826                 ToPcd.MaxDatumSize = '1'
   1827             elif Value[0] == 'L':
   1828                 ToPcd.MaxDatumSize = str((len(Value) - 2) * 2)
   1829             elif Value[0] == '{':
   1830                 ToPcd.MaxDatumSize = str(len(Value.split(',')))
   1831             else:
   1832                 ToPcd.MaxDatumSize = str(len(Value) - 1)
   1833 
   1834         # apply default SKU for dynamic PCDS if specified one is not available

   1835         if (ToPcd.Type in PCD_DYNAMIC_TYPE_LIST or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_LIST) \
   1836             and ToPcd.SkuInfoList in [None, {}, '']:
   1837             if self.Platform.SkuName in self.Platform.SkuIds:
   1838                 SkuName = self.Platform.SkuName
   1839             else:
   1840                 SkuName = 'DEFAULT'
   1841             ToPcd.SkuInfoList = {
   1842                 SkuName : SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName], '', '', '', '', '', ToPcd.DefaultValue)
   1843             }
   1844 
   1845     ## Apply PCD setting defined platform to a module

   1846     #

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

   1848     #

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

   1850     #

   1851     def ApplyPcdSetting(self, Module, Pcds):
   1852         # for each PCD in module

   1853         for Name, Guid in Pcds:
   1854             PcdInModule = Pcds[Name, Guid]
   1855             # find out the PCD setting in platform

   1856             if (Name, Guid) in self.Platform.Pcds:
   1857                 PcdInPlatform = self.Platform.Pcds[Name, Guid]
   1858             else:
   1859                 PcdInPlatform = None
   1860             # then override the settings if any

   1861             self._OverridePcd(PcdInModule, PcdInPlatform, Module)
   1862             # resolve the VariableGuid value

   1863             for SkuId in PcdInModule.SkuInfoList:
   1864                 Sku = PcdInModule.SkuInfoList[SkuId]
   1865                 if Sku.VariableGuid == '': continue
   1866                 Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList)
   1867                 if Sku.VariableGuidValue == None:
   1868                     PackageList = "\n\t".join([str(P) for P in self.PackageList])
   1869                     EdkLogger.error(
   1870                                 'build',
   1871                                 RESOURCE_NOT_AVAILABLE,
   1872                                 "Value of GUID [%s] is not found in" % Sku.VariableGuid,
   1873                                 ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \
   1874                                                         % (Guid, Name, str(Module)),
   1875                                 File=self.MetaFile
   1876                                 )
   1877 
   1878         # override PCD settings with module specific setting

   1879         if Module in self.Platform.Modules:
   1880             PlatformModule = self.Platform.Modules[str(Module)]
   1881             for Key  in PlatformModule.Pcds:
   1882                 if Key in Pcds:
   1883                     self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)
   1884         return Pcds.values()
   1885 
   1886     ## Resolve library names to library modules

   1887     #

   1888     # (for Edk.x modules)

   1889     #

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

   1891     #

   1892     #   @retval library_list    The list of library modules

   1893     #

   1894     def ResolveLibraryReference(self, Module):
   1895         EdkLogger.verbose("")
   1896         EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), self.Arch))
   1897         LibraryConsumerList = [Module]
   1898 
   1899         # "CompilerStub" is a must for Edk modules

   1900         if Module.Libraries:
   1901             Module.Libraries.append("CompilerStub")
   1902         LibraryList = []
   1903         while len(LibraryConsumerList) > 0:
   1904             M = LibraryConsumerList.pop()
   1905             for LibraryName in M.Libraries:
   1906                 Library = self.Platform.LibraryClasses[LibraryName, ':dummy:']
   1907                 if Library == None:
   1908                     for Key in self.Platform.LibraryClasses.data.keys():
   1909                         if LibraryName.upper() == Key.upper():
   1910                             Library = self.Platform.LibraryClasses[Key, ':dummy:']
   1911                             break
   1912                     if Library == None:
   1913                         EdkLogger.warn("build", "Library [%s] is not found" % LibraryName, File=str(M),
   1914                             ExtraData="\t%s [%s]" % (str(Module), self.Arch))
   1915                         continue
   1916 
   1917                 if Library not in LibraryList:
   1918                     LibraryList.append(Library)
   1919                     LibraryConsumerList.append(Library)
   1920                     EdkLogger.verbose("\t" + LibraryName + " : " + str(Library) + ' ' + str(type(Library)))
   1921         return LibraryList
   1922 
   1923     ## Calculate the priority value of the build option

   1924     #

   1925     # @param    Key    Build option definition contain: TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE

   1926     #

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

   1928     #

   1929     def CalculatePriorityValue(self, Key):
   1930         Target, ToolChain, Arch, CommandType, Attr = Key.split('_')
   1931         PriorityValue = 0x11111
   1932         if Target == "*":
   1933             PriorityValue &= 0x01111
   1934         if ToolChain == "*":
   1935             PriorityValue &= 0x10111
   1936         if Arch == "*":
   1937             PriorityValue &= 0x11011
   1938         if CommandType == "*":
   1939             PriorityValue &= 0x11101
   1940         if Attr == "*":
   1941             PriorityValue &= 0x11110
   1942 
   1943         return self.PrioList["0x%0.5x" % PriorityValue]
   1944 
   1945 
   1946     ## Expand * in build option key

   1947     #

   1948     #   @param  Options     Options to be expanded

   1949     #

   1950     #   @retval options     Options expanded

   1951     #      

   1952     def _ExpandBuildOption(self, Options, ModuleStyle=None):
   1953         BuildOptions = {}
   1954         FamilyMatch  = False
   1955         FamilyIsNull = True
   1956 
   1957         OverrideList = {}
   1958         #

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

   1960         #

   1961         for Key in Options:
   1962             #

   1963             # Key[0] -- tool family

   1964             # Key[1] -- TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE

   1965             #

   1966             if (Key[0] == self.BuildRuleFamily and
   1967                 (ModuleStyle == None or len(Key) < 3 or (len(Key) > 2 and Key[2] == ModuleStyle))):
   1968                 Target, ToolChain, Arch, CommandType, Attr = Key[1].split('_')
   1969                 if Target == self.BuildTarget or Target == "*":
   1970                     if ToolChain == self.ToolChain or ToolChain == "*":
   1971                         if Arch == self.Arch or Arch == "*":
   1972                             if Options[Key].startswith("="):
   1973                                 if OverrideList.get(Key[1]) != None:
   1974                                     OverrideList.pop(Key[1])
   1975                                 OverrideList[Key[1]] = Options[Key]
   1976         
   1977         #

   1978         # Use the highest priority value. 

   1979         #

   1980         if (len(OverrideList) >= 2):
   1981             KeyList = OverrideList.keys()
   1982             for Index in range(len(KeyList)):
   1983                 NowKey = KeyList[Index]
   1984                 Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_")
   1985                 for Index1 in range(len(KeyList) - Index - 1):
   1986                     NextKey = KeyList[Index1 + Index + 1]
   1987                     #

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

   1989                     #                    

   1990                     Target2, ToolChain2, Arch2, CommandType2, Attr2 = NextKey.split("_")
   1991                     if Target1 == Target2 or Target1 == "*" or Target2 == "*":
   1992                         if ToolChain1 == ToolChain2 or ToolChain1 == "*" or ToolChain2 == "*":
   1993                             if Arch1 == Arch2 or Arch1 == "*" or Arch2 == "*":
   1994                                 if CommandType1 == CommandType2 or CommandType1 == "*" or CommandType2 == "*":
   1995                                     if Attr1 == Attr2 or Attr1 == "*" or Attr2 == "*":
   1996                                         if self.CalculatePriorityValue(NowKey) > self.CalculatePriorityValue(NextKey):
   1997                                             if Options.get((self.BuildRuleFamily, NextKey)) != None:
   1998                                                 Options.pop((self.BuildRuleFamily, NextKey))
   1999                                         else:
   2000                                             if Options.get((self.BuildRuleFamily, NowKey)) != None:
   2001                                                 Options.pop((self.BuildRuleFamily, NowKey))
   2002                                                            
   2003         for Key in Options:
   2004             if ModuleStyle != None and len (Key) > 2:
   2005                 # Check Module style is EDK or EDKII.

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

   2007                 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
   2008                     continue
   2009                 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
   2010                     continue
   2011             Family = Key[0]
   2012             Target, Tag, Arch, Tool, Attr = Key[1].split("_")
   2013             # if tool chain family doesn't match, skip it

   2014             if Tool in self.ToolDefinition and Family != "":
   2015                 FamilyIsNull = False
   2016                 if self.ToolDefinition[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":
   2017                     if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:
   2018                         continue
   2019                 elif Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
   2020                     continue
   2021                 FamilyMatch = True
   2022             # expand any wildcard

   2023             if Target == "*" or Target == self.BuildTarget:
   2024                 if Tag == "*" or Tag == self.ToolChain:
   2025                     if Arch == "*" or Arch == self.Arch:
   2026                         if Tool not in BuildOptions:
   2027                             BuildOptions[Tool] = {}
   2028                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
   2029                             BuildOptions[Tool][Attr] = Options[Key]
   2030                         else:
   2031                             # append options for the same tool

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

   2034         if FamilyMatch or FamilyIsNull:
   2035             return BuildOptions
   2036 
   2037         for Key in Options:
   2038             if ModuleStyle != None and len (Key) > 2:
   2039                 # Check Module style is EDK or EDKII.

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

   2041                 if ModuleStyle == EDK_NAME and Key[2] != EDK_NAME:
   2042                     continue
   2043                 elif ModuleStyle == EDKII_NAME and Key[2] != EDKII_NAME:
   2044                     continue
   2045             Family = Key[0]
   2046             Target, Tag, Arch, Tool, Attr = Key[1].split("_")
   2047             # if tool chain family doesn't match, skip it

   2048             if Tool not in self.ToolDefinition or Family == "":
   2049                 continue
   2050             # option has been added before

   2051             if Family != self.ToolDefinition[Tool][TAB_TOD_DEFINES_FAMILY]:
   2052                 continue
   2053 
   2054             # expand any wildcard

   2055             if Target == "*" or Target == self.BuildTarget:
   2056                 if Tag == "*" or Tag == self.ToolChain:
   2057                     if Arch == "*" or Arch == self.Arch:
   2058                         if Tool not in BuildOptions:
   2059                             BuildOptions[Tool] = {}
   2060                         if Attr != "FLAGS" or Attr not in BuildOptions[Tool] or Options[Key].startswith('='):
   2061                             BuildOptions[Tool][Attr] = Options[Key]
   2062                         else:
   2063                             # append options for the same tool

   2064                             BuildOptions[Tool][Attr] += " " + Options[Key]
   2065         return BuildOptions
   2066 
   2067     ## Append build options in platform to a module

   2068     #

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

   2070     #

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

   2072     #

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

   2075         if Module.AutoGenVersion < 0x00010005:
   2076             PlatformOptions = self.EdkBuildOption
   2077             ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDK_NAME, Module.ModuleType)
   2078         else:
   2079             PlatformOptions = self.EdkIIBuildOption
   2080             ModuleTypeOptions = self.Platform.GetBuildOptionsByModuleType(EDKII_NAME, Module.ModuleType)
   2081         ModuleTypeOptions = self._ExpandBuildOption(ModuleTypeOptions)
   2082         ModuleOptions = self._ExpandBuildOption(Module.BuildOptions)
   2083         if Module in self.Platform.Modules:
   2084             PlatformModule = self.Platform.Modules[str(Module)]
   2085             PlatformModuleOptions = self._ExpandBuildOption(PlatformModule.BuildOptions)
   2086         else:
   2087             PlatformModuleOptions = {}
   2088 
   2089         BuildRuleOrder = None
   2090         for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
   2091             for Tool in Options:
   2092                 for Attr in Options[Tool]:
   2093                     if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
   2094                         BuildRuleOrder = Options[Tool][Attr]
   2095 
   2096         AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() +
   2097                        PlatformModuleOptions.keys() + ModuleTypeOptions.keys() +
   2098                        self.ToolDefinition.keys())
   2099         BuildOptions = {}
   2100         for Tool in AllTools:
   2101             if Tool not in BuildOptions:
   2102                 BuildOptions[Tool] = {}
   2103 
   2104             for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]:
   2105                 if Tool not in Options:
   2106                     continue
   2107                 for Attr in Options[Tool]:
   2108                     Value = Options[Tool][Attr]
   2109                     #

   2110                     # Do not generate it in Makefile

   2111                     #

   2112                     if Attr == TAB_TOD_DEFINES_BUILDRULEORDER:
   2113                         continue
   2114                     if Attr not in BuildOptions[Tool]:
   2115                         BuildOptions[Tool][Attr] = ""
   2116                     # check if override is indicated

   2117                     if Value.startswith('='):
   2118                         ToolPath = Value[1:]
   2119                         ToolPath = mws.handleWsMacro(ToolPath)
   2120                         BuildOptions[Tool][Attr] = ToolPath
   2121                     else:
   2122                         Value = mws.handleWsMacro(Value)
   2123                         BuildOptions[Tool][Attr] += " " + Value
   2124         if Module.AutoGenVersion < 0x00010005 and self.Workspace.UniFlag != None:
   2125             #

   2126             # Override UNI flag only for EDK module.

   2127             #

   2128             if 'BUILD' not in BuildOptions:
   2129                 BuildOptions['BUILD'] = {}
   2130             BuildOptions['BUILD']['FLAGS'] = self.Workspace.UniFlag
   2131         return BuildOptions, BuildRuleOrder
   2132 
   2133     Platform            = property(_GetPlatform)
   2134     Name                = property(_GetName)
   2135     Guid                = property(_GetGuid)
   2136     Version             = property(_GetVersion)
   2137 
   2138     OutputDir           = property(_GetOutputDir)
   2139     BuildDir            = property(_GetBuildDir)
   2140     MakeFileDir         = property(_GetMakeFileDir)
   2141     FdfFile             = property(_GetFdfFile)
   2142 
   2143     PcdTokenNumber      = property(_GetPcdTokenNumbers)    # (TokenCName, TokenSpaceGuidCName) : GeneratedTokenNumber

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

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

   2146     NonDynamicPcdDict   = property(_GetNonDynamicPcdDict)
   2147     PackageList         = property(_GetPackageList)
   2148 
   2149     ToolDefinition      = property(_GetToolDefinition)    # toolcode : tool path

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

   2151     ToolChainFamily     = property(_GetToolChainFamily)
   2152     BuildRuleFamily     = property(_GetBuildRuleFamily)
   2153     BuildOption         = property(_GetBuildOptions)    # toolcode : option

   2154     EdkBuildOption      = property(_GetEdkBuildOptions)   # edktoolcode : option

   2155     EdkIIBuildOption    = property(_GetEdkIIBuildOptions) # edkiitoolcode : option

   2156 
   2157     BuildCommand        = property(_GetBuildCommand)
   2158     BuildRule           = property(_GetBuildRule)
   2159     ModuleAutoGenList   = property(_GetModuleAutoGenList)
   2160     LibraryAutoGenList  = property(_GetLibraryAutoGenList)
   2161     GenFdsCommand       = property(_GenFdsCommand)
   2162 
   2163 ## ModuleAutoGen class

   2164 #

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

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

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

   2168 #

   2169 class ModuleAutoGen(AutoGen):
   2170     ## The real constructor of ModuleAutoGen

   2171     #

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

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

   2174     #  object of ModuleAutoGen

   2175     #

   2176     #   @param      Workspace           EdkIIWorkspaceBuild object

   2177     #   @param      ModuleFile          The path of module file

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

   2179     #   @param      Toolchain           Name of tool chain

   2180     #   @param      Arch                The arch the module supports

   2181     #   @param      PlatformFile        Platform meta-file

   2182     #

   2183     def _Init(self, Workspace, ModuleFile, Target, Toolchain, Arch, PlatformFile):
   2184         EdkLogger.debug(EdkLogger.DEBUG_9, "AutoGen module [%s] [%s]" % (ModuleFile, Arch))
   2185         GlobalData.gProcessingFile = "%s [%s, %s, %s]" % (ModuleFile, Arch, Toolchain, Target)
   2186 
   2187         self.Workspace = Workspace
   2188         self.WorkspaceDir = Workspace.WorkspaceDir
   2189 
   2190         self.MetaFile = ModuleFile
   2191         self.PlatformInfo = PlatformAutoGen(Workspace, PlatformFile, Target, Toolchain, Arch)
   2192         # check if this module is employed by active platform

   2193         if not self.PlatformInfo.ValidModule(self.MetaFile):
   2194             EdkLogger.verbose("Module [%s] for [%s] is not employed by active platform\n" \
   2195                               % (self.MetaFile, Arch))
   2196             return False
   2197 
   2198         self.SourceDir = self.MetaFile.SubDir
   2199         self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir)
   2200 
   2201         self.SourceOverrideDir = None
   2202         # use overrided path defined in DSC file

   2203         if self.MetaFile.Key in GlobalData.gOverrideDir:
   2204             self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key]
   2205 
   2206         self.ToolChain = Toolchain
   2207         self.BuildTarget = Target
   2208         self.Arch = Arch
   2209         self.ToolChainFamily = self.PlatformInfo.ToolChainFamily
   2210         self.BuildRuleFamily = self.PlatformInfo.BuildRuleFamily
   2211 
   2212         self.IsMakeFileCreated = False
   2213         self.IsCodeFileCreated = False
   2214         self.IsAsBuiltInfCreated = False
   2215         self.DepexGenerated = False
   2216 
   2217         self.BuildDatabase = self.Workspace.BuildDatabase
   2218         self.BuildRuleOrder = None
   2219 
   2220         self._Module          = None
   2221         self._Name            = None
   2222         self._Guid            = None
   2223         self._Version         = None
   2224         self._ModuleType      = None
   2225         self._ComponentType   = None
   2226         self._PcdIsDriver     = None
   2227         self._AutoGenVersion  = None
   2228         self._LibraryFlag     = None
   2229         self._CustomMakefile  = None
   2230         self._Macro           = None
   2231 
   2232         self._BuildDir        = None
   2233         self._OutputDir       = None
   2234         self._DebugDir        = None
   2235         self._MakeFileDir     = None
   2236 
   2237         self._IncludePathList = None
   2238         self._AutoGenFileList = None
   2239         self._UnicodeFileList = None
   2240         self._SourceFileList  = None
   2241         self._ObjectFileList  = None
   2242         self._BinaryFileList  = None
   2243 
   2244         self._DependentPackageList    = None
   2245         self._DependentLibraryList    = None
   2246         self._LibraryAutoGenList      = None
   2247         self._DerivedPackageList      = None
   2248         self._ModulePcdList           = None
   2249         self._LibraryPcdList          = None
   2250         self._PcdComments = sdict()
   2251         self._GuidList                = None
   2252         self._GuidsUsedByPcd = None
   2253         self._GuidComments = sdict()
   2254         self._ProtocolList            = None
   2255         self._ProtocolComments = sdict()
   2256         self._PpiList                 = None
   2257         self._PpiComments = sdict()
   2258         self._DepexList               = None
   2259         self._DepexExpressionList     = None
   2260         self._BuildOption             = None
   2261         self._BuildOptionIncPathList  = None
   2262         self._BuildTargets            = None
   2263         self._IntroBuildTargetList    = None
   2264         self._FinalBuildTargetList    = None
   2265         self._FileTypes               = None
   2266         self._BuildRules              = None
   2267         
   2268         ## The Modules referenced to this Library

   2269         #  Only Library has this attribute

   2270         self._ReferenceModules        = []        
   2271         
   2272         ## Store the FixedAtBuild Pcds

   2273         #  

   2274         self._FixedAtBuildPcds         = []
   2275         self.ConstPcd                  = {}
   2276         return True
   2277 
   2278     def __repr__(self):
   2279         return "%s [%s]" % (self.MetaFile, self.Arch)
   2280 
   2281     # Get FixedAtBuild Pcds of this Module

   2282     def _GetFixedAtBuildPcds(self):
   2283         if self._FixedAtBuildPcds:
   2284             return self._FixedAtBuildPcds
   2285         for Pcd in self.ModulePcdList:
   2286             if self.IsLibrary:
   2287                 if not (Pcd.Pending == False and Pcd.Type == "FixedAtBuild"):
   2288                     continue
   2289             elif Pcd.Type != "FixedAtBuild":
   2290                 continue
   2291             if Pcd not in self._FixedAtBuildPcds:
   2292                 self._FixedAtBuildPcds.append(Pcd)
   2293                 
   2294         return self._FixedAtBuildPcds        
   2295 
   2296     def _GetUniqueBaseName(self):
   2297         BaseName = self.Name
   2298         for Module in self.PlatformInfo.ModuleAutoGenList:
   2299             if Module.MetaFile == self.MetaFile:
   2300                 continue
   2301             if Module.Name == self.Name:
   2302                 if uuid.UUID(Module.Guid) == uuid.UUID(self.Guid):
   2303                     EdkLogger.error("build", FILE_DUPLICATED, 'Modules have same BaseName and FILE_GUID:\n'
   2304                                     '  %s\n  %s' % (Module.MetaFile, self.MetaFile))
   2305                 BaseName = '%s_%s' % (self.Name, self.Guid)
   2306         return BaseName
   2307 
   2308     # Macros could be used in build_rule.txt (also Makefile)

   2309     def _GetMacros(self):
   2310         if self._Macro == None:
   2311             self._Macro = sdict()
   2312             self._Macro["WORKSPACE"             ] = self.WorkspaceDir
   2313             self._Macro["MODULE_NAME"           ] = self.Name
   2314             self._Macro["MODULE_NAME_GUID"      ] = self._GetUniqueBaseName()
   2315             self._Macro["MODULE_GUID"           ] = self.Guid
   2316             self._Macro["MODULE_VERSION"        ] = self.Version
   2317             self._Macro["MODULE_TYPE"           ] = self.ModuleType
   2318             self._Macro["MODULE_FILE"           ] = str(self.MetaFile)
   2319             self._Macro["MODULE_FILE_BASE_NAME" ] = self.MetaFile.BaseName
   2320             self._Macro["MODULE_RELATIVE_DIR"   ] = self.SourceDir
   2321             self._Macro["MODULE_DIR"            ] = self.SourceDir
   2322 
   2323             self._Macro["BASE_NAME"             ] = self.Name
   2324 
   2325             self._Macro["ARCH"                  ] = self.Arch
   2326             self._Macro["TOOLCHAIN"             ] = self.ToolChain
   2327             self._Macro["TOOLCHAIN_TAG"         ] = self.ToolChain
   2328             self._Macro["TOOL_CHAIN_TAG"        ] = self.ToolChain
   2329             self._Macro["TARGET"                ] = self.BuildTarget
   2330 
   2331             self._Macro["BUILD_DIR"             ] = self.PlatformInfo.BuildDir
   2332             self._Macro["BIN_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
   2333             self._Macro["LIB_DIR"               ] = os.path.join(self.PlatformInfo.BuildDir, self.Arch)
   2334             self._Macro["MODULE_BUILD_DIR"      ] = self.BuildDir
   2335             self._Macro["OUTPUT_DIR"            ] = self.OutputDir
   2336             self._Macro["DEBUG_DIR"             ] = self.DebugDir
   2337         return self._Macro
   2338 
   2339     ## Return the module build data object

   2340     def _GetModule(self):
   2341         if self._Module == None:
   2342             self._Module = self.Workspace.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain]
   2343         return self._Module
   2344 
   2345     ## Return the module name

   2346     def _GetBaseName(self):
   2347         return self.Module.BaseName
   2348 
   2349     ## Return the module DxsFile if exist

   2350     def _GetDxsFile(self):
   2351         return self.Module.DxsFile
   2352 
   2353     ## Return the module SourceOverridePath

   2354     def _GetSourceOverridePath(self):
   2355         return self.Module.SourceOverridePath
   2356 
   2357     ## Return the module meta-file GUID

   2358     def _GetGuid(self):
   2359         #

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

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

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

   2363         #

   2364         if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path):
   2365             #

   2366             # Length of GUID is 36

   2367             #

   2368             return os.path.basename(self.MetaFile.Path)[:36]
   2369         return self.Module.Guid
   2370 
   2371     ## Return the module version

   2372     def _GetVersion(self):
   2373         return self.Module.Version
   2374 
   2375     ## Return the module type

   2376     def _GetModuleType(self):
   2377         return self.Module.ModuleType
   2378 
   2379     ## Return the component type (for Edk.x style of module)

   2380     def _GetComponentType(self):
   2381         return self.Module.ComponentType
   2382 
   2383     ## Return the build type

   2384     def _GetBuildType(self):
   2385         return self.Module.BuildType
   2386 
   2387     ## Return the PCD_IS_DRIVER setting

   2388     def _GetPcdIsDriver(self):
   2389         return self.Module.PcdIsDriver
   2390 
   2391     ## Return the autogen version, i.e. module meta-file version

   2392     def _GetAutoGenVersion(self):
   2393         return self.Module.AutoGenVersion
   2394 
   2395     ## Check if the module is library or not

   2396     def _IsLibrary(self):
   2397         if self._LibraryFlag == None:
   2398             if self.Module.LibraryClass != None and self.Module.LibraryClass != []:
   2399                 self._LibraryFlag = True
   2400             else:
   2401                 self._LibraryFlag = False
   2402         return self._LibraryFlag
   2403 
   2404     ## Check if the module is binary module or not

   2405     def _IsBinaryModule(self):
   2406         return self.Module.IsBinaryModule
   2407 
   2408     ## Return the directory to store intermediate files of the module

   2409     def _GetBuildDir(self):
   2410         if self._BuildDir == None:
   2411             self._BuildDir = path.join(
   2412                                     self.PlatformInfo.BuildDir,
   2413                                     self.Arch,
   2414                                     self.SourceDir,
   2415                                     self.MetaFile.BaseName
   2416                                     )
   2417             CreateDirectory(self._BuildDir)
   2418         return self._BuildDir
   2419 
   2420     ## Return the directory to store the intermediate object files of the mdoule

   2421     def _GetOutputDir(self):
   2422         if self._OutputDir == None:
   2423             self._OutputDir = path.join(self.BuildDir, "OUTPUT")
   2424             CreateDirectory(self._OutputDir)
   2425         return self._OutputDir
   2426 
   2427     ## Return the directory to store auto-gened source files of the mdoule

   2428     def _GetDebugDir(self):
   2429         if self._DebugDir == None:
   2430             self._DebugDir = path.join(self.BuildDir, "DEBUG")
   2431             CreateDirectory(self._DebugDir)
   2432         return self._DebugDir
   2433 
   2434     ## Return the path of custom file

   2435     def _GetCustomMakefile(self):
   2436         if self._CustomMakefile == None:
   2437             self._CustomMakefile = {}
   2438             for Type in self.Module.CustomMakefile:
   2439                 if Type in gMakeTypeMap:
   2440                     MakeType = gMakeTypeMap[Type]
   2441                 else:
   2442                     MakeType = 'nmake'
   2443                 if self.SourceOverrideDir != None:
   2444                     File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type])
   2445                     if not os.path.exists(File):
   2446                         File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
   2447                 else:
   2448                     File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type])
   2449                 self._CustomMakefile[MakeType] = File
   2450         return self._CustomMakefile
   2451 
   2452     ## Return the directory of the makefile

   2453     #

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

   2455     #

   2456     def _GetMakeFileDir(self):
   2457         return self.BuildDir
   2458 
   2459     ## Return build command string

   2460     #

   2461     #   @retval     string  Build command string

   2462     #

   2463     def _GetBuildCommand(self):
   2464         return self.PlatformInfo.BuildCommand
   2465 
   2466     ## Get object list of all packages the module and its dependent libraries belong to

   2467     #

   2468     #   @retval     list    The list of package object

   2469     #

   2470     def _GetDerivedPackageList(self):
   2471         PackageList = []
   2472         for M in [self.Module] + self.DependentLibraryList:
   2473             for Package in M.Packages:
   2474                 if Package in PackageList:
   2475                     continue
   2476                 PackageList.append(Package)
   2477         return PackageList
   2478     
   2479     ## Get the depex string

   2480     #

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

   2482     def _GetDepexExpresionString(self):
   2483         DepexStr = ''
   2484         DepexList = []
   2485         ## DPX_SOURCE IN Define section.

   2486         if self.Module.DxsFile:
   2487             return DepexStr
   2488         for M in [self.Module] + self.DependentLibraryList:
   2489             Filename = M.MetaFile.Path
   2490             InfObj = InfSectionParser.InfSectionParser(Filename)
   2491             DepexExpresionList = InfObj.GetDepexExpresionList()
   2492             for DepexExpresion in DepexExpresionList:
   2493                 for key in DepexExpresion.keys():
   2494                     Arch, ModuleType = key
   2495                     # the type of build module is USER_DEFINED.

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

   2497                     # and there would be separate DEPEX section tags

   2498                     if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:
   2499                         if (Arch.upper() == self.Arch.upper()) and (ModuleType.upper() != TAB_ARCH_COMMON):
   2500                             DepexList.append({(Arch, ModuleType): DepexExpresion[key][:]})
   2501                     else:
   2502                         if Arch.upper() == TAB_ARCH_COMMON or \
   2503                           (Arch.upper() == self.Arch.upper() and \
   2504                           ModuleType.upper() in [TAB_ARCH_COMMON, self.ModuleType.upper()]):
   2505                             DepexList.append({(Arch, ModuleType): DepexExpresion[key][:]})
   2506         
   2507         #the type of build module is USER_DEFINED.

   2508         if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:
   2509             for Depex in DepexList:
   2510                 for key in Depex.keys():
   2511                     DepexStr += '[Depex.%s.%s]\n' % key
   2512                     DepexStr += '\n'.join(['# '+ val for val in Depex[key]])
   2513                     DepexStr += '\n\n'
   2514             if not DepexStr:
   2515                 return '[Depex.%s]\n' % self.Arch
   2516             return DepexStr
   2517         
   2518         #the type of build module not is USER_DEFINED.

   2519         Count = 0
   2520         for Depex in DepexList:
   2521             Count += 1
   2522             if DepexStr != '':
   2523                 DepexStr += ' AND '
   2524             DepexStr += '('
   2525             for D in Depex.values():
   2526                 DepexStr += ' '.join([val for val in D])
   2527             Index = DepexStr.find('END')
   2528             if Index > -1 and Index == len(DepexStr) - 3:
   2529                 DepexStr = DepexStr[:-3]
   2530             DepexStr = DepexStr.strip()
   2531             DepexStr += ')'
   2532         if Count == 1:
   2533             DepexStr = DepexStr.lstrip('(').rstrip(')').strip()
   2534         if not DepexStr:
   2535             return '[Depex.%s]\n' % self.Arch
   2536         return '[Depex.%s]\n#  ' % self.Arch + DepexStr
   2537     
   2538     ## Merge dependency expression

   2539     #

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

   2541     #

   2542     def _GetDepexTokenList(self):
   2543         if self._DepexList == None:
   2544             self._DepexList = {}
   2545             if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
   2546                 return self._DepexList
   2547 
   2548             self._DepexList[self.ModuleType] = []
   2549 
   2550             for ModuleType in self._DepexList:
   2551                 DepexList = self._DepexList[ModuleType]
   2552                 #

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

   2554                 #

   2555                 for M in [self.Module] + self.DependentLibraryList:
   2556                     Inherited = False
   2557                     for D in M.Depex[self.Arch, ModuleType]:
   2558                         if DepexList != []:
   2559                             DepexList.append('AND')
   2560                         DepexList.append('(')
   2561                         DepexList.extend(D)
   2562                         if DepexList[-1] == 'END':  # no need of a END at this time

   2563                             DepexList.pop()
   2564                         DepexList.append(')')
   2565                         Inherited = True
   2566                     if Inherited:
   2567                         EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexList))
   2568                     if 'BEFORE' in DepexList or 'AFTER' in DepexList:
   2569                         break
   2570                 if len(DepexList) > 0:
   2571                     EdkLogger.verbose('')
   2572         return self._DepexList
   2573 
   2574     ## Merge dependency expression

   2575     #

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

   2577     #

   2578     def _GetDepexExpressionTokenList(self):
   2579         if self._DepexExpressionList == None:
   2580             self._DepexExpressionList = {}
   2581             if self.DxsFile or self.IsLibrary or TAB_DEPENDENCY_EXPRESSION_FILE in self.FileTypes:
   2582                 return self._DepexExpressionList
   2583 
   2584             self._DepexExpressionList[self.ModuleType] = ''
   2585 
   2586             for ModuleType in self._DepexExpressionList:
   2587                 DepexExpressionList = self._DepexExpressionList[ModuleType]
   2588                 #

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

   2590                 #

   2591                 for M in [self.Module] + self.DependentLibraryList:
   2592                     Inherited = False
   2593                     for D in M.DepexExpression[self.Arch, ModuleType]:
   2594                         if DepexExpressionList != '':
   2595                             DepexExpressionList += ' AND '
   2596                         DepexExpressionList += '('
   2597                         DepexExpressionList += D
   2598                         DepexExpressionList = DepexExpressionList.rstrip('END').strip()
   2599                         DepexExpressionList += ')'
   2600                         Inherited = True
   2601                     if Inherited:
   2602                         EdkLogger.verbose("DEPEX[%s] (+%s) = %s" % (self.Name, M.BaseName, DepexExpressionList))
   2603                     if 'BEFORE' in DepexExpressionList or 'AFTER' in DepexExpressionList:
   2604                         break
   2605                 if len(DepexExpressionList) > 0:
   2606                     EdkLogger.verbose('')
   2607                 self._DepexExpressionList[ModuleType] = DepexExpressionList
   2608         return self._DepexExpressionList
   2609 
   2610     ## Return the list of specification version required for the module

   2611     #

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

   2613     #

   2614     def _GetSpecification(self):
   2615         return self.Module.Specification
   2616 
   2617     ## Tool option for the module build

   2618     #

   2619     #   @param      PlatformInfo    The object of PlatformBuildInfo

   2620     #   @retval     dict            The dict containing valid options

   2621     #

   2622     def _GetModuleBuildOption(self):
   2623         if self._BuildOption == None:
   2624             self._BuildOption, self.BuildRuleOrder = self.PlatformInfo.ApplyBuildOption(self.Module)
   2625             if self.BuildRuleOrder:
   2626                 self.BuildRuleOrder = ['.%s' % Ext for Ext in self.BuildRuleOrder.split()]
   2627         return self._BuildOption
   2628 
   2629     ## Get include path list from tool option for the module build

   2630     #

   2631     #   @retval     list            The include path list

   2632     #

   2633     def _GetBuildOptionIncPathList(self):
   2634         if self._BuildOptionIncPathList == None:
   2635             #

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

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

   2638             #

   2639             if self.PlatformInfo.ToolChainFamily in ('MSFT'):
   2640                 gBuildOptIncludePattern = re.compile(r"(?:.*?)/I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)
   2641             elif self.PlatformInfo.ToolChainFamily in ('INTEL', 'GCC', 'RVCT'):
   2642                 gBuildOptIncludePattern = re.compile(r"(?:.*?)-I[ \t]*([^ ]*)", re.MULTILINE | re.DOTALL)
   2643             else:
   2644                 #

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

   2646                 #

   2647                 self._BuildOptionIncPathList = []
   2648                 return self._BuildOptionIncPathList
   2649             
   2650             BuildOptionIncPathList = []
   2651             for Tool in ('CC', 'PP', 'VFRPP', 'ASLPP', 'ASLCC', 'APP', 'ASM'):
   2652                 Attr = 'FLAGS'
   2653                 try:
   2654                     FlagOption = self.BuildOption[Tool][Attr]
   2655                 except KeyError:
   2656                     FlagOption = ''
   2657                 
   2658                 if self.PlatformInfo.ToolChainFamily != 'RVCT':
   2659                     IncPathList = [NormPath(Path, self.Macros) for Path in gBuildOptIncludePattern.findall(FlagOption)]
   2660                 else:
   2661                     #

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

   2663                     #

   2664                     IncPathList = []
   2665                     for Path in gBuildOptIncludePattern.findall(FlagOption):
   2666                         PathList = GetSplitList(Path, TAB_COMMA_SPLIT)
   2667                         IncPathList += [NormPath(PathEntry, self.Macros) for PathEntry in PathList]
   2668 
   2669                 #

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

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

   2672                 #

   2673                 if self.AutoGenVersion >= 0x00010005 and len(IncPathList) > 0:
   2674                     for Path in IncPathList:
   2675                         if (Path not in self.IncludePathList) and (CommonPath([Path, self.MetaFile.Dir]) != self.MetaFile.Dir):
   2676                             ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path, Tool, FlagOption)
   2677                             EdkLogger.error("build",
   2678                                             PARAMETER_INVALID,
   2679                                             ExtraData=ErrMsg,
   2680                                             File=str(self.MetaFile))
   2681 
   2682                 
   2683                 BuildOptionIncPathList += IncPathList
   2684             
   2685             self._BuildOptionIncPathList = BuildOptionIncPathList
   2686         
   2687         return self._BuildOptionIncPathList
   2688         
   2689     ## Return a list of files which can be built from source

   2690     #

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

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

   2693     #

   2694     def _GetSourceFileList(self):
   2695         if self._SourceFileList == None:
   2696             self._SourceFileList = []
   2697             for F in self.Module.Sources:
   2698                 # match tool chain

   2699                 if F.TagName not in ("", "*", self.ToolChain):
   2700                     EdkLogger.debug(EdkLogger.DEBUG_9, "The toolchain [%s] for processing file [%s] is found, "
   2701                                     "but [%s] is needed" % (F.TagName, str(F), self.ToolChain))
   2702                     continue
   2703                 # match tool chain family

   2704                 if F.ToolChainFamily not in ("", "*", self.ToolChainFamily):
   2705                     EdkLogger.debug(
   2706                                 EdkLogger.DEBUG_0,
   2707                                 "The file [%s] must be built by tools of [%s], " \
   2708                                 "but current toolchain family is [%s]" \
   2709                                     % (str(F), F.ToolChainFamily, self.ToolChainFamily))
   2710                     continue
   2711 
   2712                 # add the file path into search path list for file including

   2713                 if F.Dir not in self.IncludePathList and self.AutoGenVersion >= 0x00010005:
   2714                     self.IncludePathList.insert(0, F.Dir)
   2715                 self._SourceFileList.append(F)
   2716                 self._ApplyBuildRule(F, TAB_UNKNOWN_FILE)
   2717         return self._SourceFileList
   2718 
   2719     ## Return the list of unicode files

   2720     def _GetUnicodeFileList(self):
   2721         if self._UnicodeFileList == None:
   2722             if TAB_UNICODE_FILE in self.FileTypes:
   2723                 self._UnicodeFileList = self.FileTypes[TAB_UNICODE_FILE]
   2724             else:
   2725                 self._UnicodeFileList = []
   2726         return self._UnicodeFileList
   2727 
   2728     ## Return a list of files which can be built from binary

   2729     #

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

   2731     #

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

   2733     #

   2734     def _GetBinaryFiles(self):
   2735         if self._BinaryFileList == None:
   2736             self._BinaryFileList = []
   2737             for F in self.Module.Binaries:
   2738                 if F.Target not in ['COMMON', '*'] and F.Target != self.BuildTarget:
   2739                     continue
   2740                 self._BinaryFileList.append(F)
   2741                 self._ApplyBuildRule(F, F.Type)
   2742         return self._BinaryFileList
   2743 
   2744     def _GetBuildRules(self):
   2745         if self._BuildRules == None:
   2746             BuildRules = {}
   2747             BuildRuleDatabase = self.PlatformInfo.BuildRule
   2748             for Type in BuildRuleDatabase.FileTypeList:
   2749                 #first try getting build rule by BuildRuleFamily

   2750                 RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.BuildRuleFamily]
   2751                 if not RuleObject:
   2752                     # build type is always module type, but ...

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

   2756                 if not RuleObject:
   2757                     RuleObject = BuildRuleDatabase[Type, self.BuildType, self.Arch, self.ToolChainFamily]
   2758                     if not RuleObject:
   2759                         # build type is always module type, but ...

   2760                         if self.ModuleType != self.BuildType:
   2761                             RuleObject = BuildRuleDatabase[Type, self.ModuleType, self.Arch, self.ToolChainFamily]
   2762                 if not RuleObject:
   2763                     continue
   2764                 RuleObject = RuleObject.Instantiate(self.Macros)
   2765                 BuildRules[Type] = RuleObject
   2766                 for Ext in RuleObject.SourceFileExtList:
   2767                     BuildRules[Ext] = RuleObject
   2768             self._BuildRules = BuildRules
   2769         return self._BuildRules
   2770 
   2771     def _ApplyBuildRule(self, File, FileType):
   2772         if self._BuildTargets == None:
   2773             self._IntroBuildTargetList = set()
   2774             self._FinalBuildTargetList = set()
   2775             self._BuildTargets = {}
   2776             self._FileTypes = {}
   2777 
   2778         SubDirectory = os.path.join(self.OutputDir, File.SubDir)
   2779         if not os.path.exists(SubDirectory):
   2780             CreateDirectory(SubDirectory)
   2781         LastTarget = None
   2782         RuleChain = []
   2783         SourceList = [File]
   2784         Index = 0
   2785         #

   2786         # Make sure to get build rule order value

   2787         #

   2788         self._GetModuleBuildOption()
   2789 
   2790         while Index < len(SourceList):
   2791             Source = SourceList[Index]
   2792             Index = Index + 1
   2793 
   2794             if Source != File:
   2795                 CreateDirectory(Source.Dir)
   2796 
   2797             if File.IsBinary and File == Source and self._BinaryFileList != None and File in self._BinaryFileList:
   2798                 # Skip all files that are not binary libraries

   2799                 if not self.IsLibrary:
   2800                     continue
   2801                 RuleObject = self.BuildRules[TAB_DEFAULT_BINARY_FILE]
   2802             elif FileType in self.BuildRules:
   2803                 RuleObject = self.BuildRules[FileType]
   2804             elif Source.Ext in self.BuildRules:
   2805                 RuleObject = self.BuildRules[Source.Ext]
   2806             else:
   2807                 # stop at no more rules

   2808                 if LastTarget:
   2809                     self._FinalBuildTargetList.add(LastTarget)
   2810                 break
   2811 
   2812             FileType = RuleObject.SourceFileType
   2813             if FileType not in self._FileTypes:
   2814                 self._FileTypes[FileType] = set()
   2815             self._FileTypes[FileType].add(Source)
   2816 
   2817             # stop at STATIC_LIBRARY for library

   2818             if self.IsLibrary and FileType == TAB_STATIC_LIBRARY:
   2819                 if LastTarget:
   2820                     self._FinalBuildTargetList.add(LastTarget)
   2821                 break
   2822 
   2823             Target = RuleObject.Apply(Source, self.BuildRuleOrder)
   2824             if not Target:
   2825                 if LastTarget:
   2826                     self._FinalBuildTargetList.add(LastTarget)
   2827                 break
   2828             elif not Target.Outputs:
   2829                 # Only do build for target with outputs

   2830                 self._FinalBuildTargetList.add(Target)
   2831 
   2832             if FileType not in self._BuildTargets:
   2833                 self._BuildTargets[FileType] = set()
   2834             self._BuildTargets[FileType].add(Target)
   2835 
   2836             if not Source.IsBinary and Source == File:
   2837                 self._IntroBuildTargetList.add(Target)
   2838 
   2839             # to avoid cyclic rule

   2840             if FileType in RuleChain:
   2841                 break
   2842 
   2843             RuleChain.append(FileType)
   2844             SourceList.extend(Target.Outputs)
   2845             LastTarget = Target
   2846             FileType = TAB_UNKNOWN_FILE
   2847 
   2848     def _GetTargets(self):
   2849         if self._BuildTargets == None:
   2850             self._IntroBuildTargetList = set()
   2851             self._FinalBuildTargetList = set()
   2852             self._BuildTargets = {}
   2853             self._FileTypes = {}
   2854 
   2855         #TRICK: call _GetSourceFileList to apply build rule for source files

   2856         if self.SourceFileList:
   2857             pass
   2858 
   2859         #TRICK: call _GetBinaryFileList to apply build rule for binary files

   2860         if self.BinaryFileList:
   2861             pass
   2862 
   2863         return self._BuildTargets
   2864 
   2865     def _GetIntroTargetList(self):
   2866         self._GetTargets()
   2867         return self._IntroBuildTargetList
   2868 
   2869     def _GetFinalTargetList(self):
   2870         self._GetTargets()
   2871         return self._FinalBuildTargetList
   2872 
   2873     def _GetFileTypes(self):
   2874         self._GetTargets()
   2875         return self._FileTypes
   2876 
   2877     ## Get the list of package object the module depends on

   2878     #

   2879     #   @retval     list    The package object list

   2880     #

   2881     def _GetDependentPackageList(self):
   2882         return self.Module.Packages
   2883 
   2884     ## Return the list of auto-generated code file

   2885     #

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

   2887     #

   2888     def _GetAutoGenFileList(self):
   2889         UniStringAutoGenC = True
   2890         UniStringBinBuffer = StringIO()
   2891         if self.BuildType == 'UEFI_HII':
   2892             UniStringAutoGenC = False
   2893         if self._AutoGenFileList == None:
   2894             self._AutoGenFileList = {}
   2895             AutoGenC = TemplateString()
   2896             AutoGenH = TemplateString()
   2897             StringH = TemplateString()
   2898             GenC.CreateCode(self, AutoGenC, AutoGenH, StringH, UniStringAutoGenC, UniStringBinBuffer)
   2899             #

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

   2901             #

   2902             if str(AutoGenC) != "" and (len(self.Module.LibraryClasses) > 0
   2903                                         or TAB_OBJECT_FILE in self.FileTypes):
   2904                 AutoFile = PathClass(gAutoGenCodeFileName, self.DebugDir)
   2905                 self._AutoGenFileList[AutoFile] = str(AutoGenC)
   2906                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   2907             if str(AutoGenH) != "":
   2908                 AutoFile = PathClass(gAutoGenHeaderFileName, self.DebugDir)
   2909                 self._AutoGenFileList[AutoFile] = str(AutoGenH)
   2910                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   2911             if str(StringH) != "":
   2912                 AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir)
   2913                 self._AutoGenFileList[AutoFile] = str(StringH)
   2914                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   2915             if UniStringBinBuffer != None and UniStringBinBuffer.getvalue() != "":
   2916                 AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir)
   2917                 self._AutoGenFileList[AutoFile] = UniStringBinBuffer.getvalue()
   2918                 AutoFile.IsBinary = True
   2919                 self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE)
   2920             if UniStringBinBuffer != None:
   2921                 UniStringBinBuffer.close()
   2922         return self._AutoGenFileList
   2923 
   2924     ## Return the list of library modules explicitly or implicityly used by this module

   2925     def _GetLibraryList(self):
   2926         if self._DependentLibraryList == None:
   2927             # only merge library classes and PCD for non-library module

   2928             if self.IsLibrary:
   2929                 self._DependentLibraryList = []
   2930             else:
   2931                 if self.AutoGenVersion < 0x00010005:
   2932                     self._DependentLibraryList = self.PlatformInfo.ResolveLibraryReference(self.Module)
   2933                 else:
   2934                     self._DependentLibraryList = self.PlatformInfo.ApplyLibraryInstance(self.Module)
   2935         return self._DependentLibraryList
   2936 
   2937     @staticmethod
   2938     def UpdateComments(Recver, Src):
   2939         for Key in Src:
   2940             if Key not in Recver:
   2941                 Recver[Key] = []
   2942             Recver[Key].extend(Src[Key])
   2943     ## Get the list of PCDs from current module

   2944     #

   2945     #   @retval     list                    The list of PCD

   2946     #

   2947     def _GetModulePcdList(self):
   2948         if self._ModulePcdList == None:
   2949             # apply PCD settings from platform

   2950             self._ModulePcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, self.Module.Pcds)
   2951             self.UpdateComments(self._PcdComments, self.Module.PcdComments)
   2952         return self._ModulePcdList
   2953 
   2954     ## Get the list of PCDs from dependent libraries

   2955     #

   2956     #   @retval     list                    The list of PCD

   2957     #

   2958     def _GetLibraryPcdList(self):
   2959         if self._LibraryPcdList == None:
   2960             Pcds = sdict()
   2961             if not self.IsLibrary:
   2962                 # get PCDs from dependent libraries

   2963                 for Library in self.DependentLibraryList:
   2964                     self.UpdateComments(self._PcdComments, Library.PcdComments)
   2965                     for Key in Library.Pcds:
   2966                         # skip duplicated PCDs

   2967                         if Key in self.Module.Pcds or Key in Pcds:
   2968                             continue
   2969                         Pcds[Key] = copy.copy(Library.Pcds[Key])
   2970                 # apply PCD settings from platform

   2971                 self._LibraryPcdList = self.PlatformInfo.ApplyPcdSetting(self.Module, Pcds)
   2972             else:
   2973                 self._LibraryPcdList = []
   2974         return self._LibraryPcdList
   2975 
   2976     ## Get the GUID value mapping

   2977     #

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

   2979     #

   2980     def _GetGuidList(self):
   2981         if self._GuidList == None:
   2982             self._GuidList = sdict()
   2983             self._GuidList.update(self.Module.Guids)
   2984             for Library in self.DependentLibraryList:
   2985                 self._GuidList.update(Library.Guids)
   2986                 self.UpdateComments(self._GuidComments, Library.GuidComments)
   2987             self.UpdateComments(self._GuidComments, self.Module.GuidComments)
   2988         return self._GuidList
   2989 
   2990     def GetGuidsUsedByPcd(self):
   2991         if self._GuidsUsedByPcd == None:
   2992             self._GuidsUsedByPcd = sdict()
   2993             self._GuidsUsedByPcd.update(self.Module.GetGuidsUsedByPcd())
   2994             for Library in self.DependentLibraryList:
   2995                 self._GuidsUsedByPcd.update(Library.GetGuidsUsedByPcd())
   2996         return self._GuidsUsedByPcd
   2997     ## Get the protocol value mapping

   2998     #

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

   3000     #

   3001     def _GetProtocolList(self):
   3002         if self._ProtocolList == None:
   3003             self._ProtocolList = sdict()
   3004             self._ProtocolList.update(self.Module.Protocols)
   3005             for Library in self.DependentLibraryList:
   3006                 self._ProtocolList.update(Library.Protocols)
   3007                 self.UpdateComments(self._ProtocolComments, Library.ProtocolComments)
   3008             self.UpdateComments(self._ProtocolComments, self.Module.ProtocolComments)
   3009         return self._ProtocolList
   3010 
   3011     ## Get the PPI value mapping

   3012     #

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

   3014     #

   3015     def _GetPpiList(self):
   3016         if self._PpiList == None:
   3017             self._PpiList = sdict()
   3018             self._PpiList.update(self.Module.Ppis)
   3019             for Library in self.DependentLibraryList:
   3020                 self._PpiList.update(Library.Ppis)
   3021                 self.UpdateComments(self._PpiComments, Library.PpiComments)
   3022             self.UpdateComments(self._PpiComments, self.Module.PpiComments)
   3023         return self._PpiList
   3024 
   3025     ## Get the list of include search path

   3026     #

   3027     #   @retval     list                    The list path

   3028     #

   3029     def _GetIncludePathList(self):
   3030         if self._IncludePathList == None:
   3031             self._IncludePathList = []
   3032             if self.AutoGenVersion < 0x00010005:
   3033                 for Inc in self.Module.Includes:
   3034                     if Inc not in self._IncludePathList:
   3035                         self._IncludePathList.append(Inc)
   3036                     # for Edk modules

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

   3041                 self._IncludePathList.append(self.DebugDir)
   3042             else:
   3043                 self._IncludePathList.append(self.MetaFile.Dir)
   3044                 self._IncludePathList.append(self.DebugDir)
   3045 
   3046             for Package in self.Module.Packages:
   3047                 PackageDir = mws.join(self.WorkspaceDir, Package.MetaFile.Dir)
   3048                 if PackageDir not in self._IncludePathList:
   3049                     self._IncludePathList.append(PackageDir)
   3050                 for Inc in Package.Includes:
   3051                     if Inc not in self._IncludePathList:
   3052                         self._IncludePathList.append(str(Inc))
   3053         return self._IncludePathList
   3054 
   3055     ## Get HII EX PCDs which maybe used by VFR

   3056     #

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

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

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

   3060     #

   3061     #  @retval    list    HII EX PCDs

   3062     #

   3063     def _GetPcdsMaybeUsedByVfr(self):
   3064         if not self.SourceFileList:
   3065             return []
   3066 
   3067         NameGuids = []
   3068         for SrcFile in self.SourceFileList:
   3069             if SrcFile.Ext.lower() != '.vfr':
   3070                 continue
   3071             Vfri = os.path.join(self.OutputDir, SrcFile.BaseName + '.i')
   3072             if not os.path.exists(Vfri):
   3073                 continue
   3074             VfriFile = open(Vfri, 'r')
   3075             Content = VfriFile.read()
   3076             VfriFile.close()
   3077             Pos = Content.find('efivarstore')
   3078             while Pos != -1:
   3079                 #

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

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

   3082                 #

   3083                 Index = Pos - 1
   3084                 while Index >= 0 and Content[Index] in ' \t\r\n':
   3085                     Index -= 1
   3086                 if Index >= 0 and Content[Index] != ';':
   3087                     Pos = Content.find('efivarstore', Pos + len('efivarstore'))
   3088                     continue
   3089                 #

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

   3091                 #

   3092                 Name = gEfiVarStoreNamePattern.search(Content, Pos)
   3093                 if not Name:
   3094                     break
   3095                 Guid = gEfiVarStoreGuidPattern.search(Content, Pos)
   3096                 if not Guid:
   3097                     break
   3098                 NameArray = ConvertStringToByteArray('L"' + Name.group(1) + '"')
   3099                 NameGuids.append((NameArray, GuidStructureStringToGuidString(Guid.group(1))))
   3100                 Pos = Content.find('efivarstore', Name.end())
   3101         if not NameGuids:
   3102             return []
   3103         HiiExPcds = []
   3104         for Pcd in self.PlatformInfo.Platform.Pcds.values():
   3105             if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII:
   3106                 continue
   3107             for SkuName in Pcd.SkuInfoList:
   3108                 SkuInfo = Pcd.SkuInfoList[SkuName]
   3109                 Name = ConvertStringToByteArray(SkuInfo.VariableName)
   3110                 Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList)
   3111                 if not Value:
   3112                     continue
   3113                 Guid = GuidStructureStringToGuidString(Value)
   3114                 if (Name, Guid) in NameGuids and Pcd not in HiiExPcds:
   3115                     HiiExPcds.append(Pcd)
   3116                     break
   3117 
   3118         return HiiExPcds
   3119 
   3120     def _GenOffsetBin(self):
   3121         VfrUniBaseName = {}
   3122         for SourceFile in self.Module.Sources:
   3123             if SourceFile.Type.upper() == ".VFR" :
   3124                 #

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

   3126                 #

   3127                 VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")
   3128             if SourceFile.Type.upper() == ".UNI" :
   3129                 #

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

   3131                 #

   3132                 VfrUniBaseName["UniOffsetName"] = (self.Name + "Strings")
   3133 
   3134         if len(VfrUniBaseName) == 0:
   3135             return None
   3136         MapFileName = os.path.join(self.OutputDir, self.Name + ".map")
   3137         EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi")
   3138         VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())
   3139         if not VfrUniOffsetList:
   3140             return None
   3141 
   3142         OutputName = '%sOffset.bin' % self.Name
   3143         UniVfrOffsetFileName    =  os.path.join( self.OutputDir, OutputName)
   3144 
   3145         try:
   3146             fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
   3147         except:
   3148             EdkLogger.error("build", FILE_OPEN_FAILURE, "File open failed for %s" % UniVfrOffsetFileName,None)
   3149 
   3150         # Use a instance of StringIO to cache data

   3151         fStringIO = StringIO('')  
   3152 
   3153         for Item in VfrUniOffsetList:
   3154             if (Item[0].find("Strings") != -1):
   3155                 #

   3156                 # UNI offset in image.

   3157                 # GUID + Offset

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

   3159                 #

   3160                 UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
   3161                 UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
   3162                 fStringIO.write(''.join(UniGuid))            
   3163                 UniValue = pack ('Q', int (Item[1], 16))
   3164                 fStringIO.write (UniValue)
   3165             else:
   3166                 #

   3167                 # VFR binary offset in image.

   3168                 # GUID + Offset

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

   3170                 #

   3171                 VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
   3172                 VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
   3173                 fStringIO.write(''.join(VfrGuid))                   
   3174                 type (Item[1]) 
   3175                 VfrValue = pack ('Q', int (Item[1], 16))
   3176                 fStringIO.write (VfrValue)
   3177         #

   3178         # write data into file.

   3179         #

   3180         try :  
   3181             fInputfile.write (fStringIO.getvalue())
   3182         except:
   3183             EdkLogger.error("build", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the "
   3184                             "file been locked or using by other applications." %UniVfrOffsetFileName,None)
   3185 
   3186         fStringIO.close ()
   3187         fInputfile.close ()
   3188         return OutputName
   3189 
   3190     ## Create AsBuilt INF file the module

   3191     #

   3192     def CreateAsBuiltInf(self):
   3193         if self.IsAsBuiltInfCreated:
   3194             return
   3195             
   3196         # Skip the following code for EDK I inf

   3197         if self.AutoGenVersion < 0x00010005:
   3198             return
   3199             
   3200         # Skip the following code for libraries

   3201         if self.IsLibrary:
   3202             return
   3203             
   3204         # Skip the following code for modules with no source files

   3205         if self.SourceFileList == None or self.SourceFileList == []:
   3206             return
   3207 
   3208         # Skip the following code for modules without any binary files

   3209         if self.BinaryFileList <> None and self.BinaryFileList <> []:
   3210             return
   3211             
   3212         ### TODO: How to handles mixed source and binary modules

   3213 
   3214         # Find all DynamicEx and PatchableInModule PCDs used by this module and dependent libraries

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

   3216         Pcds = []
   3217         PatchablePcds = {}
   3218         Packages = []
   3219         PcdCheckList = []
   3220         PcdTokenSpaceList = []
   3221         for Pcd in self.ModulePcdList + self.LibraryPcdList:
   3222             if Pcd.Type == TAB_PCDS_PATCHABLE_IN_MODULE:
   3223                 PatchablePcds[Pcd.TokenCName] = Pcd
   3224                 PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'PatchableInModule'))
   3225             elif Pcd.Type in GenC.gDynamicExPcd:
   3226                 if Pcd not in Pcds:
   3227                     Pcds += [Pcd]
   3228                     PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'DynamicEx'))
   3229                     PcdCheckList.append((Pcd.TokenCName, Pcd.TokenSpaceGuidCName, 'Dynamic'))
   3230                     PcdTokenSpaceList.append(Pcd.TokenSpaceGuidCName)
   3231         GuidList = sdict()
   3232         GuidList.update(self.GuidList)
   3233         for TokenSpace in self.GetGuidsUsedByPcd():
   3234             # If token space is not referred by patch PCD or Ex PCD, remove the GUID from GUID list

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

   3236             if TokenSpace not in PcdTokenSpaceList and TokenSpace in GuidList:
   3237                 GuidList.pop(TokenSpace)
   3238         CheckList = (GuidList, self.PpiList, self.ProtocolList, PcdCheckList)
   3239         for Package in self.DerivedPackageList:
   3240             if Package in Packages:
   3241                 continue
   3242             BeChecked = (Package.Guids, Package.Ppis, Package.Protocols, Package.Pcds)
   3243             Found = False
   3244             for Index in range(len(BeChecked)):
   3245                 for Item in CheckList[Index]:
   3246                     if Item in BeChecked[Index]:
   3247                         Packages += [Package]
   3248                         Found = True
   3249                         break
   3250                 if Found: break
   3251 
   3252         VfrPcds = self._GetPcdsMaybeUsedByVfr()
   3253         for Pkg in self.PlatformInfo.PackageList:
   3254             if Pkg in Packages:
   3255                 continue
   3256             for VfrPcd in VfrPcds:
   3257                 if ((VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'DynamicEx') in Pkg.Pcds or
   3258                     (VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'Dynamic') in Pkg.Pcds):
   3259                     Packages += [Pkg]
   3260                     break
   3261 
   3262         ModuleType = self.ModuleType
   3263         if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated:
   3264             ModuleType = 'DXE_DRIVER'
   3265 
   3266         DriverType = ''
   3267         if self.PcdIsDriver != '':
   3268             DriverType = self.PcdIsDriver
   3269 
   3270         Guid = self.Guid
   3271         MDefs = self.Module.Defines
   3272 
   3273         AsBuiltInfDict = {
   3274           'module_name'                       : self.Name,
   3275           'module_guid'                       : Guid,
   3276           'module_module_type'                : ModuleType,
   3277           'module_version_string'             : [MDefs['VERSION_STRING']] if 'VERSION_STRING' in MDefs else [],
   3278           'pcd_is_driver_string'              : [],
   3279           'module_uefi_specification_version' : [],
   3280           'module_pi_specification_version'   : [],
   3281           'module_entry_point'                : self.Module.ModuleEntryPointList,
   3282           'module_unload_image'               : self.Module.ModuleUnloadImageList,
   3283           'module_constructor'                : self.Module.ConstructorList,
   3284           'module_destructor'                 : self.Module.DestructorList,
   3285           'module_shadow'                     : [MDefs['SHADOW']] if 'SHADOW' in MDefs else [],
   3286           'module_pci_vendor_id'              : [MDefs['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs else [],
   3287           'module_pci_device_id'              : [MDefs['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs else [],
   3288           'module_pci_class_code'             : [MDefs['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs else [],
   3289           'module_pci_revision'               : [MDefs['PCI_REVISION']] if 'PCI_REVISION' in MDefs else [],
   3290           'module_build_number'               : [MDefs['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs else [],
   3291           'module_spec'                       : [MDefs['SPEC']] if 'SPEC' in MDefs else [],
   3292           'module_uefi_hii_resource_section'  : [MDefs['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs else [],
   3293           'module_uni_file'                   : [MDefs['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs else [],
   3294           'module_arch'                       : self.Arch,
   3295           'package_item'                      : ['%s' % (Package.MetaFile.File.replace('\\', '/')) for Package in Packages],
   3296           'binary_item'                       : [],
   3297           'patchablepcd_item'                 : [],
   3298           'pcd_item'                          : [],
   3299           'protocol_item'                     : [],
   3300           'ppi_item'                          : [],
   3301           'guid_item'                         : [],
   3302           'flags_item'                        : [],
   3303           'libraryclasses_item'               : []
   3304         }
   3305 
   3306         if self.AutoGenVersion > int(gInfSpecVersion, 0):
   3307             AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion
   3308         else:
   3309             AsBuiltInfDict['module_inf_version'] = gInfSpecVersion
   3310 
   3311         if DriverType:
   3312             AsBuiltInfDict['pcd_is_driver_string'] += [DriverType]
   3313 
   3314         if 'UEFI_SPECIFICATION_VERSION' in self.Specification:
   3315           AsBuiltInfDict['module_uefi_specification_version'] += [self.Specification['UEFI_SPECIFICATION_VERSION']]
   3316         if 'PI_SPECIFICATION_VERSION' in self.Specification:
   3317           AsBuiltInfDict['module_pi_specification_version'] += [self.Specification['PI_SPECIFICATION_VERSION']]
   3318 
   3319         OutputDir = self.OutputDir.replace('\\', '/').strip('/')
   3320         if self.ModuleType in ['BASE', 'USER_DEFINED']:
   3321           for Item in self.CodaTargetList:
   3322             File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/')
   3323             if Item.Target.Ext.lower() == '.aml':
   3324               AsBuiltInfDict['binary_item'] += ['ASL|' + File]
   3325             elif Item.Target.Ext.lower() == '.acpi':
   3326               AsBuiltInfDict['binary_item'] += ['ACPI|' + File]
   3327             else:
   3328               AsBuiltInfDict['binary_item'] += ['BIN|' + File]
   3329         else:
   3330           for Item in self.CodaTargetList:
   3331             File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/')
   3332             if Item.Target.Ext.lower() == '.efi':
   3333               AsBuiltInfDict['binary_item'] += ['PE32|' + self.Name + '.efi']
   3334             else:
   3335               AsBuiltInfDict['binary_item'] += ['BIN|' + File]
   3336           if self.DepexGenerated:
   3337             if self.ModuleType in ['PEIM']:
   3338               AsBuiltInfDict['binary_item'] += ['PEI_DEPEX|' + self.Name + '.depex']
   3339             if self.ModuleType in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']:
   3340               AsBuiltInfDict['binary_item'] += ['DXE_DEPEX|' + self.Name + '.depex']
   3341             if self.ModuleType in ['DXE_SMM_DRIVER']:
   3342               AsBuiltInfDict['binary_item'] += ['SMM_DEPEX|' + self.Name + '.depex']
   3343 
   3344         Bin = self._GenOffsetBin()
   3345         if Bin:
   3346             AsBuiltInfDict['binary_item'] += ['BIN|%s' % Bin]
   3347 
   3348         for Root, Dirs, Files in os.walk(OutputDir):
   3349             for File in Files:
   3350                 if File.lower().endswith('.pdb'):
   3351                     AsBuiltInfDict['binary_item'] += ['DISPOSABLE|' + File]
   3352         HeaderComments = self.Module.HeaderComments
   3353         StartPos = 0
   3354         for Index in range(len(HeaderComments)):
   3355             if HeaderComments[Index].find('@BinaryHeader') != -1:
   3356                 HeaderComments[Index] = HeaderComments[Index].replace('@BinaryHeader', '@file')
   3357                 StartPos = Index
   3358                 break
   3359         AsBuiltInfDict['header_comments'] = '\n'.join(HeaderComments[StartPos:]).replace(':#', '://')

   3360         AsBuiltInfDict['tail_comments'] = '\n'.join(self.Module.TailComments)
   3361 
   3362         GenList = [
   3363             (self.ProtocolList, self._ProtocolComments, 'protocol_item'),
   3364             (self.PpiList, self._PpiComments, 'ppi_item'),
   3365             (GuidList, self._GuidComments, 'guid_item')
   3366         ]
   3367         for Item in GenList:
   3368             for CName in Item[0]:
   3369                 Comments = ''
   3370                 if CName in Item[1]:
   3371                     Comments = '\n  '.join(Item[1][CName])
   3372                 Entry = CName
   3373                 if Comments:
   3374                     Entry = Comments + '\n  ' + CName
   3375                 AsBuiltInfDict[Item[2]].append(Entry)
   3376         PatchList = parsePcdInfoFromMapFile(
   3377                             os.path.join(self.OutputDir, self.Name + '.map'),
   3378                             os.path.join(self.OutputDir, self.Name + '.efi')
   3379                         )
   3380         if PatchList:
   3381             for PatchPcd in PatchList:
   3382                 if PatchPcd[0] not in PatchablePcds:
   3383                     continue
   3384                 Pcd = PatchablePcds[PatchPcd[0]]
   3385                 PcdValue = ''
   3386                 if Pcd.DatumType != 'VOID*':
   3387                     HexFormat = '0x%02x'
   3388                     if Pcd.DatumType == 'UINT16':
   3389                         HexFormat = '0x%04x'
   3390                     elif Pcd.DatumType == 'UINT32':
   3391                         HexFormat = '0x%08x'
   3392                     elif Pcd.DatumType == 'UINT64':
   3393                         HexFormat = '0x%016x'
   3394                     PcdValue = HexFormat % int(Pcd.DefaultValue, 0)
   3395                 else:
   3396                     if Pcd.MaxDatumSize == None or Pcd.MaxDatumSize == '':
   3397                         EdkLogger.error("build", AUTOGEN_ERROR,
   3398                                         "Unknown [MaxDatumSize] of PCD [%s.%s]" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
   3399                                         )
   3400                     ArraySize = int(Pcd.MaxDatumSize, 0)
   3401                     PcdValue = Pcd.DefaultValue
   3402                     if PcdValue[0] != '{':
   3403                         Unicode = False
   3404                         if PcdValue[0] == 'L':
   3405                             Unicode = True
   3406                         PcdValue = PcdValue.lstrip('L')
   3407                         PcdValue = eval(PcdValue)
   3408                         NewValue = '{'
   3409                         for Index in range(0, len(PcdValue)):
   3410                             if Unicode:
   3411                                 CharVal = ord(PcdValue[Index])
   3412                                 NewValue = NewValue + '0x%02x' % (CharVal & 0x00FF) + ', ' \
   3413                                         + '0x%02x' % (CharVal >> 8) + ', '
   3414                             else:
   3415                                 NewValue = NewValue + '0x%02x' % (ord(PcdValue[Index]) % 0x100) + ', '
   3416                         Padding = '0x00, '
   3417                         if Unicode:
   3418                             Padding = Padding * 2
   3419                             ArraySize = ArraySize / 2
   3420                         if ArraySize < (len(PcdValue) + 1):
   3421                             EdkLogger.error("build", AUTOGEN_ERROR,
   3422                                             "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
   3423                                             )
   3424                         if ArraySize > len(PcdValue) + 1:
   3425                             NewValue = NewValue + Padding * (ArraySize - len(PcdValue) - 1)
   3426                         PcdValue = NewValue + Padding.strip().rstrip(',') + '}'
   3427                     elif len(PcdValue.split(',')) <= ArraySize:
   3428                         PcdValue = PcdValue.rstrip('}') + ', 0x00' * (ArraySize - len(PcdValue.split(',')))
   3429                         PcdValue += '}'
   3430                     else:
   3431                         EdkLogger.error("build", AUTOGEN_ERROR,
   3432                                         "The maximum size of VOID* type PCD '%s.%s' is less than its actual size occupied." % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName)
   3433                                         )
   3434                 PcdItem = '%s.%s|%s|0x%X' % \
   3435                     (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, PcdValue, PatchPcd[1])
   3436                 PcdComments = ''
   3437                 if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
   3438                     PcdComments = '\n  '.join(self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName])
   3439                 if PcdComments:
   3440                     PcdItem = PcdComments + '\n  ' + PcdItem
   3441                 AsBuiltInfDict['patchablepcd_item'].append(PcdItem)
   3442 
   3443         HiiPcds = []
   3444         for Pcd in Pcds + VfrPcds:
   3445             PcdComments = ''
   3446             PcdCommentList = []
   3447             HiiInfo = ''
   3448             SkuId = ''
   3449             if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII:
   3450                 for SkuName in Pcd.SkuInfoList:
   3451                     SkuInfo = Pcd.SkuInfoList[SkuName]
   3452                     SkuId = SkuInfo.SkuId
   3453                     HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset)
   3454                     break
   3455             if SkuId:
   3456                 #

   3457                 # Don't generate duplicated HII PCD

   3458                 #

   3459                 if (SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in HiiPcds:
   3460                     continue
   3461                 else:
   3462                     HiiPcds.append((SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
   3463             if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
   3464                 PcdCommentList = self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName][:]
   3465             if HiiInfo:
   3466                 UsageIndex = -1
   3467                 UsageStr = ''
   3468                 for Index, Comment in enumerate(PcdCommentList):
   3469                     for Usage in UsageList:
   3470                         if Comment.find(Usage) != -1:
   3471                             UsageStr = Usage
   3472                             UsageIndex = Index
   3473                             break
   3474                 if UsageIndex != -1:
   3475                     PcdCommentList[UsageIndex] = '## %s %s %s' % (UsageStr, HiiInfo, PcdCommentList[UsageIndex].replace(UsageStr, '')) 
   3476                 else:
   3477                     PcdCommentList.append('## UNDEFINED ' + HiiInfo)
   3478             PcdComments = '\n  '.join(PcdCommentList)
   3479             PcdEntry = Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName
   3480             if PcdComments:
   3481                 PcdEntry = PcdComments + '\n  ' + PcdEntry
   3482             AsBuiltInfDict['pcd_item'] += [PcdEntry]
   3483         for Item in self.BuildOption:
   3484           if 'FLAGS' in self.BuildOption[Item]:
   3485             AsBuiltInfDict['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self.ToolChainFamily, self.BuildTarget, self.ToolChain, self.Arch, Item, self.BuildOption[Item]['FLAGS'].strip())]
   3486 
   3487         # Generated LibraryClasses section in comments.

   3488         for Library in self.LibraryAutoGenList:
   3489             AsBuiltInfDict['libraryclasses_item'] += [Library.MetaFile.File.replace('\\', '/')]
   3490         
   3491         # Generated depex expression section in comments.
   3492         AsBuiltInfDict['depexsection_item'] = ''
   3493         DepexExpresion = self._GetDepexExpresionString()
   3494         if DepexExpresion:
   3495             AsBuiltInfDict['depexsection_item'] = DepexExpresion
   3496         
   3497         AsBuiltInf = TemplateString()
   3498         AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict))
   3499         
   3500         SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False)
   3501         
   3502         self.IsAsBuiltInfCreated = True
   3503         
   3504     ## Create makefile for the module and its dependent libraries
   3505     #
   3506     #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of
   3507     #                                       dependent libraries will be created
   3508     #
   3509     def CreateMakeFile(self, CreateLibraryMakeFile=True):
   3510         # Ignore generating makefile when it is a binary module
   3511         if self.IsBinaryModule:
   3512             return
   3513 
   3514         if self.IsMakeFileCreated:
   3515             return
   3516 
   3517         if not self.IsLibrary and CreateLibraryMakeFile:
   3518             for LibraryAutoGen in self.LibraryAutoGenList:
   3519                 LibraryAutoGen.CreateMakeFile()
   3520 
   3521         if len(self.CustomMakefile) == 0:
   3522             Makefile = GenMake.ModuleMakefile(self)
   3523         else:
   3524             Makefile = GenMake.CustomMakefile(self)
   3525         if Makefile.Generate():
   3526             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated makefile for module %s [%s]" %
   3527                             (self.Name, self.Arch))
   3528         else:
   3529             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %
   3530                             (self.Name, self.Arch))
   3531 
   3532         self.IsMakeFileCreated = True
   3533 
   3534     def CopyBinaryFiles(self):
   3535         for File in self.Module.Binaries:
   3536             SrcPath = File.Path
   3537             DstPath = os.path.join(self.OutputDir , os.path.basename(SrcPath))
   3538             CopyLongFilePath(SrcPath, DstPath)
   3539     ## Create autogen code for the module and its dependent libraries
   3540     #
   3541     #   @param      CreateLibraryCodeFile   Flag indicating if or not the code of
   3542     #                                       dependent libraries will be created
   3543     #
   3544     def CreateCodeFile(self, CreateLibraryCodeFile=True):
   3545         if self.IsCodeFileCreated:
   3546             return
   3547 
   3548         # Need to generate PcdDatabase even PcdDriver is binarymodule
   3549         if self.IsBinaryModule and self.PcdIsDriver != '':
   3550             CreatePcdDatabaseCode(self, TemplateString(), TemplateString())
   3551             return
   3552         if self.IsBinaryModule:
   3553             if self.IsLibrary:
   3554                 self.CopyBinaryFiles()
   3555             return
   3556 
   3557         if not self.IsLibrary and CreateLibraryCodeFile:
   3558             for LibraryAutoGen in self.LibraryAutoGenList:
   3559                 LibraryAutoGen.CreateCodeFile()
   3560 
   3561         AutoGenList = []
   3562         IgoredAutoGenList = []
   3563 
   3564         for File in self.AutoGenFileList:
   3565             if GenC.Generate(File.Path, self.AutoGenFileList[File], File.IsBinary):
   3566                 #Ignore Edk AutoGen.c
   3567                 if self.AutoGenVersion < 0x00010005 and File.Name == 'AutoGen.c':
   3568                         continue
   3569 
   3570                 AutoGenList.append(str(File))
   3571             else:
   3572                 IgoredAutoGenList.append(str(File))
   3573 
   3574         # Skip the following code for EDK I inf
   3575         if self.AutoGenVersion < 0x00010005:
   3576             return
   3577 
   3578         for ModuleType in self.DepexList:
   3579             # Ignore empty [depex] section or [depex] section for "USER_DEFINED" module
   3580             if len(self.DepexList[ModuleType]) == 0 or ModuleType == "USER_DEFINED":
   3581                 continue
   3582 
   3583             Dpx = GenDepex.DependencyExpression(self.DepexList[ModuleType], ModuleType, True)
   3584             DpxFile = gAutoGenDepexFileName % {"module_name" : self.Name}
   3585 
   3586             if len(Dpx.PostfixNotation) <> 0:
   3587                 self.DepexGenerated = True
   3588 
   3589             if Dpx.Generate(path.join(self.OutputDir, DpxFile)):
   3590                 AutoGenList.append(str(DpxFile))
   3591             else:
   3592                 IgoredAutoGenList.append(str(DpxFile))
   3593 
   3594         if IgoredAutoGenList == []:
   3595             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] files for module %s [%s]" %
   3596                             (" ".join(AutoGenList), self.Name, self.Arch))
   3597         elif AutoGenList == []:
   3598             EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of [%s] files for module %s [%s]" %
   3599                             (" ".join(IgoredAutoGenList), self.Name, self.Arch))
   3600         else:
   3601             EdkLogger.debug(EdkLogger.DEBUG_9, "Generated [%s] (skipped %s) files for module %s [%s]" %
   3602                             (" ".join(AutoGenList), " ".join(IgoredAutoGenList), self.Name, self.Arch))
   3603 
   3604         self.IsCodeFileCreated = True
   3605         return AutoGenList
   3606 
   3607     ## Summarize the ModuleAutoGen objects of all libraries used by this module
   3608     def _GetLibraryAutoGenList(self):
   3609         if self._LibraryAutoGenList == None:
   3610             self._LibraryAutoGenList = []
   3611             for Library in self.DependentLibraryList:
   3612                 La = ModuleAutoGen(
   3613                         self.Workspace,
   3614                         Library.MetaFile,
   3615                         self.BuildTarget,
   3616                         self.ToolChain,
   3617                         self.Arch,
   3618                         self.PlatformInfo.MetaFile
   3619                         )
   3620                 if La not in self._LibraryAutoGenList:
   3621                     self._LibraryAutoGenList.append(La)
   3622                     for Lib in La.CodaTargetList:
   3623                         self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)
   3624         return self._LibraryAutoGenList
   3625 
   3626     Module          = property(_GetModule)
   3627     Name            = property(_GetBaseName)
   3628     Guid            = property(_GetGuid)
   3629     Version         = property(_GetVersion)
   3630     ModuleType      = property(_GetModuleType)
   3631     ComponentType   = property(_GetComponentType)
   3632     BuildType       = property(_GetBuildType)
   3633     PcdIsDriver     = property(_GetPcdIsDriver)
   3634     AutoGenVersion  = property(_GetAutoGenVersion)
   3635     Macros          = property(_GetMacros)
   3636     Specification   = property(_GetSpecification)
   3637 
   3638     IsLibrary       = property(_IsLibrary)
   3639     IsBinaryModule  = property(_IsBinaryModule)
   3640     BuildDir        = property(_GetBuildDir)
   3641     OutputDir       = property(_GetOutputDir)
   3642     DebugDir        = property(_GetDebugDir)
   3643     MakeFileDir     = property(_GetMakeFileDir)
   3644     CustomMakefile  = property(_GetCustomMakefile)
   3645 
   3646     IncludePathList = property(_GetIncludePathList)
   3647     AutoGenFileList = property(_GetAutoGenFileList)
   3648     UnicodeFileList = property(_GetUnicodeFileList)
   3649     SourceFileList  = property(_GetSourceFileList)
   3650     BinaryFileList  = property(_GetBinaryFiles) # FileType : [File List]
   3651     Targets         = property(_GetTargets)
   3652     IntroTargetList = property(_GetIntroTargetList)
   3653     CodaTargetList  = property(_GetFinalTargetList)
   3654     FileTypes       = property(_GetFileTypes)
   3655     BuildRules      = property(_GetBuildRules)
   3656 
   3657     DependentPackageList    = property(_GetDependentPackageList)
   3658     DependentLibraryList    = property(_GetLibraryList)
   3659     LibraryAutoGenList      = property(_GetLibraryAutoGenList)
   3660     DerivedPackageList      = property(_GetDerivedPackageList)
   3661 
   3662     ModulePcdList           = property(_GetModulePcdList)
   3663     LibraryPcdList          = property(_GetLibraryPcdList)
   3664     GuidList                = property(_GetGuidList)
   3665     ProtocolList            = property(_GetProtocolList)
   3666     PpiList                 = property(_GetPpiList)
   3667     DepexList               = property(_GetDepexTokenList)
   3668     DxsFile                 = property(_GetDxsFile)
   3669     DepexExpressionList     = property(_GetDepexExpressionTokenList)
   3670     BuildOption             = property(_GetModuleBuildOption)
   3671     BuildOptionIncPathList  = property(_GetBuildOptionIncPathList)
   3672     BuildCommand            = property(_GetBuildCommand)
   3673     
   3674     FixedAtBuildPcds         = property(_GetFixedAtBuildPcds)
   3675 
   3676 # This acts like the main() function for the script, unless it is 'import'ed into another script.
   3677 if __name__ == '__main__':
   3678     pass
   3679 
   3680