| # # @file |
| # This file is used to create a database used by build tool |
| # |
| # Copyright (c) 2017, Intel Corporation. All rights reserved.<BR> |
| # (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> |
| # 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 |
| # http://opensource.org/licenses/bsd-license.php |
| # |
| # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, |
| # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. |
| # |
| |
| # # Platform build information from DSC file |
| # |
| # This class is used to retrieve information stored in database and convert them |
| # into PlatformBuildClassObject form for easier use for AutoGen. |
| # |
| from Common.String import * |
| from Common.DataType import * |
| from Common.Misc import * |
| from types import * |
| |
| from CommonDataClass.CommonClass import SkuInfoClass |
| |
| from MetaDataTable import * |
| from MetaFileTable import * |
| from MetaFileParser 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 |
| import subprocess |
| from Workspace.BuildClassObject import PlatformBuildClassObject, StructurePcd, PcdClassObject, ModuleBuildClassObject |
| |
| # |
| # Treat CHAR16 as a synonym for UINT16. CHAR16 support is required for VFR C structs |
| # |
| PcdValueInitName = 'PcdValueInit' |
| PcdSupportedBaseTypes = ['BOOLEAN', 'UINT8', 'UINT16', 'UINT32', 'UINT64', 'CHAR16'] |
| PcdSupportedBaseTypeWidth = {'BOOLEAN':8, 'UINT8':8, 'UINT16':16, 'UINT32':32, 'UINT64':64} |
| PcdUnsupportedBaseTypes = ['INT8', 'INT16', 'INT32', 'INT64', 'CHAR8', 'UINTN', 'INTN', 'VOID'] |
| |
| PcdMainCHeader = ''' |
| /** |
| DO NOT EDIT |
| FILE auto-generated |
| **/ |
| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <PcdValueCommon.h> |
| ''' |
| |
| PcdMainCEntry = ''' |
| int |
| main ( |
| int argc, |
| char *argv[] |
| ) |
| { |
| return PcdValueMain (argc, argv); |
| } |
| ''' |
| |
| PcdMakefileHeader = ''' |
| # |
| # DO NOT EDIT |
| # This file is auto-generated by build utility |
| # |
| |
| ''' |
| |
| PcdMakefileEnd = ''' |
| !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.common |
| |
| CFLAGS = $(CFLAGS) /wd4200 /wd4034 /wd4101 |
| |
| LIBS = $(LIB_PATH)\Common.lib |
| |
| !INCLUDE $(BASE_TOOLS_PATH)\Source\C\Makefiles\ms.app |
| ''' |
| |
| PcdGccMakefile = ''' |
| ARCH ?= IA32 |
| MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C |
| LIBS = -lCommon |
| ''' |
| |
| class DscBuildData(PlatformBuildClassObject): |
| # dict used to convert PCD type in database to string used by build tool |
| _PCD_TYPE_STRING_ = { |
| MODEL_PCD_FIXED_AT_BUILD : "FixedAtBuild", |
| MODEL_PCD_PATCHABLE_IN_MODULE : "PatchableInModule", |
| MODEL_PCD_FEATURE_FLAG : "FeatureFlag", |
| MODEL_PCD_DYNAMIC : "Dynamic", |
| MODEL_PCD_DYNAMIC_DEFAULT : "Dynamic", |
| MODEL_PCD_DYNAMIC_HII : "DynamicHii", |
| MODEL_PCD_DYNAMIC_VPD : "DynamicVpd", |
| MODEL_PCD_DYNAMIC_EX : "DynamicEx", |
| MODEL_PCD_DYNAMIC_EX_DEFAULT : "DynamicEx", |
| MODEL_PCD_DYNAMIC_EX_HII : "DynamicExHii", |
| MODEL_PCD_DYNAMIC_EX_VPD : "DynamicExVpd", |
| } |
| |
| # dict used to convert part of [Defines] to members of DscBuildData directly |
| _PROPERTY_ = { |
| # |
| # Required Fields |
| # |
| TAB_DSC_DEFINES_PLATFORM_NAME : "_PlatformName", |
| TAB_DSC_DEFINES_PLATFORM_GUID : "_Guid", |
| TAB_DSC_DEFINES_PLATFORM_VERSION : "_Version", |
| TAB_DSC_DEFINES_DSC_SPECIFICATION : "_DscSpecification", |
| # 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_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 |
| _NullLibraryNumber = 0 |
| |
| # # Constructor of DscBuildData |
| # |
| # Initialize object of DscBuildData |
| # |
| # @param FilePath The path of platform description file |
| # @param RawData The raw data of DSC file |
| # @param BuildDataBase Database used to retrieve module/package information |
| # @param Arch The target architecture |
| # @param Platform (not used for DscBuildData) |
| # @param Macros Macros used for replacement in DSC file |
| # |
| 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._Target = Target |
| self._Toolchain = Toolchain |
| self._Clear() |
| self._HandleOverridePath() |
| if os.getenv("WORKSPACE"): |
| self.OutputPath = os.path.join(os.getenv("WORKSPACE"), 'Build', PcdValueInitName) |
| else: |
| self.OutputPath = os.path.dirname(self.DscFile) |
| self.DefaultStores = None |
| self.SkuIdMgr = SkuClass(self.SkuIdentifier, self.SkuIds) |
| arraystr = self.SkuIdMgr.DumpSkuIdArrary() |
| |
| # # XXX[key] = value |
| def __setitem__(self, key, value): |
| self.__dict__[self._PROPERTY_[key]] = value |
| |
| # # value = XXX[key] |
| def __getitem__(self, key): |
| return self.__dict__[self._PROPERTY_[key]] |
| |
| # # "in" test support |
| def __contains__(self, key): |
| return key in self._PROPERTY_ |
| |
| # # Set all internal used members of DscBuildData to None |
| def _Clear(self): |
| self._Header = None |
| self._PlatformName = None |
| self._Guid = None |
| self._Version = None |
| self._DscSpecification = None |
| self._OutputDirectory = None |
| 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 |
| self._RtBaseAddress = None |
| self._SkuIds = None |
| self._Modules = None |
| 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 |
| self.DefaultStores = 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[6] |
| LineNo = Record[7] |
| 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): |
| return self._Arch |
| |
| # # Set architecture |
| # |
| # Changing the default ARCH to another may affect all other information |
| # because all information in a platform may be ARCH-related. That's |
| # why we need to clear all internal used members, in order to cause all |
| # information to be re-retrieved. |
| # |
| # @param Value The value of ARCH |
| # |
| def _SetArch(self, Value): |
| if self._Arch == Value: |
| return |
| self._Arch = Value |
| self._Clear() |
| |
| # # Retrieve all information in [Defines] section |
| # |
| # (Retriving all [Defines] information in one-shot is just to save time.) |
| # |
| def _GetHeaderInfo(self): |
| RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch] |
| for Record in RecordList: |
| Name = Record[1] |
| # items defined _PROPERTY_ don't need additional processing |
| |
| # some special items in [Defines] section need special treatment |
| 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[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[2], TAB_VALUE_SPLIT) |
| elif Name == TAB_DSC_DEFINES_BUILD_TARGETS: |
| self._BuildTargets = GetSplitValueList(Record[2]) |
| elif Name == TAB_DSC_DEFINES_SKUID_IDENTIFIER: |
| if self._SkuName == None: |
| 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: |
| 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[2]) |
| except: |
| EdkLogger.error("build", FORMAT_INVALID, "Invalid GUID format for VPD_TOOL_GUID", File=self.MetaFile) |
| 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' |
| |
| # # Retrieve platform name |
| def _GetPlatformName(self): |
| if self._PlatformName == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._PlatformName == None: |
| EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_NAME", File=self.MetaFile) |
| return self._PlatformName |
| |
| # # Retrieve file guid |
| def _GetFileGuid(self): |
| if self._Guid == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._Guid == None: |
| EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_GUID", File=self.MetaFile) |
| return self._Guid |
| |
| # # Retrieve platform version |
| def _GetVersion(self): |
| if self._Version == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._Version == None: |
| EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No PLATFORM_VERSION", File=self.MetaFile) |
| return self._Version |
| |
| # # Retrieve platform description file version |
| def _GetDscSpec(self): |
| if self._DscSpecification == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._DscSpecification == None: |
| EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No DSC_SPECIFICATION", File=self.MetaFile) |
| return self._DscSpecification |
| |
| # # Retrieve OUTPUT_DIRECTORY |
| def _GetOutpuDir(self): |
| if self._OutputDirectory == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._OutputDirectory == None: |
| self._OutputDirectory = os.path.join("Build", self._PlatformName) |
| return self._OutputDirectory |
| |
| # # Retrieve SUPPORTED_ARCHITECTURES |
| def _GetSupArch(self): |
| if self._SupArchList == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._SupArchList == None: |
| EdkLogger.error('build', ATTRIBUTE_NOT_AVAILABLE, "No SUPPORTED_ARCHITECTURES", File=self.MetaFile) |
| return self._SupArchList |
| |
| # # Retrieve BUILD_TARGETS |
| def _GetBuildTarget(self): |
| if self._BuildTargets == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._BuildTargets == None: |
| 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): |
| self._SkuName = 'DEFAULT' |
| return self._SkuName |
| |
| # # Override SKUID_IDENTIFIER |
| def _SetSkuName(self, Value): |
| self._SkuName = Value |
| self._Pcds = None |
| |
| def _GetFdfFile(self): |
| if self._FlashDefinition == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._FlashDefinition == None: |
| 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: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._BuildNumber == None: |
| self._BuildNumber = '' |
| return self._BuildNumber |
| |
| # # Retrieve MAKEFILE_NAME |
| def _GetMakefileName(self): |
| if self._MakefileName == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._MakefileName == None: |
| self._MakefileName = '' |
| return self._MakefileName |
| |
| # # Retrieve BsBaseAddress |
| def _GetBsBaseAddress(self): |
| if self._BsBaseAddress == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._BsBaseAddress == None: |
| self._BsBaseAddress = '' |
| return self._BsBaseAddress |
| |
| # # Retrieve RtBaseAddress |
| def _GetRtBaseAddress(self): |
| if self._RtBaseAddress == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._RtBaseAddress == None: |
| self._RtBaseAddress = '' |
| return self._RtBaseAddress |
| |
| # # Retrieve the top address for the load fix address |
| def _GetLoadFixAddress(self): |
| if self._LoadFixAddress == None: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| |
| if self._LoadFixAddress == None: |
| 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: |
| if self._Header == None: |
| self._GetHeaderInfo() |
| if self._VpdToolGuid == None: |
| self._VpdToolGuid = '' |
| return self._VpdToolGuid |
| |
| # # Retrieve [SkuIds] section information |
| def _GetSkuIds(self): |
| if self._SkuIds == None: |
| 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', |
| File=self.MetaFile, Line=Record[-1]) |
| if Record[1] in [None, '']: |
| EdkLogger.error('build', FORMAT_INVALID, 'No Sku ID name', |
| File=self.MetaFile, Line=Record[-1]) |
| self._SkuIds[Record[1]] = (Record[0],Record[1],Record[2]) |
| if 'DEFAULT' not in self._SkuIds: |
| self._SkuIds['DEFAULT'] = ("0","DEFAULT","DEFAULT") |
| if 'COMMON' not in self._SkuIds: |
| self._SkuIds['COMMON'] = ("0","DEFAULT","DEFAULT") |
| return self._SkuIds |
| def ToInt(self,intstr): |
| return int(intstr,16) if intstr.upper().startswith("0X") else int(intstr) |
| def _GetDefaultStores(self): |
| if self.DefaultStores == None: |
| self.DefaultStores = sdict() |
| RecordList = self._RawData[MODEL_EFI_DEFAULT_STORES, self._Arch] |
| for Record in RecordList: |
| if Record[0] in [None, '']: |
| EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID number', |
| File=self.MetaFile, Line=Record[-1]) |
| if Record[1] in [None, '']: |
| EdkLogger.error('build', FORMAT_INVALID, 'No DefaultStores ID name', |
| File=self.MetaFile, Line=Record[-1]) |
| self.DefaultStores[Record[1]] = (self.ToInt(Record[0]),Record[1]) |
| if TAB_DEFAULT_STORES_DEFAULT not in self.DefaultStores: |
| self.DefaultStores[TAB_DEFAULT_STORES_DEFAULT] = (0,TAB_DEFAULT_STORES_DEFAULT) |
| GlobalData.gDefaultStores = self.DefaultStores.keys() |
| if GlobalData.gDefaultStores: |
| GlobalData.gDefaultStores.sort() |
| return self.DefaultStores |
| |
| # # Retrieve [Components] section information |
| def _GetModules(self): |
| if self._Modules != None: |
| return self._Modules |
| |
| self._Modules = sdict() |
| RecordList = self._RawData[MODEL_META_DATA_COMPONENT, self._Arch] |
| 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[6] |
| LineNo = Record[7] |
| |
| # check the file validation |
| ErrorCode, ErrorInfo = ModuleFile.Validate('.inf') |
| if ErrorCode != 0: |
| EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, |
| ExtraData=ErrorInfo) |
| # Check duplication |
| # 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 private library instance |
| RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, ModuleId] |
| for Record in RecordList: |
| LibraryClass = Record[0] |
| LibraryPath = PathClass(NormPath(Record[1], Macros), GlobalData.gWorkspace, Arch=self._Arch) |
| LineNo = Record[-1] |
| |
| # check the file validation |
| ErrorCode, ErrorInfo = LibraryPath.Validate('.inf') |
| if ErrorCode != 0: |
| EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, |
| ExtraData=ErrorInfo) |
| |
| if LibraryClass == '' or LibraryClass == 'NULL': |
| self._NullLibraryNumber += 1 |
| LibraryClass = 'NULL%d' % self._NullLibraryNumber |
| EdkLogger.verbose("Found forced library for %s\n\t%s [%s]" % (ModuleFile, LibraryPath, LibraryClass)) |
| Module.LibraryClasses[LibraryClass] = LibraryPath |
| if LibraryPath not in self.LibraryInstances: |
| self.LibraryInstances.append(LibraryPath) |
| |
| # get module private PCD setting |
| for Type in [MODEL_PCD_FIXED_AT_BUILD, MODEL_PCD_PATCHABLE_IN_MODULE, \ |
| MODEL_PCD_FEATURE_FLAG, MODEL_PCD_DYNAMIC, MODEL_PCD_DYNAMIC_EX]: |
| RecordList = self._RawData[Type, self._Arch, None, ModuleId] |
| for TokenSpaceGuid, PcdCName, Setting, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList: |
| TokenList = GetSplitValueList(Setting) |
| DefaultValue = TokenList[0] |
| if len(TokenList) > 1: |
| MaxDatumSize = TokenList[1] |
| else: |
| MaxDatumSize = '' |
| TypeString = self._PCD_TYPE_STRING_[Type] |
| Pcd = PcdClassObject( |
| PcdCName, |
| TokenSpaceGuid, |
| TypeString, |
| '', |
| DefaultValue, |
| '', |
| MaxDatumSize, |
| {}, |
| False, |
| None |
| ) |
| Module.Pcds[PcdCName, TokenSpaceGuid] = Pcd |
| |
| # get module private build options |
| RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, None, ModuleId] |
| for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4,Dummy5 in RecordList: |
| if (ToolChainFamily, ToolChain) not in Module.BuildOptions: |
| Module.BuildOptions[ToolChainFamily, ToolChain] = Option |
| else: |
| 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 <Defines> 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 |
| |
| # # Retrieve all possible library instances used in this platform |
| def _GetLibraryInstances(self): |
| if self._LibraryInstances == None: |
| self._GetLibraryClasses() |
| return self._LibraryInstances |
| |
| # # Retrieve [LibraryClasses] information |
| def _GetLibraryClasses(self): |
| if self._LibraryClasses == None: |
| self._LibraryInstances = [] |
| # |
| # tdict is a special dict kind of type, used for selecting correct |
| # library instance for given library class and module type |
| # |
| LibraryClassDict = tdict(True, 3) |
| # track all library class names |
| LibraryClassSet = set() |
| RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch, None, -1] |
| Macros = self._Macros |
| for Record in RecordList: |
| LibraryClass, LibraryInstance, Dummy, Arch, ModuleType, Dummy,Dummy, LineNo = Record |
| if LibraryClass == '' or LibraryClass == 'NULL': |
| self._NullLibraryNumber += 1 |
| LibraryClass = 'NULL%d' % self._NullLibraryNumber |
| EdkLogger.verbose("Found forced library for arch=%s\n\t%s [%s]" % (Arch, LibraryInstance, LibraryClass)) |
| LibraryClassSet.add(LibraryClass) |
| LibraryInstance = PathClass(NormPath(LibraryInstance, Macros), GlobalData.gWorkspace, Arch=self._Arch) |
| # check the file validation |
| ErrorCode, ErrorInfo = LibraryInstance.Validate('.inf') |
| if ErrorCode != 0: |
| EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, |
| ExtraData=ErrorInfo) |
| |
| if ModuleType != 'COMMON' and ModuleType not in SUP_MODULE_LIST: |
| EdkLogger.error('build', OPTION_UNKNOWN, "Unknown module type [%s]" % ModuleType, |
| File=self.MetaFile, ExtraData=LibraryInstance, Line=LineNo) |
| LibraryClassDict[Arch, ModuleType, LibraryClass] = LibraryInstance |
| if LibraryInstance not in self._LibraryInstances: |
| self._LibraryInstances.append(LibraryInstance) |
| |
| # resolve the specific library instance for each class and each module type |
| self._LibraryClasses = tdict(True) |
| for LibraryClass in LibraryClassSet: |
| # try all possible module types |
| for ModuleType in SUP_MODULE_LIST: |
| LibraryInstance = LibraryClassDict[self._Arch, ModuleType, LibraryClass] |
| if LibraryInstance == None: |
| continue |
| self._LibraryClasses[LibraryClass, ModuleType] = LibraryInstance |
| |
| # 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) |
| LineNo = Record[-1] |
| # check the file validation |
| ErrorCode, ErrorInfo = File.Validate('.inf') |
| if ErrorCode != 0: |
| EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=LineNo, |
| ExtraData=ErrorInfo) |
| if File not in self._LibraryInstances: |
| self._LibraryInstances.append(File) |
| # |
| # we need the module name as the library class name, so we have |
| # to parse it here. (self._Bdb[] will trigger a file parse if it |
| # hasn't been parsed) |
| # |
| 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 and "." in TokenSpaceGuid and (TokenSpaceGuid.split(".")[1], TokenSpaceGuid.split(".")[0]) 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 |
| |
| def _FilterPcdBySkuUsage(self,Pcds): |
| available_sku = self.SkuIdMgr.AvailableSkuIdSet |
| sku_usage = self.SkuIdMgr.SkuUsageType |
| if sku_usage == SkuClass.SINGLE: |
| for pcdname in Pcds: |
| pcd = Pcds[pcdname] |
| Pcds[pcdname].SkuInfoList = {"DEFAULT":pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku} |
| else: |
| for pcdname in Pcds: |
| pcd = Pcds[pcdname] |
| Pcds[pcdname].SkuInfoList = {skuid:pcd.SkuInfoList[skuid] for skuid in pcd.SkuInfoList if skuid in available_sku} |
| return Pcds |
| # # Retrieve all PCD settings in platform |
| def _GetPcds(self): |
| if self._Pcds == None: |
| 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)) |
| self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_DEFAULT)) |
| self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_HII)) |
| self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_VPD)) |
| self._Pcds.update(self._GetDynamicPcd(MODEL_PCD_DYNAMIC_EX_DEFAULT)) |
| self._Pcds.update(self._GetDynamicHiiPcd(MODEL_PCD_DYNAMIC_EX_HII)) |
| self._Pcds.update(self._GetDynamicVpdPcd(MODEL_PCD_DYNAMIC_EX_VPD)) |
| |
| self._Pcds = self.CompletePcdValues(self._Pcds) |
| self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds) |
| self._Pcds = self._FilterPcdBySkuUsage(self._Pcds) |
| return self._Pcds |
| |
| def _dumpPcdInfo(self,Pcds): |
| for pcd in Pcds: |
| pcdobj = Pcds[pcd] |
| if not pcdobj.TokenCName.startswith("Test"): |
| continue |
| for skuid in pcdobj.SkuInfoList: |
| if pcdobj.Type in (self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]): |
| for storename in pcdobj.SkuInfoList[skuid].DefaultStoreDict: |
| print "PcdCName: %s, SkuName: %s, StoreName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,storename,str(pcdobj.SkuInfoList[skuid].DefaultStoreDict[storename])) |
| else: |
| print "PcdCName: %s, SkuName: %s, Value: %s" % (".".join((pcdobj.TokenSpaceGuidCName, pcdobj.TokenCName)), skuid,str(pcdobj.SkuInfoList[skuid].DefaultValue)) |
| # # Retrieve [BuildOptions] |
| def _GetBuildOptions(self): |
| if self._BuildOptions == None: |
| self._BuildOptions = sdict() |
| # |
| # Retrieve build option for EDKII and EDK style module |
| # |
| 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,Dummy5 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,Dummy5 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] |
| |
| def GetStructurePcdInfo(self, PcdSet): |
| structure_pcd_data = {} |
| for item in PcdSet: |
| if (item[0],item[1]) not in structure_pcd_data: |
| structure_pcd_data[(item[0],item[1])] = [] |
| structure_pcd_data[(item[0],item[1])].append(item) |
| |
| return structure_pcd_data |
| |
| def UpdateStructuredPcds(self, TypeList, AllPcds): |
| Pcds = AllPcds |
| DefaultStoreMgr = DefaultStore(self.DefaultStores) |
| SkuIds = set([skuid for pcdobj in AllPcds.values() for skuid in pcdobj.SkuInfoList.keys()]) |
| DefaultStores = set([storename for pcdobj in AllPcds.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()]) |
| |
| S_PcdSet = [] |
| # Find out all possible PCD candidates for self._Arch |
| RecordList = [] |
| |
| for Type in TypeList: |
| RecordList.extend(self._RawData[Type, self._Arch]) |
| |
| for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, default_store, Dummy4,Dummy5 in RecordList: |
| SkuName = 'DEFAULT' if SkuName == 'COMMON' else SkuName |
| if SkuName not in SkuIds: |
| continue |
| |
| if SkuName in SkuIds and "." in TokenSpaceGuid: |
| S_PcdSet.append(( TokenSpaceGuid.split(".")[0],TokenSpaceGuid.split(".")[1], PcdCName,SkuName, default_store,Dummy5, AnalyzePcdExpression(Setting)[0])) |
| |
| # handle pcd value override |
| StrPcdSet = self.GetStructurePcdInfo(S_PcdSet) |
| S_pcd_set = {} |
| for str_pcd in StrPcdSet: |
| str_pcd_obj = Pcds.get((str_pcd[1], str_pcd[0]), None) |
| str_pcd_dec = self._DecPcds.get((str_pcd[1], str_pcd[0]), None) |
| if str_pcd_dec: |
| str_pcd_obj_str = StructurePcd() |
| str_pcd_obj_str.copy(str_pcd_dec) |
| if str_pcd_obj: |
| str_pcd_obj_str.copy(str_pcd_obj) |
| if str_pcd_obj.DefaultValue: |
| str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue |
| for str_pcd_data in StrPcdSet[str_pcd]: |
| if str_pcd_data[3] in SkuIds: |
| str_pcd_obj_str.AddOverrideValue(str_pcd_data[2], str(str_pcd_data[6]), 'DEFAULT' if str_pcd_data[3] == 'COMMON' else str_pcd_data[3],'STANDARD' if str_pcd_data[4] == 'COMMON' else str_pcd_data[4], self.MetaFile.File,LineNo=str_pcd_data[5]) |
| S_pcd_set[str_pcd[1], str_pcd[0]] = str_pcd_obj_str |
| # Add the Structure PCD that only defined in DEC, don't have override in DSC file |
| for Pcd in self._DecPcds: |
| if type (self._DecPcds[Pcd]) is StructurePcd: |
| if Pcd not in S_pcd_set: |
| str_pcd_obj_str = StructurePcd() |
| str_pcd_obj_str.copy(self._DecPcds[Pcd]) |
| str_pcd_obj = Pcds.get(Pcd, None) |
| if str_pcd_obj: |
| str_pcd_obj_str.copy(str_pcd_obj) |
| if str_pcd_obj.DefaultValue: |
| str_pcd_obj_str.DefaultFromDSC = str_pcd_obj.DefaultValue |
| S_pcd_set[Pcd] = str_pcd_obj_str |
| if S_pcd_set: |
| GlobalData.gStructurePcd[self.Arch] = S_pcd_set |
| for stru_pcd in S_pcd_set.values(): |
| if stru_pcd.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]: |
| continue |
| if stru_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: |
| for skuid in SkuIds: |
| nextskuid = skuid |
| if skuid not in stru_pcd.SkuOverrideValues: |
| while nextskuid not in stru_pcd.SkuOverrideValues: |
| nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) |
| stru_pcd.SkuOverrideValues[skuid] = {} |
| PcdDefaultStoreSet = set([defaultstorename for defaultstorename in stru_pcd.SkuOverrideValues[skuid]]) |
| mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet) |
| for defaultstoreid in DefaultStores: |
| if defaultstoreid not in stru_pcd.SkuOverrideValues[skuid]: |
| stru_pcd.SkuOverrideValues[skuid][defaultstoreid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid][mindefaultstorename]) |
| for skuid in SkuIds: |
| if skuid in stru_pcd.SkuOverrideValues: |
| continue |
| nextskuid = self.SkuIdMgr.GetNextSkuId(skuid) |
| while nextskuid not in stru_pcd.SkuOverrideValues: |
| nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) |
| stru_pcd.SkuOverrideValues[skuid] = copy.deepcopy(stru_pcd.SkuOverrideValues[nextskuid] ) |
| Str_Pcd_Values = self.GenerateByteArrayValue(S_pcd_set) |
| if Str_Pcd_Values: |
| for (skuname,StoreName,PcdGuid,PcdName,PcdValue) in Str_Pcd_Values: |
| str_pcd_obj = S_pcd_set.get((PcdName, PcdGuid)) |
| if str_pcd_obj is None: |
| raise |
| if str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: |
| if skuname not in str_pcd_obj.SkuInfoList: |
| str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], HiiDefaultValue=PcdValue, DefaultStore = {StoreName:PcdValue}) |
| else: |
| str_pcd_obj.SkuInfoList[skuname].HiiDefaultValue = PcdValue |
| str_pcd_obj.SkuInfoList[skuname].DefaultStoreDict.update({StoreName:PcdValue}) |
| elif str_pcd_obj.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], |
| self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]: |
| if skuname in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'): |
| str_pcd_obj.DefaultValue = PcdValue |
| else: |
| if skuname not in str_pcd_obj.SkuInfoList: |
| str_pcd_obj.SkuInfoList[skuname] = SkuInfoClass(SkuIdName=skuname, SkuId=self.SkuIds[skuname][0], DefaultValue=PcdValue) |
| else: |
| str_pcd_obj.SkuInfoList[skuname].DefaultValue = PcdValue |
| for str_pcd_obj in S_pcd_set.values(): |
| if str_pcd_obj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: |
| continue |
| PcdDefaultStoreSet = set([defaultstorename for skuobj in str_pcd_obj.SkuInfoList.values() for defaultstorename in skuobj.DefaultStoreDict]) |
| DefaultStoreObj = DefaultStore(self._GetDefaultStores()) |
| mindefaultstorename = DefaultStoreObj.GetMin(PcdDefaultStoreSet) |
| str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].HiiDefaultValue = str_pcd_obj.SkuInfoList[self.SkuIdMgr.SystemSkuId].DefaultStoreDict[mindefaultstorename] |
| |
| for str_pcd_obj in S_pcd_set.values(): |
| str_pcd_obj.MaxDatumSize = self.GetStructurePcdMaxSize(str_pcd_obj) |
| Pcds[str_pcd_obj.TokenCName, str_pcd_obj.TokenSpaceGuidCName] = str_pcd_obj |
| |
| return Pcds |
| |
| # # Retrieve non-dynamic PCD settings |
| # |
| # @param Type PCD type |
| # |
| # @retval a dict object contains settings of given PCD type |
| # |
| def _GetPcd(self, Type): |
| Pcds = sdict() |
| # |
| # tdict is a special dict kind of type, used for selecting correct |
| # PCD settings for certain ARCH |
| # |
| |
| |
| 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,Dummy5 in RecordList: |
| if SkuName in (self.SkuIdMgr.SystemSkuId, 'DEFAULT', 'COMMON'): |
| if "." not in TokenSpaceGuid: |
| PcdSet.add((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) |
| PcdDict[Arch, PcdCName, TokenSpaceGuid, SkuName] = Setting |
| |
| for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdSet: |
| Setting = PcdDict[self._Arch, PcdCName, TokenSpaceGuid, SkuName] |
| if Setting == None: |
| continue |
| 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 self.SkuIdMgr.SystemSkuId in PcdSetting: |
| PcdValue, DatumType, MaxDatumSize = PcdSetting[self.SkuIdMgr.SystemSkuId] |
| |
| Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( |
| PcdCName, |
| TokenSpaceGuid, |
| self._PCD_TYPE_STRING_[Type], |
| DatumType, |
| PcdValue, |
| '', |
| MaxDatumSize, |
| {}, |
| False, |
| None |
| ) |
| |
| |
| return Pcds |
| |
| def GetStructurePcdMaxSize(self, str_pcd): |
| pcd_default_value = str_pcd.DefaultValue |
| sku_values = [skuobj.HiiDefaultValue if str_pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]] else skuobj.DefaultValue for skuobj in str_pcd.SkuInfoList.values()] |
| sku_values.append(pcd_default_value) |
| |
| def get_length(value): |
| Value = value.strip() |
| if Value.startswith('GUID') and Value.endswith(')'): |
| return 16 |
| if Value.startswith('L"') and Value.endswith('"'): |
| return len(Value[2:-1]) |
| if Value[0] == '"' and Value[-1] == '"': |
| return len(Value) - 2 |
| if Value[0] == '{' and Value[-1] == '}': |
| return len(Value.split(",")) |
| if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1: |
| return len(list(Value[2:-1])) |
| if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1: |
| return len(Value) - 2 |
| return len(Value) |
| |
| return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]])) |
| |
| def IsFieldValueAnArray (self, Value): |
| Value = Value.strip() |
| if Value.startswith('GUID') and Value.endswith(')'): |
| return True |
| if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1: |
| return True |
| if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1: |
| return True |
| if Value[0] == '{' and Value[-1] == '}': |
| return True |
| if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1: |
| print 'foo = ', list(Value[2:-1]) |
| return True |
| if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1: |
| print 'bar = ', list(Value[1:-1]) |
| return True |
| return False |
| |
| def ExecuteCommand (self, Command): |
| try: |
| Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) |
| except: |
| print 'ERROR: Can not execute command:', Command |
| sys.exit(1) |
| Result = Process.communicate() |
| if Process.returncode <> 0: |
| print 'ERROR: Can not collect output from command:', Command |
| return Result[0], Result[1] |
| |
| def IntToCString(self, Value, ValueSize): |
| Result = '"' |
| if not isinstance (Value, str): |
| for Index in range(0, ValueSize): |
| Result = Result + '\\x%02x' % (Value & 0xff) |
| Value = Value >> 8 |
| Result = Result + '"' |
| return Result |
| |
| def GenerateInitializeFunc(self, SkuName, DefaultStoreName, Pcd, InitByteValue, CApp): |
| OverrideValues = {DefaultStoreName:""} |
| if Pcd.SkuOverrideValues: |
| OverrideValues = Pcd.SkuOverrideValues[SkuName] |
| for DefaultStoreName in OverrideValues.keys(): |
| CApp = CApp + 'void\n' |
| CApp = CApp + 'Initialize_%s_%s_%s_%s(\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) |
| CApp = CApp + ' void\n' |
| CApp = CApp + ' )\n' |
| CApp = CApp + '{\n' |
| CApp = CApp + ' UINT32 Size;\n' |
| CApp = CApp + ' UINT32 FieldSize;\n' |
| CApp = CApp + ' UINT8 *Value;\n' |
| CApp = CApp + ' UINT32 OriginalSize;\n' |
| CApp = CApp + ' VOID *OriginalPcd;\n' |
| CApp = CApp + ' %s *Pcd;\n' % (Pcd.DatumType) |
| CApp = CApp + '\n' |
| InitByteValue += '%s.%s.%s.%s|%s|%s\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, Pcd.DatumType, Pcd.DefaultValue) |
| |
| # |
| # Get current PCD value and size |
| # |
| CApp = CApp + ' OriginalPcd = PcdGetPtr (%s, %s, %s, %s, &OriginalSize);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) |
| CApp = CApp + ' printf("OriginalSize = %d\\n", OriginalSize);\n' |
| |
| |
| # |
| # Determine the size of the PCD. For simple structures, sizeof(TYPE) provides |
| # the correct value. For structures with a flexible array member, the flexible |
| # array member is detected, and the size is based on the highest index used with |
| # the flexible array member. The flexible array member must be the last field |
| # in a structure. The size formula for this case is: |
| # OFFSET_OF(FlexbleArrayField) + sizeof(FlexibleArray[0]) * (HighestIndex + 1) |
| # |
| CApp = CApp + ' Size = sizeof(%s);\n' % (Pcd.DatumType) |
| CApp = CApp + ' printf("Size = %d\\n", Size);\n' |
| for FieldList in [Pcd.DefaultValues, OverrideValues.get(DefaultStoreName)]: |
| if not FieldList: |
| continue |
| for FieldName in FieldList: |
| FieldName = "." + FieldName |
| IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) |
| if IsArray: |
| Value, ValueSize = ParseFieldValue (FieldList[FieldName.strip(".")][0]) |
| CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d / __ARRAY_ELEMENT_SIZE(%s, %s));\n' % (Pcd.DatumType, FieldName.strip("."), ValueSize, Pcd.DatumType, FieldName.strip(".")); |
| CApp = CApp + ' printf("Size = %d\\n", Size);\n' |
| else: |
| NewFieldName = '' |
| while '[' in FieldName: |
| NewFieldName = NewFieldName + FieldName.split('[', 1)[0] + '[0]' |
| ArrayIndex = int(FieldName.split('[', 1)[1].split(']', 1)[0]) |
| FieldName = FieldName.split(']', 1)[1] |
| FieldName = NewFieldName + FieldName |
| while '[' in FieldName: |
| FieldName = FieldName.rsplit('[', 1)[0] |
| CApp = CApp + ' __FLEXIBLE_SIZE(Size, %s, %s, %d);\n' % (Pcd.DatumType, FieldName.strip("."), ArrayIndex + 1) |
| CApp = CApp + ' printf("Size = %d\\n", Size);\n' |
| CApp = CApp + ' printf("Size = %d\\n", Size);\n' |
| |
| # |
| # Allocate and zero buffer for the PCD |
| # Must handle cases where current value is smaller, larger, or same size |
| # Always keep that larger one as the current size |
| # |
| CApp = CApp + ' Size = (OriginalSize > Size ? OriginalSize : Size);\n' |
| CApp = CApp + ' printf("Size = %d\\n", Size);\n' |
| CApp = CApp + ' Pcd = (%s *)malloc (Size);\n' % (Pcd.DatumType) |
| CApp = CApp + ' memset (Pcd, 0, Size);\n' |
| |
| # |
| # Copy current PCD value into allocated buffer. |
| # |
| CApp = CApp + ' memcpy (Pcd, OriginalPcd, OriginalSize);\n' |
| |
| # |
| # Assign field values in PCD |
| # |
| for FieldList in [Pcd.DefaultValues, Pcd.DefaultFromDSC,OverrideValues.get(DefaultStoreName)]: |
| if not FieldList: |
| continue |
| if Pcd.DefaultFromDSC and FieldList == Pcd.DefaultFromDSC: |
| IsArray = self.IsFieldValueAnArray(FieldList) |
| Value, ValueSize = ParseFieldValue (FieldList) |
| if isinstance(Value, str): |
| CApp = CApp + ' Pcd = %s; // From DSC Default Value %s\n' % (Value, Pcd.DefaultFromDSC) |
| elif IsArray: |
| # |
| # Use memcpy() to copy value into field |
| # |
| CApp = CApp + ' Value = %s; // From DSC Default Value %s\n' % (self.IntToCString(Value, ValueSize), Pcd.DefaultFromDSC) |
| CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) |
| continue |
| |
| for FieldName in FieldList: |
| IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) |
| try: |
| Value, ValueSize = ParseFieldValue (FieldList[FieldName][0]) |
| except Exception: |
| print FieldList[FieldName][0] |
| if isinstance(Value, str): |
| CApp = CApp + ' Pcd->%s = %s; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) |
| elif IsArray: |
| # |
| # Use memcpy() to copy value into field |
| # |
| CApp = CApp + ' FieldSize = __FIELD_SIZE(%s, %s);\n' % (Pcd.DatumType, FieldName) |
| CApp = CApp + ' printf("FieldSize = %d\\n", FieldSize);\n' |
| CApp = CApp + ' Value = %s; // From %s Line %d Value %s\n' % (self.IntToCString(Value, ValueSize), FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) |
| CApp = CApp + ' memcpy (&Pcd->%s[0], Value, (FieldSize > 0 && FieldSize < %d) ? FieldSize : %d);\n' % (FieldName, ValueSize, ValueSize) |
| else: |
| if ValueSize > 4: |
| CApp = CApp + ' Pcd->%s = %dULL; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) |
| else: |
| CApp = CApp + ' Pcd->%s = %d; // From %s Line %d Value %s\n' % (FieldName, Value, FieldList[FieldName][1], FieldList[FieldName][2], FieldList[FieldName][0]) |
| |
| # |
| # Set new PCD value and size |
| # |
| CApp = CApp + ' PcdSetPtr (%s, %s, %s, %s, Size, (UINT8 *)Pcd);\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) |
| |
| # |
| # Free PCD |
| # |
| CApp = CApp + ' free (Pcd);\n' |
| CApp = CApp + '}\n' |
| CApp = CApp + '\n' |
| return InitByteValue, CApp |
| |
| def GenerateByteArrayValue (self, StructuredPcds): |
| # |
| # Generate/Compile/Run C application to determine if there are any flexible array members |
| # |
| if not StructuredPcds: |
| return |
| |
| InitByteValue = "" |
| CApp = PcdMainCHeader |
| |
| Includes = {} |
| for PcdName in StructuredPcds: |
| Pcd = StructuredPcds[PcdName] |
| IncludeFile = Pcd.StructuredPcdIncludeFile |
| if IncludeFile not in Includes: |
| Includes[IncludeFile] = True |
| CApp = CApp + '#include <%s>\n' % (IncludeFile) |
| CApp = CApp + '\n' |
| |
| for PcdName in StructuredPcds: |
| Pcd = StructuredPcds[PcdName] |
| if not Pcd.SkuOverrideValues: |
| InitByteValue, CApp = self.GenerateInitializeFunc(self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd, InitByteValue, CApp) |
| else: |
| for SkuName in Pcd.SkuOverrideValues: |
| for DefaultStoreName in Pcd.DefaultStoreName: |
| Pcd = StructuredPcds[PcdName] |
| InitByteValue, CApp = self.GenerateInitializeFunc(SkuName, DefaultStoreName, Pcd, InitByteValue, CApp) |
| |
| CApp = CApp + 'VOID\n' |
| CApp = CApp + 'PcdEntryPoint(\n' |
| CApp = CApp + ' VOID\n' |
| CApp = CApp + ' )\n' |
| CApp = CApp + '{\n' |
| for Pcd in StructuredPcds.values(): |
| if not Pcd.SkuOverrideValues: |
| CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (self.SkuIdMgr.SystemSkuId, 'STANDARD', Pcd.TokenSpaceGuidCName, Pcd.TokenCName) |
| else: |
| for SkuName in Pcd.SkuOverrideValues: |
| for DefaultStoreName in Pcd.SkuOverrideValues[SkuName]: |
| CApp = CApp + ' Initialize_%s_%s_%s_%s();\n' % (SkuName, DefaultStoreName, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) |
| CApp = CApp + '}\n' |
| |
| CApp = CApp + PcdMainCEntry + '\n' |
| |
| if not os.path.exists(self.OutputPath): |
| os.makedirs(self.OutputPath) |
| CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName) |
| File = open (CAppBaseFileName + '.c', 'w') |
| File.write(CApp) |
| File.close() |
| |
| MakeApp = PcdMakefileHeader |
| if sys.platform == "win32": |
| MakeApp = MakeApp + 'ARCH = IA32\nAPPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s\%s.obj\n' % (self.OutputPath, PcdValueInitName) + 'INC = ' |
| else: |
| MakeApp = MakeApp + PcdGccMakefile |
| MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \ |
| 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'BUILD_CFLAGS += -Wno-error\n' + 'INCLUDE +=' |
| |
| PlatformInc = {} |
| for Cache in self._Bdb._CACHE_.values(): |
| if Cache.MetaFile.Ext.lower() != '.dec': |
| continue |
| if Cache.Includes: |
| if str(Cache.MetaFile.Path) not in PlatformInc: |
| PlatformInc[str(Cache.MetaFile.Path)] = Cache.Includes |
| |
| PcdDependDEC = [] |
| for Pcd in StructuredPcds.values(): |
| for PackageDec in Pcd.PackageDecs: |
| Package = os.path.normpath(mws.join(GlobalData.gWorkspace, PackageDec)) |
| if not os.path.exists(Package): |
| EdkLogger.error('Build', RESOURCE_NOT_AVAILABLE, "The dependent Package %s of PCD %s.%s is not exist." % (PackageDec, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)) |
| if Package not in PcdDependDEC: |
| PcdDependDEC.append(Package) |
| |
| if PlatformInc and PcdDependDEC: |
| for pkg in PcdDependDEC: |
| if pkg in PlatformInc: |
| for inc in PlatformInc[pkg]: |
| MakeApp += '-I' + str(inc) + ' ' |
| MakeApp = MakeApp + '\n' |
| if sys.platform == "win32": |
| MakeApp = MakeApp + PcdMakefileEnd |
| MakeFileName = os.path.join(self.OutputPath, 'Makefile') |
| File = open (MakeFileName, 'w') |
| File.write(MakeApp) |
| File.close() |
| |
| InputValueFile = os.path.join(self.OutputPath, 'Input.txt') |
| OutputValueFile = os.path.join(self.OutputPath, 'Output.txt') |
| File = open (InputValueFile, 'w') |
| File.write(InitByteValue) |
| File.close() |
| |
| if sys.platform == "win32": |
| StdOut, StdErr = self.ExecuteCommand ('nmake clean & nmake -f %s' % (MakeFileName)) |
| else: |
| StdOut, StdErr = self.ExecuteCommand ('make clean & make -f %s' % (MakeFileName)) |
| Messages = StdOut.split('\r') |
| for Message in Messages: |
| if " error " in Message: |
| FileInfo = Message.strip().split('(') |
| if len (FileInfo) > 0: |
| FileName = FileInfo [0] |
| FileLine = FileInfo [1].split (')')[0] |
| else: |
| FileInfo = Message.strip().split(':') |
| FileName = FileInfo [0] |
| FileLine = FileInfo [1] |
| |
| File = open (FileName, 'r') |
| FileData = File.readlines() |
| File.close() |
| error_line = FileData[int (FileLine) - 1] |
| if r"//" in error_line: |
| c_line,dsc_line = error_line.split(r"//") |
| else: |
| dsc_line = error_line |
| |
| message_itmes = Message.split(":") |
| for item in message_itmes: |
| if "PcdValueInit.c" in item: |
| message_itmes[message_itmes.index(item)] = dsc_line.strip() |
| |
| EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, ":".join(message_itmes[1:])) |
| |
| PcdValueInitExe = PcdValueInitName |
| if not sys.platform == "win32": |
| PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName) |
| |
| StdOut, StdErr = self.ExecuteCommand (PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile)) |
| File = open (OutputValueFile, 'r') |
| FileBuffer = File.readlines() |
| File.close() |
| |
| StructurePcdSet = [] |
| for Pcd in FileBuffer: |
| PcdValue = Pcd.split ('|') |
| PcdInfo = PcdValue[0].split ('.') |
| StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip())) |
| return StructurePcdSet |
| |
| # # Retrieve dynamic PCD settings |
| # |
| # @param Type PCD type |
| # |
| # @retval a dict object contains settings of given PCD type |
| # |
| def _GetDynamicPcd(self, Type): |
| |
| |
| 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) |
| PcdList = [] |
| # Find out all possible PCD candidates for self._Arch |
| RecordList = self._RawData[Type, self._Arch] |
| AvailableSkuIdSet = copy.copy(self.SkuIds) |
| |
| |
| for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList: |
| if SkuName not in AvailableSkuIdSet: |
| continue |
| if "." not in TokenSpaceGuid: |
| PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) |
| PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting |
| |
| # Remove redundant PCD candidates, per the ARCH and SKU |
| for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList: |
| |
| Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid] |
| if Setting == None: |
| continue |
| |
| PcdValue, DatumType, MaxDatumSize = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) |
| SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', '', 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] |
| # Only fix the value while no value provided in DSC file. |
| for sku in pcd.SkuInfoList.values(): |
| if (sku.DefaultValue == "" or sku.DefaultValue==None): |
| sku.DefaultValue = pcdDecObject.DefaultValue |
| 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 self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE: |
| if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys(): |
| pcd.SkuInfoList[self.SkuIdMgr.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 |
| def CompletePcdValues(self,PcdSet): |
| Pcds = {} |
| DefaultStoreObj = DefaultStore(self._GetDefaultStores()) |
| SkuIds = set([(skuid,skuobj.SkuId) for pcdobj in PcdSet.values() for skuid,skuobj in pcdobj.SkuInfoList.items()]) |
| DefaultStores = set([storename for pcdobj in PcdSet.values() for skuobj in pcdobj.SkuInfoList.values() for storename in skuobj.DefaultStoreDict.keys()]) |
| for PcdCName, TokenSpaceGuid in PcdSet: |
| PcdObj = PcdSet[(PcdCName, TokenSpaceGuid)] |
| if PcdObj.Type not in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_DEFAULT], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII], |
| self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_VPD]]: |
| Pcds[PcdCName, TokenSpaceGuid]= PcdObj |
| continue |
| PcdType = PcdObj.Type |
| if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: |
| for skuid in PcdObj.SkuInfoList: |
| skuobj = PcdObj.SkuInfoList[skuid] |
| mindefaultstorename = DefaultStoreObj.GetMin(set([defaultstorename for defaultstorename in skuobj.DefaultStoreDict])) |
| for defaultstorename in DefaultStores: |
| if defaultstorename not in skuobj.DefaultStoreDict: |
| skuobj.DefaultStoreDict[defaultstorename] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename]) |
| skuobj.HiiDefaultValue = skuobj.DefaultStoreDict[mindefaultstorename] |
| for skuname,skuid in SkuIds: |
| if skuname not in PcdObj.SkuInfoList: |
| nextskuid = self.SkuIdMgr.GetNextSkuId(skuname) |
| while nextskuid not in PcdObj.SkuInfoList: |
| nextskuid = self.SkuIdMgr.GetNextSkuId(nextskuid) |
| PcdObj.SkuInfoList[skuname] = copy.deepcopy(PcdObj.SkuInfoList[nextskuid]) |
| PcdObj.SkuInfoList[skuname].SkuId = skuid |
| PcdObj.SkuInfoList[skuname].SkuIdName = skuname |
| if PcdType in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: |
| PcdObj.DefaultValue = PcdObj.SkuInfoList.values()[0].HiiDefaultValue if self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE else PcdObj.SkuInfoList["DEFAULT"].HiiDefaultValue |
| Pcds[PcdCName, TokenSpaceGuid]= PcdObj |
| return Pcds |
| # # Retrieve dynamic HII PCD settings |
| # |
| # @param Type PCD type |
| # |
| # @retval a dict object contains settings of given PCD type |
| # |
| def _GetDynamicHiiPcd(self, Type): |
| |
| VariableAttrs = {} |
| |
| Pcds = sdict() |
| # |
| # tdict is a special dict kind of type, used for selecting correct |
| # PCD settings for certain ARCH and SKU |
| # |
| PcdDict = tdict(True, 5) |
| PcdSet = set() |
| RecordList = self._RawData[Type, self._Arch] |
| # Find out all possible PCD candidates for self._Arch |
| AvailableSkuIdSet = copy.copy(self.SkuIds) |
| |
| for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, DefaultStore, Dummy4,Dummy5 in RecordList: |
| if DefaultStore == "COMMON": |
| DefaultStore = "STANDARD" |
| if SkuName not in AvailableSkuIdSet: |
| continue |
| if "." not in TokenSpaceGuid: |
| PcdSet.add((PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4)) |
| PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] = Setting |
| |
| |
| # Remove redundant PCD candidates, per the ARCH and SKU |
| for PcdCName, TokenSpaceGuid, SkuName,DefaultStore, Dummy4 in PcdSet: |
| |
| Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid,DefaultStore] |
| if Setting == None: |
| continue |
| 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)])) |
| |
| pcdDecObject = self._DecPcds[PcdCName, TokenSpaceGuid] |
| if (PcdCName, TokenSpaceGuid) in Pcds.keys(): |
| pcdObject = Pcds[PcdCName, TokenSpaceGuid] |
| if SkuName in pcdObject.SkuInfoList: |
| Skuitem = pcdObject.SkuInfoList[SkuName] |
| Skuitem.DefaultStoreDict.update({DefaultStore:DefaultValue}) |
| else: |
| SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue}) |
| pcdObject.SkuInfoList[SkuName] = SkuInfo |
| else: |
| SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], VariableName, VariableGuid, VariableOffset, DefaultValue, VariableAttribute=VarAttribute,DefaultStore={DefaultStore:DefaultValue}) |
| Pcds[PcdCName, TokenSpaceGuid] = PcdClassObject( |
| PcdCName, |
| TokenSpaceGuid, |
| self._PCD_TYPE_STRING_[Type], |
| '', |
| DefaultValue, |
| '', |
| '', |
| {SkuName : SkuInfo}, |
| False, |
| 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 self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE: |
| if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys(): |
| pcd.SkuInfoList[self.SkuIdMgr.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 (_, 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) |
| rt, invalidhii = self.CheckVariableNameAssignment(Pcds) |
| if not rt: |
| invalidpcd = ",".join(invalidhii) |
| EdkLogger.error('build', PCD_VARIABLE_INFO_ERROR, Message='The same HII PCD must map to the same EFI variable for all SKUs', File=self.MetaFile, ExtraData=invalidpcd) |
| return Pcds |
| |
| def CheckVariableNameAssignment(self,Pcds): |
| invalidhii = [] |
| for pcdname in Pcds: |
| pcd = Pcds[pcdname] |
| varnameset = set([sku.VariableName for (skuid,sku) in pcd.SkuInfoList.items()]) |
| if len(varnameset) > 1: |
| invalidhii.append(".".join((pcdname[1],pcdname[0]))) |
| if len(invalidhii): |
| return False,invalidhii |
| else: |
| return True, [] |
| # # Retrieve dynamic VPD PCD settings |
| # |
| # @param Type PCD type |
| # |
| # @retval a dict object contains settings of given PCD type |
| # |
| def _GetDynamicVpdPcd(self, Type): |
| |
| |
| 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) |
| PcdList = [] |
| |
| # Find out all possible PCD candidates for self._Arch |
| RecordList = self._RawData[Type, self._Arch] |
| AvailableSkuIdSet = copy.copy(self.SkuIds) |
| |
| for TokenSpaceGuid, PcdCName, Setting, Arch, SkuName, Dummy3, Dummy4,Dummy5 in RecordList: |
| if SkuName not in AvailableSkuIdSet: |
| continue |
| if "." not in TokenSpaceGuid: |
| PcdList.append((PcdCName, TokenSpaceGuid, SkuName, Dummy4)) |
| PcdDict[Arch, SkuName, PcdCName, TokenSpaceGuid] = Setting |
| |
| # Remove redundant PCD candidates, per the ARCH and SKU |
| for PcdCName, TokenSpaceGuid, SkuName, Dummy4 in PcdList: |
| Setting = PcdDict[self._Arch, SkuName, PcdCName, TokenSpaceGuid] |
| if Setting == None: |
| continue |
| # |
| # 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 = self._ValidatePcd(PcdCName, TokenSpaceGuid, Setting, Type, Dummy4) |
| SkuInfo = SkuInfoClass(SkuName, self.SkuIds[SkuName][0], '', '', '', '', 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, |
| {SkuName : SkuInfo}, |
| False, |
| None |
| ) |
| 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.DefaultValue == "" or sku.DefaultValue==None): |
| sku.DefaultValue = pcdDecObject.DefaultValue |
| 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 self.SkuIdMgr.SkuUsageType == self.SkuIdMgr.SINGLE: |
| if 'DEFAULT' in pcd.SkuInfoList.keys() and self.SkuIdMgr.SystemSkuId not in pcd.SkuInfoList.keys(): |
| pcd.SkuInfoList[self.SkuIdMgr.SystemSkuId] = pcd.SkuInfoList['DEFAULT'] |
| del(pcd.SkuInfoList['DEFAULT']) |
| |
| return Pcds |
| |
| # # Add external modules |
| # |
| # The external modules are mostly those listed in FDF file, which don't |
| # need "build". |
| # |
| # @param FilePath The path of module description file |
| # |
| def AddModule(self, FilePath): |
| FilePath = NormPath(FilePath) |
| if FilePath not in self.Modules: |
| Module = ModuleBuildClassObject() |
| Module.MetaFile = FilePath |
| self.Modules.append(Module) |
| |
| # # Add external PCDs |
| # |
| # The external PCDs are mostly those listed in FDF file to specify address |
| # or offset information. |
| # |
| # @param Name Name of the PCD |
| # @param Guid Token space guid of the PCD |
| # @param Value Value of the PCD |
| # |
| def AddPcd(self, Name, Guid, Value): |
| if (Name, Guid) not in self.Pcds: |
| 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) |
| Guid = property(_GetFileGuid) |
| Version = property(_GetVersion) |
| DscSpecification = property(_GetDscSpec) |
| OutputDirectory = property(_GetOutpuDir) |
| 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) |
| LibraryInstances = property(_GetLibraryInstances) |
| LibraryClasses = property(_GetLibraryClasses) |
| Pcds = property(_GetPcds) |
| BuildOptions = property(_GetBuildOptions) |