X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FWorkspace%2FWorkspaceDatabase.py;h=06867219b71191ef5d6d2fbeb80c2d448d9f386a;hb=dc4c770763d05297c7de6893a1e34b76499d0b09;hp=9d53fa8e689fff55f6dea41e89ed136dad37bda4;hpb=08dd311f5dc735c595d39faf2e6f7e2810bb79a9;p=mirror_edk2.git
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index 9d53fa8e68..06867219b7 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -1,7 +1,8 @@
## @file
# This file is used to create a database used by build tool
#
-# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
+# Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.
+# (C) Copyright 2016 Hewlett Packard Enterprise Development LP
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@@ -15,13 +16,13 @@
# Import Modules
#
import sqlite3
-import os
-import os.path
+import Common.LongFilePathOs as os
import pickle
import uuid
import Common.EdkLogger as EdkLogger
import Common.GlobalData as GlobalData
+from Common.MultipleWorkspace import MultipleWorkspace as mws
from Common.String import *
from Common.DataType import *
@@ -34,6 +35,13 @@ from MetaDataTable import *
from MetaFileTable import *
from MetaFileParser import *
from BuildClassObject import *
+from WorkspaceCommon import GetDeclaredPcd
+from Common.Misc import AnalyzeDscPcd
+from Common.Misc import ProcessDuplicatedInf
+import re
+from Common.Parsing import IsValidWord
+from Common.VariableAttributes import VariableAttributes
+import Common.GlobalData as GlobalData
## Platform build information from DSC file
#
@@ -68,12 +76,14 @@ class DscBuildData(PlatformBuildClassObject):
#TAB_DSC_DEFINES_OUTPUT_DIRECTORY : "_OutputDirectory",
#TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES : "_SupArchList",
#TAB_DSC_DEFINES_BUILD_TARGETS : "_BuildTargets",
- #TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
+ TAB_DSC_DEFINES_SKUID_IDENTIFIER : "_SkuName",
#TAB_DSC_DEFINES_FLASH_DEFINITION : "_FlashDefinition",
TAB_DSC_DEFINES_BUILD_NUMBER : "_BuildNumber",
TAB_DSC_DEFINES_MAKEFILE_NAME : "_MakefileName",
TAB_DSC_DEFINES_BS_BASE_ADDRESS : "_BsBaseAddress",
TAB_DSC_DEFINES_RT_BASE_ADDRESS : "_RtBaseAddress",
+ #TAB_DSC_DEFINES_RFC_LANGUAGES : "_RFCLanguages",
+ #TAB_DSC_DEFINES_ISO_LANGUAGES : "_ISOLanguages",
}
# used to compose dummy library class name for those forced library instances
@@ -90,20 +100,15 @@ class DscBuildData(PlatformBuildClassObject):
# @param Platform (not used for DscBuildData)
# @param Macros Macros used for replacement in DSC file
#
- def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):
+ def __init__(self, FilePath, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):
self.MetaFile = FilePath
self._RawData = RawData
self._Bdb = BuildDataBase
self._Arch = Arch
- self._Macros = Macros
+ self._Target = Target
+ self._Toolchain = Toolchain
self._Clear()
- RecordList = self._RawData[MODEL_META_DATA_DEFINE, self._Arch]
- for Record in RecordList:
- GlobalData.gEdkGlobal[Record[0]] = Record[1]
-
- RecordList = self._RawData[MODEL_META_DATA_GLOBAL_DEFINE, self._Arch]
- for Record in RecordList:
- GlobalData.gGlobalDefines[Record[0]] = Record[1]
+ self._HandleOverridePath()
## XXX[key] = value
def __setitem__(self, key, value):
@@ -128,7 +133,13 @@ class DscBuildData(PlatformBuildClassObject):
self._SupArchList = None
self._BuildTargets = None
self._SkuName = None
+ self._SkuIdentifier = None
+ self._AvilableSkuIds = None
+ self._PcdInfoFlag = None
+ self._VarCheckFlag = None
self._FlashDefinition = None
+ self._Prebuild = None
+ self._Postbuild = None
self._BuildNumber = None
self._MakefileName = None
self._BsBaseAddress = None
@@ -138,9 +149,44 @@ class DscBuildData(PlatformBuildClassObject):
self._LibraryInstances = None
self._LibraryClasses = None
self._Pcds = None
+ self._DecPcds = None
self._BuildOptions = None
+ self._ModuleTypeOptions = None
self._LoadFixAddress = None
+ self._RFCLanguages = None
+ self._ISOLanguages = None
self._VpdToolGuid = None
+ self.__Macros = None
+
+
+ ## handle Override Path of Module
+ def _HandleOverridePath(self):
+ RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ for Record in RecordList:
+ ModuleId = Record[5]
+ LineNo = Record[6]
+ ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)
+ RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
+ if RecordList != []:
+ SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))
+
+ # Check if the source override path exists
+ if not os.path.isdir(SourceOverridePath):
+ EdkLogger.error('build', FILE_NOT_FOUND, Message='Source override path does not exist:', File=self.MetaFile, ExtraData=SourceOverridePath, Line=LineNo)
+
+ #Add to GlobalData Variables
+ GlobalData.gOverrideDir[ModuleFile.Key] = SourceOverridePath
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ self.__Macros.update(GlobalData.gPlatformDefines)
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ self.__Macros.update(GlobalData.gCommandLineDefines)
+ return self.__Macros
## Get architecture
def _GetArch(self):
@@ -168,42 +214,97 @@ class DscBuildData(PlatformBuildClassObject):
def _GetHeaderInfo(self):
RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
for Record in RecordList:
- Name = Record[0]
+ Name = Record[1]
# items defined _PROPERTY_ don't need additional processing
- if Name in self:
- self[Name] = Record[1]
+
# some special items in [Defines] section need special treatment
- elif Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
- self._OutputDirectory = NormPath(Record[1], self._Macros)
+ if Name == TAB_DSC_DEFINES_OUTPUT_DIRECTORY:
+ self._OutputDirectory = NormPath(Record[2], self._Macros)
if ' ' in self._OutputDirectory:
EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "No space is allowed in OUTPUT_DIRECTORY",
File=self.MetaFile, Line=Record[-1],
ExtraData=self._OutputDirectory)
elif Name == TAB_DSC_DEFINES_FLASH_DEFINITION:
- self._FlashDefinition = PathClass(NormPath(Record[1], self._Macros), GlobalData.gWorkspace)
+ self._FlashDefinition = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)
ErrorCode, ErrorInfo = self._FlashDefinition.Validate('.fdf')
if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],
ExtraData=ErrorInfo)
+ elif Name == TAB_DSC_PREBUILD:
+ PrebuildValue = Record[2]
+ if Record[2][0] == '"':
+ if Record[2][-1] != '"':
+ EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_PREBUILD,
+ File=self.MetaFile, Line=Record[-1])
+ PrebuildValue = Record[2][1:-1]
+ self._Prebuild = PathClass(NormPath(PrebuildValue, self._Macros), GlobalData.gWorkspace)
+ elif Name == TAB_DSC_POSTBUILD:
+ PostbuildValue = Record[2]
+ if Record[2][0] == '"':
+ if Record[2][-1] != '"':
+ EdkLogger.error('build', FORMAT_INVALID, 'Missing double quotes in the end of %s statement.' % TAB_DSC_POSTBUILD,
+ File=self.MetaFile, Line=Record[-1])
+ PostbuildValue = Record[2][1:-1]
+ self._Postbuild = PathClass(NormPath(PostbuildValue, self._Macros), GlobalData.gWorkspace)
elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:
- self._SupArchList = GetSplitValueList(Record[1], TAB_VALUE_SPLIT)
+ self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)
elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:
- self._BuildTargets = GetSplitValueList(Record[1])
+ self._BuildTargets = GetSplitValueList(Record[2])
elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER:
if self._SkuName == None:
- self._SkuName = Record[1]
+ self._SkuName = Record[2]
+ self._SkuIdentifier = Record[2]
+ self._AvilableSkuIds = Record[2]
+ elif Name == TAB_DSC_DEFINES_PCD_INFO_GENERATION:
+ self._PcdInfoFlag = Record[2]
+ elif Name == TAB_DSC_DEFINES_PCD_VAR_CHECK_GENERATION:
+ self._VarCheckFlag = Record[2]
elif Name == TAB_FIX_LOAD_TOP_MEMORY_ADDRESS:
- self._LoadFixAddress = Record[1]
+ try:
+ self._LoadFixAddress = int (Record[2], 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (Record[2]))
+ elif Name == TAB_DSC_DEFINES_RFC_LANGUAGES:
+ if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for RFC_LANGUAGES must have double quotes around it, for example: RFC_LANGUAGES = "en-us;zh-hans"',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageCodes = Record[2][1:-1]
+ if not LanguageCodes:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more RFC4646 format language code must be provided for RFC_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageList = GetSplitValueList(LanguageCodes, TAB_SEMI_COLON_SPLIT)
+ # check whether there is empty entries in the list
+ if None in LanguageList:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more empty language code is in RFC_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ self._RFCLanguages = LanguageList
+ elif Name == TAB_DSC_DEFINES_ISO_LANGUAGES:
+ if not Record[2] or Record[2][0] != '"' or Record[2][-1] != '"' or len(Record[2]) == 1:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'language code for ISO_LANGUAGES must have double quotes around it, for example: ISO_LANGUAGES = "engchn"',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageCodes = Record[2][1:-1]
+ if not LanguageCodes:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'one or more ISO639-2 format language code must be provided for ISO_LANGUAGES statement',
+ File=self.MetaFile, Line=Record[-1])
+ if len(LanguageCodes)%3:
+ EdkLogger.error('build', FORMAT_NOT_SUPPORTED, 'bad ISO639-2 format for ISO_LANGUAGES',
+ File=self.MetaFile, Line=Record[-1])
+ LanguageList = []
+ for i in range(0, len(LanguageCodes), 3):
+ LanguageList.append(LanguageCodes[i:i+3])
+ self._ISOLanguages = LanguageList
elif Name == TAB_DSC_DEFINES_VPD_TOOL_GUID:
#
# try to convert GUID to a real UUID value to see whether the GUID is format
# for VPD_TOOL_GUID is correct.
#
try:
- uuid.UUID(Record[1])
+ uuid.UUID(Record[2])
except:
EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile)
- self._VpdToolGuid = Record[1]
+ self._VpdToolGuid = Record[2]
+ elif Name in self:
+ self[Name] = Record[2]
# set _Header to non-None in order to avoid database re-querying
self._Header = 'DUMMY'
@@ -222,7 +323,7 @@ class DscBuildData(PlatformBuildClassObject):
if self._Header == None:
self._GetHeaderInfo()
if self._Guid == None:
- EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No FILE_GUID", File=self.MetaFile)
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile)
return self._Guid
## Retrieve platform version
@@ -231,7 +332,7 @@ class DscBuildData(PlatformBuildClassObject):
if self._Header == None:
self._GetHeaderInfo()
if self._Version == None:
- self._Version = ''
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile)
return self._Version
## Retrieve platform description file version
@@ -240,7 +341,7 @@ class DscBuildData(PlatformBuildClassObject):
if self._Header == None:
self._GetHeaderInfo()
if self._DscSpecification == None:
- self._DscSpecification = ''
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile)
return self._DscSpecification
## Retrieve OUTPUT_DIRECTORY
@@ -258,7 +359,7 @@ class DscBuildData(PlatformBuildClassObject):
if self._Header == None:
self._GetHeaderInfo()
if self._SupArchList == None:
- self._SupArchList = ARCH_LIST
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile)
return self._SupArchList
## Retrieve BUILD_TARGETS
@@ -267,24 +368,47 @@ class DscBuildData(PlatformBuildClassObject):
if self._Header == None:
self._GetHeaderInfo()
if self._BuildTargets == None:
- self._BuildTargets = ['DEBUG', 'RELEASE']
+ EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BUILD_TARGETS", File=self.MetaFile)
return self._BuildTargets
-
+
+ def _GetPcdInfoFlag(self):
+ if self._PcdInfoFlag == None or self._PcdInfoFlag.upper() == 'FALSE':
+ return False
+ elif self._PcdInfoFlag.upper() == 'TRUE':
+ return True
+ else:
+ return False
+ def _GetVarCheckFlag(self):
+ if self._VarCheckFlag == None or self._VarCheckFlag.upper() == 'FALSE':
+ return False
+ elif self._VarCheckFlag.upper() == 'TRUE':
+ return True
+ else:
+ return False
+ def _GetAviableSkuIds(self):
+ if self._AvilableSkuIds:
+ return self._AvilableSkuIds
+ return self.SkuIdentifier
+ def _GetSkuIdentifier(self):
+ if self._SkuName:
+ return self._SkuName
+ if self._SkuIdentifier == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ return self._SkuIdentifier
## Retrieve SKUID_IDENTIFIER
def _GetSkuName(self):
if self._SkuName == None:
if self._Header == None:
self._GetHeaderInfo()
- if self._SkuName == None or self._SkuName not in self.SkuIds:
+ if (self._SkuName == None or self._SkuName not in self.SkuIds):
self._SkuName = 'DEFAULT'
return self._SkuName
## Override SKUID_IDENTIFIER
def _SetSkuName(self, Value):
- if Value in self.SkuIds:
- self._SkuName = Value
- # Needs to re-retrieve the PCD information
- self._Pcds = None
+ self._SkuName = Value
+ self._Pcds = None
def _GetFdfFile(self):
if self._FlashDefinition == None:
@@ -294,6 +418,22 @@ class DscBuildData(PlatformBuildClassObject):
self._FlashDefinition = ''
return self._FlashDefinition
+ def _GetPrebuild(self):
+ if self._Prebuild == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._Prebuild == None:
+ self._Prebuild = ''
+ return self._Prebuild
+
+ def _GetPostbuild(self):
+ if self._Postbuild == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._Postbuild == None:
+ self._Postbuild = ''
+ return self._Postbuild
+
## Retrieve FLASH_DEFINITION
def _GetBuildNumber(self):
if self._BuildNumber == None:
@@ -335,10 +475,48 @@ class DscBuildData(PlatformBuildClassObject):
if self._LoadFixAddress == None:
if self._Header == None:
self._GetHeaderInfo()
+
if self._LoadFixAddress == None:
- self._LoadFixAddress = ''
+ self._LoadFixAddress = self._Macros.get(TAB_FIX_LOAD_TOP_MEMORY_ADDRESS, '0')
+
+ try:
+ self._LoadFixAddress = int (self._LoadFixAddress, 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (self._LoadFixAddress))
+
+ #
+ # If command line defined, should override the value in DSC file.
+ #
+ if 'FIX_LOAD_TOP_MEMORY_ADDRESS' in GlobalData.gCommandLineDefines.keys():
+ try:
+ self._LoadFixAddress = int(GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS'], 0)
+ except:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS %s is not valid dec or hex string" % (GlobalData.gCommandLineDefines['FIX_LOAD_TOP_MEMORY_ADDRESS']))
+
+ if self._LoadFixAddress < 0:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid negative value 0x%x" % (self._LoadFixAddress))
+ if self._LoadFixAddress != 0xFFFFFFFFFFFFFFFF and self._LoadFixAddress % 0x1000 != 0:
+ EdkLogger.error("build", PARAMETER_INVALID, "FIX_LOAD_TOP_MEMORY_ADDRESS is set to the invalid unaligned 4K value 0x%x" % (self._LoadFixAddress))
+
return self._LoadFixAddress
+ ## Retrieve RFCLanguage filter
+ def _GetRFCLanguages(self):
+ if self._RFCLanguages == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._RFCLanguages == None:
+ self._RFCLanguages = []
+ return self._RFCLanguages
+
+ ## Retrieve ISOLanguage filter
+ def _GetISOLanguages(self):
+ if self._ISOLanguages == None:
+ if self._Header == None:
+ self._GetHeaderInfo()
+ if self._ISOLanguages == None:
+ self._ISOLanguages = []
+ return self._ISOLanguages
## Retrieve the GUID string for VPD tool
def _GetVpdToolGuid(self):
if self._VpdToolGuid == None:
@@ -351,8 +529,8 @@ class DscBuildData(PlatformBuildClassObject):
## Retrieve [SkuIds] section information
def _GetSkuIds(self):
if self._SkuIds == None:
- self._SkuIds = {}
- RecordList = self._RawData[MODEL_EFI_SKU_ID]
+ self._SkuIds = sdict()
+ RecordList = self._RawData[MODEL_EFI_SKU_ID, self._Arch]
for Record in RecordList:
if Record[0] in [None, '']:
EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID number',
@@ -362,7 +540,9 @@ class DscBuildData(PlatformBuildClassObject):
File=self.MetaFile, Line=Record[-1])
self._SkuIds[Record[1]] = Record[0]
if 'DEFAULT' not in self._SkuIds:
- self._SkuIds['DEFAULT'] = 0
+ self._SkuIds['DEFAULT'] = '0'
+ if 'COMMON' not in self._SkuIds:
+ self._SkuIds['COMMON'] = '0'
return self._SkuIds
## Retrieve [Components] section information
@@ -372,9 +552,11 @@ class DscBuildData(PlatformBuildClassObject):
self._Modules = sdict()
RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
for Record in RecordList:
+ DuplicatedFile = False
+
ModuleFile = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
ModuleId = Record[5]
LineNo = Record[6]
@@ -385,24 +567,13 @@ class DscBuildData(PlatformBuildClassObject):
EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo,
ExtraData=ErrorInfo)
# Check duplication
- if ModuleFile in self._Modules:
- EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
+ # If arch is COMMON, no duplicate module is checked since all modules in all component sections are selected
+ if self._Arch != 'COMMON' and ModuleFile in self._Modules:
+ DuplicatedFile = True
Module = ModuleBuildClassObject()
Module.MetaFile = ModuleFile
- # get module override path
- RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]
- if RecordList != []:
- Module.SourceOverridePath = os.path.join(GlobalData.gWorkspace, NormPath(RecordList[0][0], Macros))
-
- # Check if the source override path exists
- if not os.path.isdir(Module.SourceOverridePath):
- EdkLogger.error('build', FILE_NOT_FOUND, Message = 'Source override path does not exist:', File=self.MetaFile, ExtraData=Module.SourceOverridePath, Line=LineNo)
-
- #Add to GlobalData Variables
- GlobalData.gOverrideDir[ModuleFile.Key] = Module.SourceOverridePath
-
# get module private library instance
RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId]
for Record in RecordList:
@@ -459,6 +630,16 @@ class DscBuildData(PlatformBuildClassObject):
OptionString = Module.BuildOptions[ToolChainFamily, ToolChain]
Module.BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, None, ModuleId]
+ if DuplicatedFile and not RecordList:
+ EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
+ if RecordList:
+ if len(RecordList) != 1:
+ EdkLogger.error('build', OPTION_UNKNOWN, 'Only FILE_GUID can be listed in section.',
+ File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
+ ModuleFile = ProcessDuplicatedInf(ModuleFile, RecordList[0][2], GlobalData.gWorkspace)
+ ModuleFile.Arch = self._Arch
+
self._Modules[ModuleFile] = Module
return self._Modules
@@ -479,9 +660,8 @@ class DscBuildData(PlatformBuildClassObject):
LibraryClassDict = tdict(True, 3)
# track all library class names
LibraryClassSet = set()
- RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1]
+ Macros = self._Macros
for Record in RecordList:
LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy, LineNo = Record
if LibraryClass == '' or LibraryClass == 'NULL':
@@ -513,7 +693,8 @@ class DscBuildData(PlatformBuildClassObject):
continue
self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance
- # for R8 style library instances, which are listed in different section
+ # for Edk style library instances, which are listed in different section
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch]
for Record in RecordList:
File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
@@ -530,14 +711,71 @@ class DscBuildData(PlatformBuildClassObject):
# to parse it here. (self._Bdb[] will trigger a file parse if it
# hasn't been parsed)
#
- Library = self._Bdb[File, self._Arch]
+ Library = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
self._LibraryClasses[Library.BaseName, ':dummy:'] = Library
return self._LibraryClasses
+ def _ValidatePcd(self, PcdCName, TokenSpaceGuid, Setting, PcdType, LineNo):
+ if self._DecPcds == None:
+ self._DecPcds = GetDeclaredPcd(self, self._Bdb, self._Arch, self._Target, self._Toolchain)
+ FdfInfList = []
+ if GlobalData.gFdfParser:
+ FdfInfList = GlobalData.gFdfParser.Profile.InfList
+
+ PkgSet = set()
+ for Inf in FdfInfList:
+ ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch=self._Arch)
+ if ModuleFile in self._Modules:
+ continue
+ ModuleData = self._Bdb[ModuleFile, self._Arch, self._Target, self._Toolchain]
+ PkgSet.update(ModuleData.Packages)
+ DecPcds = {}
+ for Pkg in PkgSet:
+ for Pcd in Pkg.Pcds:
+ DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
+ self._DecPcds.update(DecPcds)
+
+ if (PcdCName, TokenSpaceGuid) not in self._DecPcds:
+ EdkLogger.error('build', PARSER_ERROR,
+ "Pcd (%s.%s) defined in DSC is not declared in DEC files. Arch: ['%s']" % (TokenSpaceGuid, PcdCName, self._Arch),
+ File=self.MetaFile, Line=LineNo)
+ ValueList, IsValid, Index = AnalyzeDscPcd(Setting, PcdType, self._DecPcds[PcdCName, TokenSpaceGuid].DatumType)
+ if not IsValid and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
+ EdkLogger.error('build', FORMAT_INVALID, "Pcd format incorrect.", File=self.MetaFile, Line=LineNo,
+ ExtraData="%s.%s|%s" % (TokenSpaceGuid, PcdCName, Setting))
+ if ValueList[Index] and PcdType not in [MODEL_PCD_FEATURE_FLAG, MODEL_PCD_FIXED_AT_BUILD]:
+ try:
+ ValueList[Index] = ValueExpression(ValueList[Index], GlobalData.gPlatformPcds)(True)
+ except WrnExpression, Value:
+ ValueList[Index] = Value.result
+ except EvaluationException, Excpt:
+ if hasattr(Excpt, 'Pcd'):
+ if Excpt.Pcd in GlobalData.gPlatformOtherPcds:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Cannot use this PCD (%s) in an expression as"
+ " it must be defined in a [PcdsFixedAtBuild] or [PcdsFeatureFlag] section"
+ " of the DSC file" % Excpt.Pcd,
+ File=self.MetaFile, Line=LineNo)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "PCD (%s) is not defined in DSC file" % Excpt.Pcd,
+ File=self.MetaFile, Line=LineNo)
+ else:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Invalid expression: %s" % str(Excpt),
+ File=self.MetaFile, Line=LineNo)
+ if ValueList[Index] == 'True':
+ ValueList[Index] = '1'
+ elif ValueList[Index] == 'False':
+ ValueList[Index] = '0'
+ if ValueList[Index]:
+ Valid, ErrStr = CheckPcdDatum(self._DecPcds[PcdCName, TokenSpaceGuid].DatumType, ValueList[Index])
+ if not Valid:
+ EdkLogger.error('build', FORMAT_INVALID, ErrStr, File=self.MetaFile, Line=LineNo,
+ ExtraData="%s.%s" % (TokenSpaceGuid, PcdCName))
+ return ValueList
+
## Retrieve all PCD settings in platform
def _GetPcds(self):
if self._Pcds == None:
- self._Pcds = {}
+ self._Pcds = sdict()
self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
@@ -552,21 +790,41 @@ class DscBuildData(PlatformBuildClassObject):
## Retrieve [BuildOptions]
def _GetBuildOptions(self):
if self._BuildOptions == None:
- self._BuildOptions = {}
- #
- # Retrieve build option for EDKII style module
- #
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDKII_NAME]
- for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
- self._BuildOptions[ToolChainFamily, ToolChain, EDKII_NAME] = Option
+ self._BuildOptions = sdict()
#
- # Retrieve build option for EDK style module
+ # Retrieve build option for EDKII and EDK style module
#
- RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, 'COMMON', EDK_NAME]
- for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
- self._BuildOptions[ToolChainFamily, ToolChain, EDK_NAME] = Option
+ for CodeBase in (EDKII_NAME, EDK_NAME):
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]
+ for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:
+ CurKey = (ToolChainFamily, ToolChain, CodeBase)
+ #
+ # Only flags can be appended
+ #
+ if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
+ self._BuildOptions[CurKey] = Option
+ else:
+ self._BuildOptions[CurKey] += ' ' + Option
return self._BuildOptions
+ def GetBuildOptionsByModuleType(self, Edk, ModuleType):
+ if self._ModuleTypeOptions == None:
+ self._ModuleTypeOptions = sdict()
+ if (Edk, ModuleType) not in self._ModuleTypeOptions:
+ options = sdict()
+ self._ModuleTypeOptions[Edk, ModuleType] = options
+ DriverType = '%s.%s' % (Edk, ModuleType)
+ CommonDriverType = '%s.%s' % ('COMMON', ModuleType)
+ RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]
+ for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:
+ if Type == DriverType or Type == CommonDriverType:
+ Key = (ToolChainFamily, ToolChain, Edk)
+ if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):
+ options[Key] = Option
+ else:
+ options[Key] += ' ' + Option
+ return self._ModuleTypeOptions[Edk, ModuleType]
+
## Retrieve non-dynamic PCD settings
#
# @param Type PCD type
@@ -574,27 +832,49 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetPcd(self, Type):
- Pcds = {}
+ Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH
#
+
+ SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
+
PcdDict = tdict(True, 3)
PcdSet = set()
# Find out all possible PCD candidates for self._Arch
RecordList = self._RawData[Type, self._Arch]
+ PcdValueDict = sdict()
for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- PcdSet.add((PcdCName, TokenSpaceGuid))
- PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting
- # Remove redundant PCD candidates
- for PcdCName, TokenSpaceGuid in PcdSet:
- ValueList = ['', '', '']
- Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
+ if SkuName in (SkuObj.SystemSkuId,'DEFAULT','COMMON'):
+ PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
+ PcdDict[Arch, PcdCName, TokenSpaceGuid,SkuName] = Setting
+
+ #handle pcd value override
+ for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdSet:
+ Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid,SkuName]
if Setting == None:
continue
- TokenList = Setting.split(TAB_VALUE_SPLIT)
- ValueList[0:len(TokenList)] = TokenList
- PcdValue, DatumType, MaxDatumSize = ValueList
+ PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ if (PcdCName, TokenSpaceGuid) in PcdValueDict:
+ PcdValueDict[PcdCName, TokenSpaceGuid][SkuName] = (PcdValue,DatumType,MaxDatumSize)
+ else:
+ PcdValueDict[PcdCName, TokenSpaceGuid] = {SkuName:(PcdValue,DatumType,MaxDatumSize)}
+
+ PcdsKeys = PcdValueDict.keys()
+ for PcdCName,TokenSpaceGuid in PcdsKeys:
+
+ PcdSetting = PcdValueDict[PcdCName, TokenSpaceGuid]
+ PcdValue = None
+ DatumType = None
+ MaxDatumSize = None
+ if 'COMMON' in PcdSetting:
+ PcdValue,DatumType,MaxDatumSize = PcdSetting['COMMON']
+ if 'DEFAULT' in PcdSetting:
+ PcdValue,DatumType,MaxDatumSize = PcdSetting['DEFAULT']
+ if SkuObj.SystemSkuId in PcdSetting:
+ PcdValue,DatumType,MaxDatumSize = PcdSetting[SkuObj.SystemSkuId]
+
Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
PcdCName,
TokenSpaceGuid,
@@ -616,43 +896,92 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicPcd(self, Type):
- Pcds = {}
+
+ SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
+
+ Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
PcdDict = tdict(True, 4)
- PcdSet = set()
+ PcdList = []
# Find out all possible PCD candidates for self._Arch
RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- PcdSet.add((PcdCName, TokenSpaceGuid))
+ if SkuName not in AvailableSkuIdSet:
+ continue
+
+ PcdList.append((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid in PcdSet:
- ValueList = ['', '', '']
- Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]
+ for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList:
+
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
- TokenList = Setting.split(TAB_VALUE_SPLIT)
- ValueList[0:len(TokenList)] = TokenList
- PcdValue, DatumType, MaxDatumSize = ValueList
-
- SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', '', PcdValue)
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
- PcdCName,
- TokenSpaceGuid,
- self._PCD_TYPE_STRING_[Type],
- DatumType,
- PcdValue,
- '',
- MaxDatumSize,
- {self.SkuName : SkuInfo},
- False,
- None
- )
+
+ PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', '', PcdValue)
+ if (PcdCName,TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName,TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ if MaxDatumSize.strip():
+ CurrentMaxSize = int(MaxDatumSize.strip(),0)
+ else:
+ CurrentMaxSize = 0
+ if pcdObject.MaxDatumSize:
+ PcdMaxSize = int(pcdObject.MaxDatumSize,0)
+ else:
+ PcdMaxSize = 0
+ if CurrentMaxSize > PcdMaxSize:
+ pcdObject.MaxDatumSize = str(CurrentMaxSize)
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ PcdCName,
+ TokenSpaceGuid,
+ self._PCD_TYPE_STRING_[Type],
+ DatumType,
+ PcdValue,
+ '',
+ MaxDatumSize,
+ {SkuName : SkuInfo},
+ False,
+ None
+ )
+
+ for pcd in Pcds.values():
+ pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '', '', '', valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
+
return Pcds
+ def CompareVarAttr(self, Attr1, Attr2):
+ if not Attr1 or not Attr2: # for empty string
+ return True
+ Attr1s = [attr.strip() for attr in Attr1.split(",")]
+ Attr1Set = set(Attr1s)
+ Attr2s = [attr.strip() for attr in Attr2.split(",")]
+ Attr2Set = set(Attr2s)
+ if Attr2Set == Attr1Set:
+ return True
+ else:
+ return False
## Retrieve dynamic HII PCD settings
#
# @param Type PCD type
@@ -660,7 +989,11 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicHiiPcd(self, Type):
- Pcds = {}
+
+ SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
+ VariableAttrs = {}
+
+ Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
@@ -669,20 +1002,61 @@ class DscBuildData(PlatformBuildClassObject):
PcdSet = set()
RecordList = self._RawData[Type, self._Arch]
# Find out all possible PCD candidates for self._Arch
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- PcdSet.add((PcdCName, TokenSpaceGuid))
+ if SkuName not in AvailableSkuIdSet:
+ continue
+ PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,Dummy4))
PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid in PcdSet:
- ValueList = ['', '', '', '']
- Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]
+ for PcdCName, TokenSpaceGuid,SkuName, Dummy4 in PcdSet:
+
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
- TokenList = Setting.split(TAB_VALUE_SPLIT)
- ValueList[0:len(TokenList)] = TokenList
- VariableName, VariableGuid, VariableOffset, DefaultValue = ValueList
- SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue)
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ VariableName, VariableGuid, VariableOffset, DefaultValue, VarAttribute = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+
+ rt, Msg = VariableAttributes.ValidateVarAttributes(VarAttribute)
+ if not rt:
+ EdkLogger.error("build", PCD_VARIABLE_ATTRIBUTES_ERROR, "Variable attributes settings for %s is incorrect.\n %s" % (".".join((TokenSpaceGuid, PcdCName)), Msg),
+ ExtraData = "[%s]" % VarAttribute)
+ ExceedMax = False
+ FormatCorrect = True
+ if VariableOffset.isdigit():
+ if int(VariableOffset,10) > 0xFFFF:
+ ExceedMax = True
+ elif re.match(r'[\t\s]*0[xX][a-fA-F0-9]+$',VariableOffset):
+ if int(VariableOffset,16) > 0xFFFF:
+ ExceedMax = True
+ # For Offset written in "A.B"
+ elif VariableOffset.find('.') > -1:
+ VariableOffsetList = VariableOffset.split(".")
+ if not (len(VariableOffsetList) == 2
+ and IsValidWord(VariableOffsetList[0])
+ and IsValidWord(VariableOffsetList[1])):
+ FormatCorrect = False
+ else:
+ FormatCorrect = False
+ if not FormatCorrect:
+ EdkLogger.error('Build', FORMAT_INVALID, "Invalid syntax or format of the variable offset value is incorrect for %s." % ".".join((TokenSpaceGuid,PcdCName)))
+
+ if ExceedMax:
+ EdkLogger.error('Build', OPTION_VALUE_INVALID, "The variable offset value must not exceed the maximum value of 0xFFFF (UINT16) for %s." % ".".join((TokenSpaceGuid,PcdCName)))
+ if (VariableName, VariableGuid) not in VariableAttrs:
+ VariableAttrs[(VariableName, VariableGuid)] = VarAttribute
+ else:
+ if not self.CompareVarAttr(VariableAttrs[(VariableName, VariableGuid)], VarAttribute):
+ EdkLogger.error('Build', PCD_VARIABLE_ATTRIBUTES_CONFLICT_ERROR, "The variable %s.%s for DynamicHii PCDs has conflicting attributes [%s] and [%s] " % (VariableGuid, VariableName, VarAttribute, VariableAttrs[(VariableName, VariableGuid)]))
+
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute = VarAttribute)
+ pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid]
+ if (PcdCName,TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName,TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
PcdCName,
TokenSpaceGuid,
self._PCD_TYPE_STRING_[Type],
@@ -690,10 +1064,54 @@ class DscBuildData(PlatformBuildClassObject):
DefaultValue,
'',
'',
- {self.SkuName : SkuInfo},
+ {SkuName : SkuInfo},
False,
- None
+ None,
+ pcdDecObject.validateranges,
+ pcdDecObject.validlists,
+ pcdDecObject.expressions
)
+
+
+ for pcd in Pcds.values():
+ SkuInfoObj = pcd.SkuInfoList.values()[0]
+ pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
+ # Only fix the value while no value provided in DSC file.
+ for sku in pcd.SkuInfoList.values():
+ if (sku.HiiDefaultValue == "" or sku.HiiDefaultValue==None):
+ sku.HiiDefaultValue = pcdDecObject.DefaultValue
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', SkuInfoObj.VariableName, SkuInfoObj.VariableGuid, SkuInfoObj.VariableOffset, valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
+
+
+ if pcd.MaxDatumSize.strip():
+ MaxSize = int(pcd.MaxDatumSize,0)
+ else:
+ MaxSize = 0
+ if pcdDecObject.DatumType == 'VOID*':
+ for (skuname,skuobj) in pcd.SkuInfoList.items():
+ datalen = 0
+ if skuobj.HiiDefaultValue.startswith("L"):
+ datalen = (len(skuobj.HiiDefaultValue)- 3 + 1) * 2
+ elif skuobj.HiiDefaultValue.startswith("{"):
+ datalen = len(skuobj.HiiDefaultValue.split(","))
+ else:
+ datalen = len(skuobj.HiiDefaultValue) -2 + 1
+ if datalen>MaxSize:
+ MaxSize = datalen
+ pcd.MaxDatumSize = str(MaxSize)
return Pcds
## Retrieve dynamic VPD PCD settings
@@ -703,47 +1121,83 @@ class DscBuildData(PlatformBuildClassObject):
# @retval a dict object contains settings of given PCD type
#
def _GetDynamicVpdPcd(self, Type):
- Pcds = {}
+
+ SkuObj = SkuClass(self.SkuIdentifier,self.SkuIds)
+
+ Pcds = sdict()
#
# tdict is a special dict kind of type, used for selecting correct
# PCD settings for certain ARCH and SKU
#
PcdDict = tdict(True, 4)
- PcdSet = set()
+ PcdList = []
# Find out all possible PCD candidates for self._Arch
RecordList = self._RawData[Type, self._Arch]
+ AvailableSkuIdSet = SkuObj.AvailableSkuIdSet.copy()
+
+ AvailableSkuIdSet.update({'DEFAULT':0,'COMMON':0})
for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4 in RecordList:
- PcdSet.add((PcdCName, TokenSpaceGuid))
+ if SkuName not in AvailableSkuIdSet:
+ continue
+
+ PcdList.append((PcdCName, TokenSpaceGuid,SkuName, Dummy4))
PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting
# Remove redundant PCD candidates, per the ARCH and SKU
- for PcdCName, TokenSpaceGuid in PcdSet:
- ValueList = ['', '', '']
- Setting = PcdDict[self._Arch, self.SkuName, PcdCName, TokenSpaceGuid]
+ for PcdCName, TokenSpaceGuid, SkuName,Dummy4 in PcdList:
+ Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
- TokenList = Setting.split(TAB_VALUE_SPLIT)
- ValueList[0:len(TokenList)] = TokenList
#
# For the VOID* type, it can have optional data of MaxDatumSize and InitialValue
# For the Integer & Boolean type, the optional data can only be InitialValue.
# At this point, we put all the data into the PcdClssObject for we don't know the PCD's datumtype
# until the DEC parser has been called.
#
- VpdOffset, MaxDatumSize, InitialValue = ValueList
-
- SkuInfo = SkuInfoClass(self.SkuName, self.SkuIds[self.SkuName], '', '', '', '', VpdOffset, InitialValue)
- Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
+ VpdOffset, MaxDatumSize, InitialValue = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4)
+ SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName], '', '', '', '', VpdOffset, InitialValue)
+ if (PcdCName,TokenSpaceGuid) in Pcds.keys():
+ pcdObject = Pcds[PcdCName,TokenSpaceGuid]
+ pcdObject.SkuInfoList[SkuName] = SkuInfo
+ if MaxDatumSize.strip():
+ CurrentMaxSize = int(MaxDatumSize.strip(),0)
+ else:
+ CurrentMaxSize = 0
+ if pcdObject.MaxDatumSize:
+ PcdMaxSize = int(pcdObject.MaxDatumSize,0)
+ else:
+ PcdMaxSize = 0
+ if CurrentMaxSize > PcdMaxSize:
+ pcdObject.MaxDatumSize = str(CurrentMaxSize)
+ else:
+ Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject(
PcdCName,
TokenSpaceGuid,
self._PCD_TYPE_STRING_[Type],
'',
- '',
+ InitialValue,
'',
MaxDatumSize,
- {self.SkuName : SkuInfo},
+ {SkuName : SkuInfo},
False,
None
)
+ for pcd in Pcds.values():
+ SkuInfoObj = pcd.SkuInfoList.values()[0]
+ pcdDecObject = self._DecPcds[pcd.TokenCName,pcd.TokenSpaceGuidCName]
+ if 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' not in pcd.SkuInfoList.keys():
+ valuefromDec = pcdDecObject.DefaultValue
+ SkuInfo = SkuInfoClass('DEFAULT', '0', '', '', '','',SkuInfoObj.VpdOffset, valuefromDec)
+ pcd.SkuInfoList['DEFAULT'] = SkuInfo
+ elif 'DEFAULT' not in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList['DEFAULT'] = pcd.SkuInfoList['COMMON']
+ del(pcd.SkuInfoList['COMMON'])
+ elif 'DEFAULT' in pcd.SkuInfoList.keys() and 'COMMON' in pcd.SkuInfoList.keys():
+ del(pcd.SkuInfoList['COMMON'])
+ if SkuObj.SkuUsageType == SkuObj.SINGLE:
+ if 'DEFAULT' in pcd.SkuInfoList.keys() and SkuObj.SystemSkuId not in pcd.SkuInfoList.keys():
+ pcd.SkuInfoList[SkuObj.SystemSkuId] = pcd.SkuInfoList['DEFAULT']
+ del(pcd.SkuInfoList['DEFAULT'])
+
return Pcds
## Add external modules
@@ -774,6 +1228,7 @@ class DscBuildData(PlatformBuildClassObject):
self.Pcds[Name, Guid] = PcdClassObject(Name, Guid, '', '', '', '', '', {}, False, None)
self.Pcds[Name, Guid].DefaultValue = Value
+ _Macros = property(_GetMacros)
Arch = property(_GetArch, _SetArch)
Platform = property(_GetPlatformName)
PlatformName = property(_GetPlatformName)
@@ -784,12 +1239,20 @@ class DscBuildData(PlatformBuildClassObject):
SupArchList = property(_GetSupArch)
BuildTargets = property(_GetBuildTarget)
SkuName = property(_GetSkuName, _SetSkuName)
+ SkuIdentifier = property(_GetSkuIdentifier)
+ AvilableSkuIds = property(_GetAviableSkuIds)
+ PcdInfoFlag = property(_GetPcdInfoFlag)
+ VarCheckFlag = property(_GetVarCheckFlag)
FlashDefinition = property(_GetFdfFile)
+ Prebuild = property(_GetPrebuild)
+ Postbuild = property(_GetPostbuild)
BuildNumber = property(_GetBuildNumber)
MakefileName = property(_GetMakefileName)
BsBaseAddress = property(_GetBsBaseAddress)
RtBaseAddress = property(_GetRtBaseAddress)
LoadFixAddress = property(_GetLoadFixAddress)
+ RFCLanguages = property(_GetRFCLanguages)
+ ISOLanguages = property(_GetISOLanguages)
VpdToolGuid = property(_GetVpdToolGuid)
SkuIds = property(_GetSkuIds)
Modules = property(_GetModules)
@@ -842,13 +1305,14 @@ class DecBuildData(PackageBuildClassObject):
# @param Platform (not used for DecBuildData)
# @param Macros Macros used for replacement in DSC file
#
- def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Platform='DUMMY', Macros={}):
+ def __init__(self, File, RawData, BuildDataBase, Arch='COMMON', Target=None, Toolchain=None):
self.MetaFile = File
self._PackageDir = File.Dir
self._RawData = RawData
self._Bdb = BuildDataBase
self._Arch = Arch
- self._Macros = Macros
+ self._Target = Target
+ self._Toolchain = Toolchain
self._Clear()
## XXX[key] = value
@@ -876,6 +1340,18 @@ class DecBuildData(PackageBuildClassObject):
self._Includes = None
self._LibraryClasses = None
self._Pcds = None
+ self.__Macros = None
+ self._PrivateProtocols = None
+ self._PrivatePpis = None
+ self._PrivateGuids = None
+ self._PrivateIncludes = None
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ return self.__Macros
## Get architecture
def _GetArch(self):
@@ -901,11 +1377,11 @@ class DecBuildData(PackageBuildClassObject):
# (Retriving all [Defines] information in one-shot is just to save time.)
#
def _GetHeaderInfo(self):
- RecordList = self._RawData[MODEL_META_DATA_HEADER]
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch]
for Record in RecordList:
- Name = Record[0]
+ Name = Record[1]
if Name in self:
- self[Name] = Record[1]
+ self[Name] = Record[2]
self._Header = 'DUMMY'
## Retrieve package name
@@ -943,21 +1419,38 @@ class DecBuildData(PackageBuildClassObject):
# protocol defition for given ARCH
#
ProtocolDict = tdict(True)
+ PrivateProtocolDict = tdict(True)
NameList = []
+ PrivateNameList = []
+ PublicNameList = []
# find out all protocol definitions for specific and 'common' arch
RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]
- for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivateProtocolDict[Arch, Name] = Guid
+ if Name in PublicNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ else:
+ if Name not in PublicNameList:
+ PublicNameList.append(Name)
+ if Name in PrivateNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
if Name not in NameList:
NameList.append(Name)
ProtocolDict[Arch, Name] = Guid
# use sdict to keep the order
self._Protocols = sdict()
+ self._PrivateProtocols = sdict()
for Name in NameList:
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
self._Protocols[Name] = ProtocolDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]
return self._Protocols
## Retrieve PPI definitions (name/value pairs)
@@ -968,21 +1461,38 @@ class DecBuildData(PackageBuildClassObject):
# PPI defition for given ARCH
#
PpiDict = tdict(True)
+ PrivatePpiDict = tdict(True)
NameList = []
+ PrivateNameList = []
+ PublicNameList = []
# find out all PPI definitions for specific arch and 'common' arch
RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]
- for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivatePpiDict[Arch, Name] = Guid
+ if Name in PublicNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ else:
+ if Name not in PublicNameList:
+ PublicNameList.append(Name)
+ if Name in PrivateNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
if Name not in NameList:
NameList.append(Name)
PpiDict[Arch, Name] = Guid
# use sdict to keep the order
self._Ppis = sdict()
+ self._PrivatePpis = sdict()
for Name in NameList:
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
self._Ppis[Name] = PpiDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]
return self._Ppis
## Retrieve GUID definitions (name/value pairs)
@@ -993,30 +1503,49 @@ class DecBuildData(PackageBuildClassObject):
# GUID defition for given ARCH
#
GuidDict = tdict(True)
+ PrivateGuidDict = tdict(True)
NameList = []
+ PrivateNameList = []
+ PublicNameList = []
# find out all protocol definitions for specific and 'common' arch
RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]
- for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivateGuidDict[Arch, Name] = Guid
+ if Name in PublicNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
+ else:
+ if Name not in PublicNameList:
+ PublicNameList.append(Name)
+ if Name in PrivateNameList:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % Name, File=self.MetaFile, Line=LineNo)
if Name not in NameList:
NameList.append(Name)
GuidDict[Arch, Name] = Guid
# use sdict to keep the order
self._Guids = sdict()
+ self._PrivateGuids = sdict()
for Name in NameList:
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
self._Guids[Name] = GuidDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]
return self._Guids
## Retrieve public include paths declared in this package
def _GetInclude(self):
if self._Includes == None:
self._Includes = []
+ self._PrivateIncludes = []
+ PublicInclues = []
RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
for Record in RecordList:
File = PathClass(NormPath(Record[0], Macros), self._PackageDir, Arch=self._Arch)
LineNo = Record[-1]
@@ -1028,6 +1557,17 @@ class DecBuildData(PackageBuildClassObject):
# avoid duplicate include path
if File not in self._Includes:
self._Includes.append(File)
+ if Record[4] == 'PRIVATE':
+ if File not in self._PrivateIncludes:
+ self._PrivateIncludes.append(File)
+ if File in PublicInclues:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
+ else:
+ if File not in PublicInclues:
+ PublicInclues.append(File)
+ if File in self._PrivateIncludes:
+ EdkLogger.error('build', OPTION_CONFLICT, "Can't determine %s's attribute, it is both defined as Private and non-Private attribute in DEC file." % File, File=self.MetaFile, Line=LineNo)
+
return self._Includes
## Retrieve library class declarations (not used in build at present)
@@ -1040,9 +1580,8 @@ class DecBuildData(PackageBuildClassObject):
LibraryClassDict = tdict(True)
LibraryClassSet = set()
RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
- for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:
+ Macros = self._Macros
+ for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)
# check the file validation
ErrorCode, ErrorInfo = File.Validate()
@@ -1058,7 +1597,7 @@ class DecBuildData(PackageBuildClassObject):
## Retrieve PCD declarations
def _GetPcds(self):
if self._Pcds == None:
- self._Pcds = {}
+ self._Pcds = sdict()
self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
@@ -1068,7 +1607,7 @@ class DecBuildData(PackageBuildClassObject):
## Retrieve PCD declarations for given type
def _GetPcd(self, Type):
- Pcds = {}
+ Pcds = sdict()
#
# tdict is a special kind of dict, used for selecting correct
# PCD declaration for given ARCH
@@ -1078,12 +1617,11 @@ class DecBuildData(PackageBuildClassObject):
PcdSet = set()
# find out all PCDs of the 'type'
RecordList = self._RawData[Type, self._Arch]
- for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:
+ for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:
PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting
PcdSet.add((PcdCName, TokenSpaceGuid))
for PcdCName, TokenSpaceGuid in PcdSet:
- ValueList = ['', '', '']
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH and try again
@@ -1091,9 +1629,10 @@ class DecBuildData(PackageBuildClassObject):
Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
- TokenList = Setting.split(TAB_VALUE_SPLIT)
- ValueList[0:len(TokenList)] = TokenList
- DefaultValue, DatumType, TokenNumber = ValueList
+
+ DefaultValue, DatumType, TokenNumber = AnalyzePcdData(Setting)
+
+ validateranges, validlists, expressions = self._RawData.GetValidExpression(TokenSpaceGuid, PcdCName)
Pcds[PcdCName, TokenSpaceGuid, self._PCD_TYPE_STRING_[Type]] = PcdClassObject(
PcdCName,
TokenSpaceGuid,
@@ -1104,11 +1643,15 @@ class DecBuildData(PackageBuildClassObject):
'',
{},
False,
- None
+ None,
+ list(validateranges),
+ list(validlists),
+ list(expressions)
)
return Pcds
+ _Macros = property(_GetMacros)
Arch = property(_GetArch, _SetArch)
PackageName = property(_GetPackageName)
Guid = property(_GetFileGuid)
@@ -1153,10 +1696,11 @@ class InfBuildData(ModuleBuildClassObject):
#
# Optional Fields
#
- TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
+ #TAB_INF_DEFINES_INF_VERSION : "_AutoGenVersion",
TAB_INF_DEFINES_COMPONENT_TYPE : "_ComponentType",
TAB_INF_DEFINES_MAKEFILE_NAME : "_MakefileName",
#TAB_INF_DEFINES_CUSTOM_MAKEFILE : "_CustomMakefile",
+ TAB_INF_DEFINES_DPX_SOURCE :"_DxsFile",
TAB_INF_DEFINES_VERSION_NUMBER : "_Version",
TAB_INF_DEFINES_VERSION_STRING : "_Version",
TAB_INF_DEFINES_VERSION : "_Version",
@@ -1207,14 +1751,15 @@ class InfBuildData(ModuleBuildClassObject):
# @param Platform The name of platform employing this module
# @param Macros Macros used for replacement in DSC file
#
- def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Platform='COMMON', Macros={}):
+ def __init__(self, FilePath, RawData, BuildDatabase, Arch='COMMON', Target=None, Toolchain=None):
self.MetaFile = FilePath
self._ModuleDir = FilePath.Dir
self._RawData = RawData
self._Bdb = BuildDatabase
self._Arch = Arch
+ self._Target = Target
+ self._Toolchain = Toolchain
self._Platform = 'COMMON'
- self._Macros = Macros
self._SourceOverridePath = None
if FilePath.Key in GlobalData.gOverrideDir:
self._SourceOverridePath = GlobalData.gOverrideDir[FilePath.Key]
@@ -1234,9 +1779,12 @@ class InfBuildData(ModuleBuildClassObject):
## Set all internal used members of InfBuildData to None
def _Clear(self):
+ self._HeaderComments = None
+ self._TailComments = None
self._Header_ = None
self._AutoGenVersion = None
self._BaseName = None
+ self._DxsFile = None
self._ModuleType = None
self._ComponentType = None
self._BuildType = None
@@ -1259,15 +1807,32 @@ class InfBuildData(ModuleBuildClassObject):
self._LibraryClasses = None
self._Libraries = None
self._Protocols = None
+ self._ProtocolComments = None
self._Ppis = None
+ self._PpiComments = None
self._Guids = None
+ self._GuidsUsedByPcd = sdict()
+ self._GuidComments = None
self._Includes = None
self._Packages = None
self._Pcds = None
+ self._PcdComments = None
self._BuildOptions = None
self._Depex = None
self._DepexExpression = None
- #self._SourceOverridePath = None
+ self.__Macros = None
+
+ ## Get current effective macros
+ def _GetMacros(self):
+ if self.__Macros == None:
+ self.__Macros = {}
+ # EDK_GLOBAL defined macros can be applied to EDK module
+ if self.AutoGenVersion < 0x00010005:
+ self.__Macros.update(GlobalData.gEdkGlobal)
+ self.__Macros.update(GlobalData.gGlobalDefines)
+ else:
+ self.__Macros.update(self.Defines)
+ return self.__Macros
## Get architecture
def _GetArch(self):
@@ -1303,7 +1868,20 @@ class InfBuildData(ModuleBuildClassObject):
return
self._Platform = Value
self._Clear()
-
+ def _GetHeaderComments(self):
+ if not self._HeaderComments:
+ self._HeaderComments = []
+ RecordList = self._RawData[MODEL_META_DATA_HEADER_COMMENT]
+ for Record in RecordList:
+ self._HeaderComments.append(Record[0])
+ return self._HeaderComments
+ def _GetTailComments(self):
+ if not self._TailComments:
+ self._TailComments = []
+ RecordList = self._RawData[MODEL_META_DATA_TAIL_COMMENT]
+ for Record in RecordList:
+ self._TailComments.append(Record[0])
+ return self._TailComments
## Retrieve all information in [Defines] section
#
# (Retriving all [Defines] information in one-shot is just to save time.)
@@ -1311,26 +1889,28 @@ class InfBuildData(ModuleBuildClassObject):
def _GetHeaderInfo(self):
RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
- Name = Record[0]
+ Name, Value = Record[1], ReplaceMacro(Record[2], self._Macros, False)
# items defined _PROPERTY_ don't need additional processing
if Name in self:
- self[Name] = Record[1]
+ self[Name] = Value
+ if self._Defs == None:
+ self._Defs = sdict()
+ self._Defs[Name] = Value
# some special items in [Defines] section need special treatment
elif Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION', 'EDK_RELEASE_VERSION', 'PI_SPECIFICATION_VERSION'):
if Name in ('EFI_SPECIFICATION_VERSION', 'UEFI_SPECIFICATION_VERSION'):
Name = 'UEFI_SPECIFICATION_VERSION'
if self._Specification == None:
self._Specification = sdict()
- self._Specification[Name] = GetHexVerValue(Record[1])
+ self._Specification[Name] = GetHexVerValue(Value)
if self._Specification[Name] == None:
EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
- "'%s' format is not supported for %s" % (Record[1], Name),
+ "'%s' format is not supported for %s" % (Value, Name),
File=self.MetaFile, Line=Record[-1])
elif Name == 'LIBRARY_CLASS':
if self._LibraryClass == None:
self._LibraryClass = []
- ValueList = GetSplitValueList(Record[1])
+ ValueList = GetSplitValueList(Value)
LibraryClass = ValueList[0]
if len(ValueList) > 1:
SupModuleList = GetSplitValueList(ValueList[1], ' ')
@@ -1340,27 +1920,27 @@ class InfBuildData(ModuleBuildClassObject):
elif Name == 'ENTRY_POINT':
if self._ModuleEntryPointList == None:
self._ModuleEntryPointList = []
- self._ModuleEntryPointList.append(Record[1])
+ self._ModuleEntryPointList.append(Value)
elif Name == 'UNLOAD_IMAGE':
if self._ModuleUnloadImageList == None:
self._ModuleUnloadImageList = []
- if Record[1] == '':
+ if not Value:
continue
- self._ModuleUnloadImageList.append(Record[1])
+ self._ModuleUnloadImageList.append(Value)
elif Name == 'CONSTRUCTOR':
if self._ConstructorList == None:
self._ConstructorList = []
- if Record[1] == '':
+ if not Value:
continue
- self._ConstructorList.append(Record[1])
+ self._ConstructorList.append(Value)
elif Name == 'DESTRUCTOR':
if self._DestructorList == None:
self._DestructorList = []
- if Record[1] == '':
+ if not Value:
continue
- self._DestructorList.append(Record[1])
+ self._DestructorList.append(Value)
elif Name == TAB_INF_DEFINES_CUSTOM_MAKEFILE:
- TokenList = GetSplitValueList(Record[1])
+ TokenList = GetSplitValueList(Value)
if self._CustomMakefile == None:
self._CustomMakefile = {}
if len(TokenList) < 2:
@@ -1375,49 +1955,73 @@ class InfBuildData(ModuleBuildClassObject):
else:
if self._Defs == None:
self._Defs = sdict()
- self._Defs[Name] = Record[1]
+ self._Defs[Name] = Value
#
- # Retrieve information in sections specific to R8.x modules
+ # Retrieve information in sections specific to Edk.x modules
#
- if self._AutoGenVersion >= 0x00010005: # _AutoGenVersion may be None, which is less than anything
+ if self.AutoGenVersion >= 0x00010005:
if not self._ModuleType:
EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
"MODULE_TYPE is not given", File=self.MetaFile)
- if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (self._Specification['PI_SPECIFICATION_VERSION'] < 0x0001000A):
+ if self._ModuleType not in SUP_MODULE_LIST:
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
+ for Record in RecordList:
+ Name = Record[1]
+ if Name == "MODULE_TYPE":
+ LineNo = Record[6]
+ break
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED,
+ "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),
+ File=self.MetaFile, Line=LineNo)
+ if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):
if self._ModuleType == SUP_MODULE_SMM_CORE:
- EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)
+ EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)
if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \
- and 'PCI_CLASS_CODE' in self._Defs:
+ and 'PCI_CLASS_CODE' in self._Defs and 'PCI_REVISION' in self._Defs:
self._BuildType = 'UEFI_OPTIONROM'
+ if 'PCI_COMPRESS' in self._Defs:
+ if self._Defs['PCI_COMPRESS'] not in ('TRUE', 'FALSE'):
+ EdkLogger.error("build", FORMAT_INVALID, "Expected TRUE/FALSE for PCI_COMPRESS: %s" %self.MetaFile)
+
elif self._Defs and 'UEFI_HII_RESOURCE_SECTION' in self._Defs \
and self._Defs['UEFI_HII_RESOURCE_SECTION'] == 'TRUE':
self._BuildType = 'UEFI_HII'
else:
self._BuildType = self._ModuleType.upper()
- else:
- self._BuildType = self._ComponentType.upper()
+
+ if self._DxsFile:
+ File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)
+ # check the file validation
+ ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)
+ if ErrorCode != 0:
+ EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo,
+ File=self.MetaFile, Line=LineNo)
+ if self.Sources == None:
+ self._Sources = []
+ self._Sources.append(File)
+ else:
if not self._ComponentType:
EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,
"COMPONENT_TYPE is not given", File=self.MetaFile)
+ self._BuildType = self._ComponentType.upper()
if self._ComponentType in self._MODULE_TYPE_:
self._ModuleType = self._MODULE_TYPE_[self._ComponentType]
if self._ComponentType == 'LIBRARY':
self._LibraryClass = [LibraryClassObject(self._BaseName, SUP_MODULE_LIST)]
# make use some [nmake] section macros
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]
- for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:
- Value = Value.replace('$(PROCESSOR)', self._Arch)
- Name = Name.replace('$(PROCESSOR)', self._Arch)
- Name, Value = ReplaceMacros((Name, Value), GlobalData.gEdkGlobal, True)
+ for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:
+ Value = ReplaceMacro(Value, Macros, True)
if Name == "IMAGE_ENTRY_POINT":
if self._ModuleEntryPointList == None:
self._ModuleEntryPointList = []
self._ModuleEntryPointList.append(Value)
elif Name == "DPX_SOURCE":
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
- File = PathClass(NormPath(Value, Macros), self._ModuleDir, Arch=self._Arch)
+ File = PathClass(NormPath(Value), self._ModuleDir, Arch=self._Arch)
# check the file validation
ErrorCode, ErrorInfo = File.Validate(".dxs", CaseSensitive=False)
if ErrorCode != 0:
@@ -1441,9 +2045,9 @@ class InfBuildData(ModuleBuildClassObject):
else:
Tool = ToolList[0]
ToolChain = "*_*_*_%s_FLAGS" % Tool
- ToolChainFamily = 'MSFT' # R8.x only support MSFT tool chain
+ ToolChainFamily = 'MSFT' # Edk.x only support MSFT tool chain
#ignore not replaced macros in value
- ValueList = GetSplitValueList(' ' + Value, '/D')
+ ValueList = GetSplitList(' ' + Value, '/D')
Dummy = ValueList[0]
for Index in range(1, len(ValueList)):
if ValueList[Index][-1] == '=' or ValueList[Index] == '':
@@ -1461,8 +2065,17 @@ class InfBuildData(ModuleBuildClassObject):
## Retrieve file version
def _GetInfVersion(self):
if self._AutoGenVersion == None:
- if self._Header_ == None:
- self._GetHeaderInfo()
+ RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]
+ for Record in RecordList:
+ if Record[1] == TAB_INF_DEFINES_INF_VERSION:
+ if '.' in Record[2]:
+ ValueList = Record[2].split('.')
+ Major = '%04o' % int(ValueList[0], 0)
+ Minor = '%04o' % int(ValueList[1], 0)
+ self._AutoGenVersion = int('0x' + Major + Minor, 0)
+ else:
+ self._AutoGenVersion = int(Record[2], 0)
+ break
if self._AutoGenVersion == None:
self._AutoGenVersion = 0x00010000
return self._AutoGenVersion
@@ -1476,6 +2089,15 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No BASE_NAME name", File=self.MetaFile)
return self._BaseName
+ ## Retrieve DxsFile
+ def _GetDxsFile(self):
+ if self._DxsFile == None:
+ if self._Header_ == None:
+ self._GetHeaderInfo()
+ if self._DxsFile == None:
+ self._DxsFile = ''
+ return self._DxsFile
+
## Retrieve MODULE_TYPE
def _GetModuleType(self):
if self._ModuleType == None:
@@ -1511,7 +2133,7 @@ class InfBuildData(ModuleBuildClassObject):
if self._Header_ == None:
self._GetHeaderInfo()
if self._Guid == None:
- self._Guid = '00000000-0000-0000-000000000000'
+ self._Guid = '00000000-0000-0000-0000-000000000000'
return self._Guid
## Retrieve module version
@@ -1616,14 +2238,14 @@ class InfBuildData(ModuleBuildClassObject):
return self._Defs
## Retrieve binary files
- def _GetBinaryFiles(self):
+ def _GetBinaries(self):
if self._Binaries == None:
self._Binaries = []
RecordList = self._RawData[MODEL_EFI_BINARY_FILE, self._Arch, self._Platform]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
FileType = Record[0]
LineNo = Record[-1]
Target = 'COMMON'
@@ -1643,23 +2265,45 @@ class InfBuildData(ModuleBuildClassObject):
self._Binaries.append(File)
return self._Binaries
+ ## Retrieve binary files with error check.
+ def _GetBinaryFiles(self):
+ Binaries = self._GetBinaries()
+ if GlobalData.gIgnoreSource and Binaries == []:
+ ErrorInfo = "The INF file does not contain any Binaries to use in creating the image\n"
+ EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, ExtraData=ErrorInfo, File=self.MetaFile)
+
+ return Binaries
+ ## Check whether it exists the binaries with current ARCH in AsBuild INF
+ def _IsSupportedArch(self):
+ if self._GetBinaries() and not self._GetSourceFiles():
+ return True
+ else:
+ return False
## Retrieve source files
def _GetSourceFiles(self):
+ #Ignore all source files in a binary build mode
+ if GlobalData.gIgnoreSource:
+ self._Sources = []
+ return self._Sources
+
if self._Sources == None:
self._Sources = []
RecordList = self._RawData[MODEL_EFI_SOURCE_FILE, self._Arch, self._Platform]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource, 'PROCESSOR':self._Arch}
- Macros.update(self._Macros)
+ Macros = self._Macros
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
LineNo = Record[-1]
ToolChainFamily = Record[1]
TagName = Record[2]
ToolCode = Record[3]
FeatureFlag = Record[4]
- if self._AutoGenVersion < 0x00010005:
- # old module source files (R8)
- File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,
+ if self.AutoGenVersion < 0x00010005:
+ Macros["EDK_SOURCE"] = GlobalData.gEcpSource
+ Macros['PROCESSOR'] = self._Arch
+ SourceFile = NormPath(Record[0], Macros)
+ if SourceFile[0] == os.path.sep:
+ SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])
+ # old module source files (Edk)
+ File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,
'', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)
# check the file validation
ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)
@@ -1687,92 +2331,118 @@ class InfBuildData(ModuleBuildClassObject):
self._LibraryClasses = sdict()
RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, self._Platform]
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
Lib = Record[0]
Instance = Record[1]
- if Instance != None and Instance != '':
+ if Instance:
Instance = NormPath(Instance, self._Macros)
self._LibraryClasses[Lib] = Instance
return self._LibraryClasses
- ## Retrieve library names (for R8.x style of modules)
+ ## Retrieve library names (for Edk.x style of modules)
def _GetLibraryNames(self):
if self._Libraries == None:
self._Libraries = []
RecordList = self._RawData[MODEL_EFI_LIBRARY_INSTANCE, self._Arch, self._Platform]
for Record in RecordList:
- # in case of name with '.lib' extension, which is unusual in R8.x inf
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
- LibraryName = os.path.splitext(Record[0])[0]
+ LibraryName = ReplaceMacro(Record[0], self._Macros, False)
+ # in case of name with '.lib' extension, which is unusual in Edk.x inf
+ LibraryName = os.path.splitext(LibraryName)[0]
if LibraryName not in self._Libraries:
self._Libraries.append(LibraryName)
return self._Libraries
+ def _GetProtocolComments(self):
+ self._GetProtocols()
+ return self._ProtocolComments
## Retrieve protocols consumed/produced by this module
def _GetProtocols(self):
if self._Protocols == None:
self._Protocols = sdict()
+ self._ProtocolComments = sdict()
RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = ProtocolValue(CName, self.Packages)
+ Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
"Value of Protocol [%s] is not found under [Protocols] section in" % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Protocols[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._ProtocolComments[CName] = Comments
return self._Protocols
+ def _GetPpiComments(self):
+ self._GetPpis()
+ return self._PpiComments
## Retrieve PPIs consumed/produced by this module
def _GetPpis(self):
if self._Ppis == None:
self._Ppis = sdict()
+ self._PpiComments = sdict()
RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = PpiValue(CName, self.Packages)
+ Value = PpiValue(CName, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
"Value of PPI [%s] is not found under [Ppis] section in " % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Ppis[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._PpiComments[CName] = Comments
return self._Ppis
+ def _GetGuidComments(self):
+ self._GetGuids()
+ return self._GuidComments
## Retrieve GUIDs consumed/produced by this module
def _GetGuids(self):
if self._Guids == None:
self._Guids = sdict()
+ self._GuidComments = sdict()
RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = GuidValue(CName, self.Packages)
+ Value = GuidValue(CName, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
"Value of Guid [%s] is not found under [Guids] section in" % CName,
ExtraData=PackageList, File=self.MetaFile, Line=Record[-1])
self._Guids[CName] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Record[5]]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._GuidComments[CName] = Comments
return self._Guids
- ## Retrieve include paths necessary for this module (for R8.x style of modules)
+ ## Retrieve include paths necessary for this module (for Edk.x style of modules)
def _GetIncludes(self):
if self._Includes == None:
self._Includes = []
if self._SourceOverridePath:
self._Includes.append(self._SourceOverridePath)
+
+ Macros = self._Macros
+ if 'PROCESSOR' in GlobalData.gEdkGlobal.keys():
+ Macros['PROCESSOR'] = GlobalData.gEdkGlobal['PROCESSOR']
+ else:
+ Macros['PROCESSOR'] = self._Arch
RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch, self._Platform]
- # [includes] section must be used only in old (R8.x) inf file
- if self.AutoGenVersion >= 0x00010005 and len(RecordList) > 0:
- EdkLogger.error('build', FORMAT_NOT_SUPPORTED, "No [include] section allowed",
- File=self.MetaFile, Line=RecordList[0][-1]-1)
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
- Record[0] = Record[0].replace('$(PROCESSOR)', self._Arch)
- Record[0] = ReplaceMacro(Record[0], {'EFI_SOURCE' : GlobalData.gEfiSource}, False)
if Record[0].find('EDK_SOURCE') > -1:
- File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEcpSource}, False), self._Macros)
+ Macros['EDK_SOURCE'] = GlobalData.gEcpSource
+ File = NormPath(Record[0], self._Macros)
if File[0] == '.':
File = os.path.join(self._ModuleDir, File)
else:
@@ -1782,7 +2452,8 @@ class InfBuildData(ModuleBuildClassObject):
self._Includes.append(File)
#TRICK: let compiler to choose correct header file
- File = NormPath(ReplaceMacro(Record[0], {'EDK_SOURCE' : GlobalData.gEdkSource}, False), self._Macros)
+ Macros['EDK_SOURCE'] = GlobalData.gEdkSource
+ File = NormPath(Record[0], self._Macros)
if File[0] == '.':
File = os.path.join(self._ModuleDir, File)
else:
@@ -1791,14 +2462,25 @@ class InfBuildData(ModuleBuildClassObject):
if File:
self._Includes.append(File)
else:
- File = NormPath(Record[0], self._Macros)
+ File = NormPath(Record[0], Macros)
if File[0] == '.':
File = os.path.join(self._ModuleDir, File)
else:
- File = os.path.join(GlobalData.gWorkspace, File)
+ File = mws.join(GlobalData.gWorkspace, File)
File = RealPath(os.path.normpath(File))
if File:
self._Includes.append(File)
+ if not File and Record[0].find('EFI_SOURCE') > -1:
+ # tricky to regard WorkSpace as EFI_SOURCE
+ Macros['EFI_SOURCE'] = GlobalData.gWorkspace
+ File = NormPath(Record[0], Macros)
+ if File[0] == '.':
+ File = os.path.join(self._ModuleDir, File)
+ else:
+ File = os.path.join(GlobalData.gWorkspace, File)
+ File = RealPath(os.path.normpath(File))
+ if File:
+ self._Includes.append(File)
return self._Includes
## Retrieve packages this module depends on
@@ -1806,8 +2488,8 @@ class InfBuildData(ModuleBuildClassObject):
if self._Packages == None:
self._Packages = []
RecordList = self._RawData[MODEL_META_DATA_PACKAGE, self._Arch, self._Platform]
- Macros = {"EDK_SOURCE":GlobalData.gEcpSource, "EFI_SOURCE":GlobalData.gEfiSource}
- Macros.update(self._Macros)
+ Macros = self._Macros
+ Macros['EDK_SOURCE'] = GlobalData.gEcpSource
for Record in RecordList:
File = PathClass(NormPath(Record[0], Macros), GlobalData.gWorkspace, Arch=self._Arch)
LineNo = Record[-1]
@@ -1816,14 +2498,19 @@ class InfBuildData(ModuleBuildClassObject):
if ErrorCode != 0:
EdkLogger.error('build', ErrorCode, ExtraData=ErrorInfo, File=self.MetaFile, Line=LineNo)
# parse this package now. we need it to get protocol/ppi/guid value
- Package = self._Bdb[File, self._Arch]
+ Package = self._Bdb[File, self._Arch, self._Target, self._Toolchain]
self._Packages.append(Package)
return self._Packages
+ ## Retrieve PCD comments
+ def _GetPcdComments(self):
+ self._GetPcds()
+ return self._PcdComments
## Retrieve PCDs used in this module
def _GetPcds(self):
if self._Pcds == None:
- self._Pcds = {}
+ self._Pcds = sdict()
+ self._PcdComments = sdict()
self._Pcds.update(self._GetPcd(MODEL_PCD_FIXED_AT_BUILD))
self._Pcds.update(self._GetPcd(MODEL_PCD_PATCHABLE_IN_MODULE))
self._Pcds.update(self._GetPcd(MODEL_PCD_FEATURE_FLAG))
@@ -1840,7 +2527,7 @@ class InfBuildData(ModuleBuildClassObject):
ToolChainFamily = Record[0]
ToolChain = Record[1]
Option = Record[2]
- if (ToolChainFamily, ToolChain) not in self._BuildOptions:
+ if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):
self._BuildOptions[ToolChainFamily, ToolChain] = Option
else:
# concatenate the option string if they're for the same tool
@@ -1848,12 +2535,17 @@ class InfBuildData(ModuleBuildClassObject):
self._BuildOptions[ToolChainFamily, ToolChain] = OptionString + " " + Option
return self._BuildOptions
- ## Retrieve depedency expression
+ ## Retrieve dependency expression
def _GetDepex(self):
if self._Depex == None:
self._Depex = tdict(False, 2)
RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
-
+
+ # If the module has only Binaries and no Sources, then ignore [Depex]
+ if self.Sources == None or self.Sources == []:
+ if self.Binaries != None and self.Binaries != []:
+ return self._Depex
+
# PEIM and DXE drivers must have a valid [Depex] section
if len(self.LibraryClass) == 0 and len(RecordList) == 0:
if self.ModuleType == 'DXE_DRIVER' or self.ModuleType == 'PEIM' or self.ModuleType == 'DXE_SMM_DRIVER' or \
@@ -1861,12 +2553,19 @@ class InfBuildData(ModuleBuildClassObject):
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE, "No [Depex] section or no valid expression in [Depex] section for [%s] module" \
% self.ModuleType, File=self.MetaFile)
- Depex = {}
+ if len(RecordList) != 0 and self.ModuleType == 'USER_DEFINED':
+ for Record in RecordList:
+ if Record[4] not in ['PEIM', 'DXE_DRIVER', 'DXE_SMM_DRIVER']:
+ EdkLogger.error('build', FORMAT_INVALID,
+ "'%s' module must specify the type of [Depex] section" % self.ModuleType,
+ File=self.MetaFile)
+
+ Depex = sdict()
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
+ DepexStr = ReplaceMacro(Record[0], self._Macros, False)
Arch = Record[3]
ModuleType = Record[4]
- TokenList = Record[0].split()
+ TokenList = DepexStr.split()
if (Arch, ModuleType) not in Depex:
Depex[Arch, ModuleType] = []
DepexList = Depex[Arch, ModuleType]
@@ -1882,11 +2581,11 @@ class InfBuildData(ModuleBuildClassObject):
DepexList.append(Module.Guid)
else:
# get the GUID value now
- Value = ProtocolValue(Token, self.Packages)
+ Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)
if Value == None:
- Value = PpiValue(Token, self.Packages)
+ Value = PpiValue(Token, self.Packages, self.MetaFile.Path)
if Value == None:
- Value = GuidValue(Token, self.Packages)
+ Value = GuidValue(Token, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -1902,12 +2601,12 @@ class InfBuildData(ModuleBuildClassObject):
if self._DepexExpression == None:
self._DepexExpression = tdict(False, 2)
RecordList = self._RawData[MODEL_EFI_DEPEX, self._Arch]
- DepexExpression = {}
+ DepexExpression = sdict()
for Record in RecordList:
- Record = ReplaceMacros(Record, GlobalData.gEdkGlobal, False)
+ DepexStr = ReplaceMacro(Record[0], self._Macros, False)
Arch = Record[3]
ModuleType = Record[4]
- TokenList = Record[0].split()
+ TokenList = DepexStr.split()
if (Arch, ModuleType) not in DepexExpression:
DepexExpression[Arch, ModuleType] = ''
for Token in TokenList:
@@ -1916,33 +2615,40 @@ class InfBuildData(ModuleBuildClassObject):
self._DepexExpression[Arch, ModuleType] = DepexExpression[Arch, ModuleType]
return self._DepexExpression
+ def GetGuidsUsedByPcd(self):
+ return self._GuidsUsedByPcd
## Retrieve PCD for given type
def _GetPcd(self, Type):
- Pcds = {}
+ Pcds = sdict()
PcdDict = tdict(True, 4)
- PcdSet = set()
+ PcdList = []
RecordList = self._RawData[Type, self._Arch, self._Platform]
- for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Dummy1, LineNo in RecordList:
+ for TokenSpaceGuid, PcdCName, Setting, Arch, Platform, Id, LineNo in RecordList:
PcdDict[Arch, Platform, PcdCName, TokenSpaceGuid] = (Setting, LineNo)
- PcdSet.add((PcdCName, TokenSpaceGuid))
+ PcdList.append((PcdCName, TokenSpaceGuid))
# get the guid value
if TokenSpaceGuid not in self.Guids:
- Value = GuidValue(TokenSpaceGuid, self.Packages)
+ Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
"Value of Guid [%s] is not found under [Guids] section in" % TokenSpaceGuid,
ExtraData=PackageList, File=self.MetaFile, Line=LineNo)
self.Guids[TokenSpaceGuid] = Value
+ self._GuidsUsedByPcd[TokenSpaceGuid] = Value
+ CommentRecords = self._RawData[MODEL_META_DATA_COMMENT, self._Arch, self._Platform, Id]
+ Comments = []
+ for CmtRec in CommentRecords:
+ Comments.append(CmtRec[0])
+ self._PcdComments[TokenSpaceGuid, PcdCName] = Comments
# resolve PCD type, value, datum info, etc. by getting its definition from package
- for PcdCName, TokenSpaceGuid in PcdSet:
- ValueList = ['', '']
+ for PcdCName, TokenSpaceGuid in PcdList:
+ PcdRealName = PcdCName
Setting, LineNo = PcdDict[self._Arch, self.Platform, PcdCName, TokenSpaceGuid]
if Setting == None:
continue
- TokenList = Setting.split(TAB_VALUE_SPLIT)
- ValueList[0:len(TokenList)] = TokenList
+ ValueList = AnalyzePcdData(Setting)
DefaultValue = ValueList[0]
Pcd = PcdClassObject(
PcdCName,
@@ -1956,6 +2662,30 @@ class InfBuildData(ModuleBuildClassObject):
False,
self.Guids[TokenSpaceGuid]
)
+ if Type == MODEL_PCD_PATCHABLE_IN_MODULE and ValueList[1]:
+ # Patch PCD: TokenSpace.PcdCName|Value|Offset
+ Pcd.Offset = ValueList[1]
+
+ if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
+ for Package in self.Packages:
+ for key in Package.Pcds:
+ if (Package.Pcds[key].TokenCName, Package.Pcds[key].TokenSpaceGuidCName) == (PcdRealName, TokenSpaceGuid):
+ for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
+ Pcd_Type = item[0].split('_')[-1]
+ if Pcd_Type == Package.Pcds[key].Type:
+ Value = Package.Pcds[key]
+ Value.TokenCName = Package.Pcds[key].TokenCName + '_' + Pcd_Type
+ if len(key) == 2:
+ newkey = (Value.TokenCName, key[1])
+ elif len(key) == 3:
+ newkey = (Value.TokenCName, key[1], key[2])
+ del Package.Pcds[key]
+ Package.Pcds[newkey] = Value
+ break
+ else:
+ pass
+ else:
+ pass
# get necessary info from package declaring this PCD
for Package in self.Packages:
@@ -1970,16 +2700,86 @@ class InfBuildData(ModuleBuildClassObject):
if Type == MODEL_PCD_DYNAMIC:
Pcd.Pending = True
for T in ["FixedAtBuild", "PatchableInModule", "FeatureFlag", "Dynamic", "DynamicEx"]:
- if (PcdCName, TokenSpaceGuid, T) in Package.Pcds:
- PcdType = T
+ if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
+ for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
+ if str(item[0]).endswith(T) and (item[0], item[1], T) in Package.Pcds:
+ PcdType = T
+ PcdCName = item[0]
+ break
+ else:
+ pass
break
+ else:
+ if (PcdRealName, TokenSpaceGuid, T) in Package.Pcds:
+ PcdType = T
+ break
+
else:
Pcd.Pending = False
+ if (PcdRealName, TokenSpaceGuid) in GlobalData.MixedPcd:
+ for item in GlobalData.MixedPcd[(PcdRealName, TokenSpaceGuid)]:
+ Pcd_Type = item[0].split('_')[-1]
+ if Pcd_Type == PcdType:
+ PcdCName = item[0]
+ break
+ else:
+ pass
+ else:
+ pass
if (PcdCName, TokenSpaceGuid, PcdType) in Package.Pcds:
PcdInPackage = Package.Pcds[PcdCName, TokenSpaceGuid, PcdType]
Pcd.Type = PcdType
Pcd.TokenValue = PcdInPackage.TokenValue
+
+ #
+ # Check whether the token value exist or not.
+ #
+ if Pcd.TokenValue == None or Pcd.TokenValue == "":
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdRealName, str(Package)),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData=None
+ )
+ #
+ # Check hexadecimal token value length and format.
+ #
+ ReIsValidPcdTokenValue = re.compile(r"^[0][x|X][0]*[0-9a-fA-F]{1,8}$", re.DOTALL)
+ if Pcd.TokenValue.startswith("0x") or Pcd.TokenValue.startswith("0X"):
+ if ReIsValidPcdTokenValue.match(Pcd.TokenValue) == None:
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData=None
+ )
+
+ #
+ # Check decimal token value length and format.
+ #
+ else:
+ try:
+ TokenValueInt = int (Pcd.TokenValue, 10)
+ if (TokenValueInt < 0 or TokenValueInt > 4294967295):
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData=None
+ )
+ except:
+ EdkLogger.error(
+ 'build',
+ FORMAT_INVALID,
+ "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd.TokenValue, TokenSpaceGuid, PcdRealName, str(Package)),
+ File=self.MetaFile, Line=LineNo,
+ ExtraData=None
+ )
+
Pcd.DatumType = PcdInPackage.DatumType
Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize
Pcd.InfDefaultValue = Pcd.DefaultValue
@@ -1989,17 +2789,30 @@ class InfBuildData(ModuleBuildClassObject):
else:
EdkLogger.error(
'build',
- PARSER_ERROR,
- "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),
- File =self.MetaFile, Line=LineNo,
+ FORMAT_INVALID,
+ "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdRealName, self.MetaFile),
+ File=self.MetaFile, Line=LineNo,
ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])
)
Pcds[PcdCName, TokenSpaceGuid] = Pcd
+
return Pcds
- Arch = property(_GetArch, _SetArch)
- Platform = property(_GetPlatform, _SetPlatform)
+ ## check whether current module is binary module
+ def _IsBinaryModule(self):
+ if self.Binaries and not self.Sources:
+ return True
+ elif GlobalData.gIgnoreSource:
+ return True
+ else:
+ return False
+
+ _Macros = property(_GetMacros)
+ Arch = property(_GetArch, _SetArch)
+ Platform = property(_GetPlatform, _SetPlatform)
+ HeaderComments = property(_GetHeaderComments)
+ TailComments = property(_GetTailComments)
AutoGenVersion = property(_GetInfVersion)
BaseName = property(_GetBaseName)
ModuleType = property(_GetModuleType)
@@ -2017,20 +2830,27 @@ class InfBuildData(ModuleBuildClassObject):
ConstructorList = property(_GetConstructor)
DestructorList = property(_GetDestructor)
Defines = property(_GetDefines)
-
+ DxsFile = property(_GetDxsFile)
+
Binaries = property(_GetBinaryFiles)
Sources = property(_GetSourceFiles)
LibraryClasses = property(_GetLibraryClassUses)
Libraries = property(_GetLibraryNames)
Protocols = property(_GetProtocols)
+ ProtocolComments = property(_GetProtocolComments)
Ppis = property(_GetPpis)
+ PpiComments = property(_GetPpiComments)
Guids = property(_GetGuids)
+ GuidComments = property(_GetGuidComments)
Includes = property(_GetIncludes)
Packages = property(_GetPackages)
Pcds = property(_GetPcds)
+ PcdComments = property(_GetPcdComments)
BuildOptions = property(_GetBuildOptions)
Depex = property(_GetDepex)
DepexExpression = property(_GetDepexExpression)
+ IsBinaryModule = property(_IsBinaryModule)
+ IsSupportedArch = property(_IsSupportedArch)
## Database
#
@@ -2043,35 +2863,25 @@ class InfBuildData(ModuleBuildClassObject):
# @prarm RenewDb=False Create new database file if it's already there
#
class WorkspaceDatabase(object):
- # file parser
- _FILE_PARSER_ = {
- MODEL_FILE_INF : InfParser,
- MODEL_FILE_DEC : DecParser,
- MODEL_FILE_DSC : DscParser,
- MODEL_FILE_FDF : None, #FdfParser,
- MODEL_FILE_CIF : None
- }
- # file table
- _FILE_TABLE_ = {
- MODEL_FILE_INF : ModuleTable,
- MODEL_FILE_DEC : PackageTable,
- MODEL_FILE_DSC : PlatformTable,
- }
-
- # default database file path
- _DB_PATH_ = "Conf/.cache/build.db"
#
# internal class used for call corresponding file parser and caching the result
# to avoid unnecessary re-parsing
#
class BuildObjectFactory(object):
+
_FILE_TYPE_ = {
".inf" : MODEL_FILE_INF,
".dec" : MODEL_FILE_DEC,
".dsc" : MODEL_FILE_DSC,
- ".fdf" : MODEL_FILE_FDF,
+ }
+
+ # file parser
+ _FILE_PARSER_ = {
+ MODEL_FILE_INF : InfParser,
+ MODEL_FILE_DEC : DecParser,
+ MODEL_FILE_DSC : DscParser,
}
# convert to xxxBuildData object
@@ -2079,7 +2889,6 @@ class WorkspaceDatabase(object):
MODEL_FILE_INF : InfBuildData,
MODEL_FILE_DEC : DecBuildData,
MODEL_FILE_DSC : DscBuildData,
- MODEL_FILE_FDF : None #FlashDefTable,
}
_CACHE_ = {} # (FilePath, Arch) :