License header updated to match correct format.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Yingke Liu <yingke.d.liu@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>

git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15971 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Yingke Liu
2014-08-28 13:53:34 +00:00
committed by yingke
parent cb9ec399fe
commit 97fa0ee9b1
135 changed files with 1189 additions and 869 deletions

View File

@ -40,15 +40,27 @@ import Common.VpdInfoFile as VpdInfoFile
from GenPcdDb import CreatePcdDatabaseCode
from Workspace.MetaFileCommentParser import UsageList
import InfSectionParser
## Regular expression for splitting Dependency Expression string into tokens
gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
#
# Match name = variable
#
gEfiVarStoreNamePattern = re.compile("\s*name\s*=\s*(\w+)")
#
# The format of guid in efivarstore statement likes following and must be correct:
# guid = {0xA04A27f4, 0xDF00, 0x4D42, {0xB5, 0x52, 0x39, 0x51, 0x13, 0x02, 0x11, 0x3D}}
#
gEfiVarStoreGuidPattern = re.compile("\s*guid\s*=\s*({.*?{.*?}\s*})")
## Mapping Makefile type
gMakeTypeMap = {"MSFT":"nmake", "GCC":"gmake"}
## Build rule configuration file
gBuildRuleFile = 'Conf/build_rule.txt'
gDefaultBuildRuleFile = 'Conf/build_rule.txt'
## Build rule default version
AutoGenReqBuildRuleVerNum = "0.1"
@ -60,22 +72,40 @@ gAutoGenStringFileName = "%(module_name)sStrDefs.h"
gAutoGenStringFormFileName = "%(module_name)sStrDefs.hpk"
gAutoGenDepexFileName = "%(module_name)s.depex"
gInfSpecVersion = "0x00010017"
#
# Template string to generic AsBuilt INF
#
gAsBuiltInfHeaderString = TemplateString("""${header_comments}
# DO NOT EDIT
# FILE auto-generated
[Defines]
INF_VERSION = 0x00010016
INF_VERSION = ${module_inf_version}
BASE_NAME = ${module_name}
FILE_GUID = ${module_guid}
MODULE_TYPE = ${module_module_type}
VERSION_STRING = ${module_version_string}${BEGIN}
MODULE_TYPE = ${module_module_type}${BEGIN}
VERSION_STRING = ${module_version_string}${END}${BEGIN}
PCD_IS_DRIVER = ${pcd_is_driver_string}${END}${BEGIN}
UEFI_SPECIFICATION_VERSION = ${module_uefi_specification_version}${END}${BEGIN}
PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}
PI_SPECIFICATION_VERSION = ${module_pi_specification_version}${END}${BEGIN}
ENTRY_POINT = ${module_entry_point}${END}${BEGIN}
UNLOAD_IMAGE = ${module_unload_image}${END}${BEGIN}
CONSTRUCTOR = ${module_constructor}${END}${BEGIN}
DESTRUCTOR = ${module_destructor}${END}${BEGIN}
SHADOW = ${module_shadow}${END}${BEGIN}
PCI_VENDOR_ID = ${module_pci_vendor_id}${END}${BEGIN}
PCI_DEVICE_ID = ${module_pci_device_id}${END}${BEGIN}
PCI_CLASS_CODE = ${module_pci_class_code}${END}${BEGIN}
PCI_REVISION = ${module_pci_revision}${END}${BEGIN}
BUILD_NUMBER = ${module_build_number}${END}${BEGIN}
SPEC = ${module_spec}${END}${BEGIN}
UEFI_HII_RESOURCE_SECTION = ${module_uefi_hii_resource_section}${END}${BEGIN}
MODULE_UNI_FILE = ${module_uni_file}${END}
[Packages]${BEGIN}
[Packages.${module_arch}]${BEGIN}
${package_item}${END}
[Binaries.${module_arch}]${BEGIN}
@ -84,19 +114,32 @@ gAsBuiltInfHeaderString = TemplateString("""${header_comments}
[PatchPcd.${module_arch}]${BEGIN}
${patchablepcd_item}
${END}
[Protocols.${module_arch}]${BEGIN}
${protocol_item}
${END}
[Ppis.${module_arch}]${BEGIN}
${ppi_item}
${END}
[Guids.${module_arch}]${BEGIN}
${guid_item}
${END}
[PcdEx.${module_arch}]${BEGIN}
${pcd_item}
${END}
[LibraryClasses.${module_arch}]
## @LIB_INSTANCES${BEGIN}
# ${libraryclasses_item}${END}
${depexsection_item}
${tail_comments}
[BuildOptions.${module_arch}]
## @AsBuilt${BEGIN}
## ${flags_item}${END}
""")
@ -240,6 +283,15 @@ class WorkspaceAutoGen(AutoGen):
ExtraData="Build target [%s] is not supported by the platform. [Valid target: %s]"
% (self.BuildTarget, " ".join(self.Platform.BuildTargets)))
# Validate SKU ID
if not self.SkuId:
self.SkuId = 'DEFAULT'
if self.SkuId not in self.Platform.SkuIds:
EdkLogger.error("build", PARAMETER_INVALID,
ExtraData="SKU-ID [%s] is not supported by the platform. [Valid SKU-ID: %s]"
% (self.SkuId, " ".join(self.Platform.SkuIds.keys())))
# parse FDF file to get PCDs in it, if any
if not self.FdfFile:
self.FdfFile = self.Platform.FlashDefinition
@ -299,6 +351,7 @@ class WorkspaceAutoGen(AutoGen):
DecPcds = {}
DecPcdsKey = set()
PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
#Collect package set information from INF of FDF
PkgSet = set()
for Inf in ModuleList:
ModuleFile = PathClass(NormPath(Inf), GlobalData.gWorkspace, Arch)
@ -355,10 +408,10 @@ class WorkspaceAutoGen(AutoGen):
# Check PCD type and definition between DSC and DEC
#
self._CheckPcdDefineAndType()
if self.FdfFile:
self._CheckDuplicateInFV(Fdf)
# if self.FdfFile:
# self._CheckDuplicateInFV(Fdf)
self._BuildDir = None
self._FvDir = None
self._MakeFileDir = None
@ -662,7 +715,7 @@ class WorkspaceAutoGen(AutoGen):
ExtraData=None
)
Count += 1
## Generate fds command
def _GenFdsCommand(self):
return (GenMake.TopLevelMakefile(self)._TEMPLATE_.Replace(GenMake.TopLevelMakefile(self)._TemplateDict)).strip()
@ -817,9 +870,6 @@ class PlatformAutoGen(AutoGen):
# get library/modules for build
self.LibraryBuildDirectoryList = []
self.ModuleBuildDirectoryList = []
# get the original module/package/platform objects
self.LibraryBuildDirectoryList = []
self.ModuleBuildDirectoryList = []
return True
def __repr__(self):
@ -859,7 +909,7 @@ class PlatformAutoGen(AutoGen):
Ma = ModuleAutoGen(self.Workspace, ModuleFile, self.BuildTarget,
self.ToolChain, self.Arch, self.MetaFile)
Ma.CreateMakeFile(True)
Ma.CreateAsBuiltInf()
#Ma.CreateAsBuiltInf()
# no need to create makefile for the platform more than once
if self.IsMakeFileCreated:
@ -923,8 +973,11 @@ class PlatformAutoGen(AutoGen):
if PcdFromModule.DatumType == "VOID*" and PcdFromModule.MaxDatumSize in [None, '']:
NoDatumTypePcdList.add("%s.%s [%s]" % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, F))
# Check the PCD from Binary INF or Source INF
if M.IsBinaryModule == True:
PcdFromModule.IsFromBinaryInf = True
# Check the PCD from DSC or not
if (PcdFromModule.TokenCName, PcdFromModule.TokenSpaceGuidCName) in self.Platform.Pcds.keys():
PcdFromModule.IsFromDsc = True
else:
@ -943,11 +996,11 @@ class PlatformAutoGen(AutoGen):
PcdFromModule.IsFromBinaryInf == False:
# Print warning message to let the developer make a determine.
if PcdFromModule not in PcdNotInDb:
EdkLogger.warn("build",
"A PCD listed in the DSC (%s.%s, %s) is used by a module not in the FDF. If the PCD is not used by any module listed in the FDF this PCD will be ignored. " \
% (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, self.Platform.MetaFile.Path),
File=self.MetaFile, \
ExtraData=None)
# EdkLogger.warn("build",
# "A PCD listed in the DSC (%s.%s, %s) is used by a module not in the FDF. If the PCD is not used by any module listed in the FDF this PCD will be ignored. " \
# % (PcdFromModule.TokenSpaceGuidCName, PcdFromModule.TokenCName, self.Platform.MetaFile.Path),
# File=self.MetaFile, \
# ExtraData=None)
PcdNotInDb.append(PcdFromModule)
continue
# If one of the Source built modules listed in the DSC is not listed in
@ -1017,6 +1070,11 @@ class PlatformAutoGen(AutoGen):
elif PcdFromModule not in self._NonDynaPcdList_ and PcdFromModule.Type in TAB_PCDS_PATCHABLE_IN_MODULE:
self._NonDynaPcdList_.append(PcdFromModule)
if PcdFromModule in self._DynaPcdList_ and PcdFromModule.Phase == 'PEI' and PcdFromModule.Type in GenC.gDynamicExPcd:
# Overwrite the phase of any the same PCD existing, if Phase is PEI.
# It is to solve the case that a dynamic PCD used by a PEM module/PEI
# module & DXE module at a same time.
# Overwrite the type of the PCDs in source INF by the type of AsBuild
# INF file as DynamicEx.
Index = self._DynaPcdList_.index(PcdFromModule)
self._DynaPcdList_[Index].Phase = PcdFromModule.Phase
self._DynaPcdList_[Index].Type = PcdFromModule.Type
@ -1050,16 +1108,16 @@ class PlatformAutoGen(AutoGen):
# If PCD is listed in a PcdsDynamicHii, PcdsDynamicExHii, PcdsDynamicHii or PcdsDynamicExHii
# section, and the PCD is not used by any module that is listed in the DSC file, the build
# provide a warning message.
for PcdKey in self.Platform.Pcds.keys():
Pcd = self.Platform.Pcds[PcdKey]
if Pcd not in self._DynamicPcdList + PcdNotInDb and \
Pcd.Type in [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_HII]:
# Print warning message to let the developer make a determine.
EdkLogger.warn("build",
"A %s PCD listed in the DSC (%s.%s, %s) is not used by any module." \
% (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, self.Platform.MetaFile.Path),
File=self.MetaFile, \
ExtraData=None)
#for PcdKey in self.Platform.Pcds.keys():
# Pcd = self.Platform.Pcds[PcdKey]
# if Pcd not in self._DynamicPcdList + PcdNotInDb and \
# Pcd.Type in [TAB_PCDS_DYNAMIC, TAB_PCDS_DYNAMIC_DEFAULT, TAB_PCDS_DYNAMIC_HII, TAB_PCDS_DYNAMIC_EX, TAB_PCDS_DYNAMIC_EX_DEFAULT, TAB_PCDS_DYNAMIC_EX_HII]:
# # Print warning message to let the developer make a determine.
#EdkLogger.warn("build",
# "A %s PCD listed in the DSC (%s.%s, %s) is not used by any module." \
# % (Pcd.Type, Pcd.TokenSpaceGuidCName, Pcd.TokenCName, self.Platform.MetaFile.Path),
# File=self.MetaFile, \
# ExtraData=None)
#
# Sort dynamic PCD list to:
# 1) If PCD's datum type is VOID* and value is unicode string which starts with L, the PCD item should
@ -1421,7 +1479,7 @@ class PlatformAutoGen(AutoGen):
self._EdkIIBuildOption = self._ExpandBuildOption(self.Platform.BuildOptions, EDKII_NAME)
return self._EdkIIBuildOption
## Parse build_rule.txt in $(WORKSPACE)/Conf/build_rule.txt
## Parse build_rule.txt in Conf Directory.
#
# @retval BuildRule object
#
@ -1431,7 +1489,7 @@ class PlatformAutoGen(AutoGen):
if TAB_TAT_DEFINES_BUILD_RULE_CONF in self.Workspace.TargetTxt.TargetTxtDictionary:
BuildRuleFile = self.Workspace.TargetTxt.TargetTxtDictionary[TAB_TAT_DEFINES_BUILD_RULE_CONF]
if BuildRuleFile in [None, '']:
BuildRuleFile = gBuildRuleFile
BuildRuleFile = gDefaultBuildRuleFile
self._BuildRule = BuildRule(BuildRuleFile)
if self._BuildRule._FileVersion == "":
self._BuildRule._FileVersion = AutoGenReqBuildRuleVerNum
@ -2140,6 +2198,9 @@ class ModuleAutoGen(AutoGen):
return False
self.SourceDir = self.MetaFile.SubDir
if self.SourceDir.upper().find(self.WorkspaceDir.upper()) == 0:
self.SourceDir = self.SourceDir[len(self.WorkspaceDir) + 1:]
self.SourceOverrideDir = None
# use overrided path defined in DSC file
if self.MetaFile.Key in GlobalData.gOverrideDir:
@ -2284,6 +2345,16 @@ class ModuleAutoGen(AutoGen):
## Return the module meta-file GUID
def _GetGuid(self):
#
# To build same module more than once, the module path with FILE_GUID overridden has
# the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path
# in DSC. The overridden GUID can be retrieved from file name
#
if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path):
#
# Length of GUID is 36
#
return os.path.basename(self.MetaFile.Path)[:36]
return self.Module.Guid
## Return the module version
@ -2393,7 +2464,66 @@ class ModuleAutoGen(AutoGen):
continue
PackageList.append(Package)
return PackageList
## Get the depex string
#
# @return : a string contain all depex expresion.
def _GetDepexExpresionString(self):
DepexStr = ''
DepexList = []
## DPX_SOURCE IN Define section.
if self.Module.DxsFile:
return DepexStr
for M in [self.Module] + self.DependentLibraryList:
Filename = M.MetaFile.Path
InfObj = InfSectionParser.InfSectionParser(Filename)
DepexExpresionList = InfObj.GetDepexExpresionList()
for DepexExpresion in DepexExpresionList:
for key in DepexExpresion.keys():
Arch, ModuleType = key
# the type of build module is USER_DEFINED.
# All different DEPEX section tags would be copied into the As Built INF file
# and there would be separate DEPEX section tags
if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:
if (Arch.upper() == self.Arch.upper()) and (ModuleType.upper() != TAB_ARCH_COMMON):
DepexList.append({(Arch, ModuleType): DepexExpresion[key][:]})
else:
if Arch.upper() == TAB_ARCH_COMMON or \
(Arch.upper() == self.Arch.upper() and \
ModuleType.upper() in [TAB_ARCH_COMMON, self.ModuleType.upper()]):
DepexList.append({(Arch, ModuleType): DepexExpresion[key][:]})
#the type of build module is USER_DEFINED.
if self.ModuleType.upper() == SUP_MODULE_USER_DEFINED:
for Depex in DepexList:
for key in Depex.keys():
DepexStr += '[Depex.%s.%s]\n' % key
DepexStr += '\n'.join(['# '+ val for val in Depex[key]])
DepexStr += '\n\n'
if not DepexStr:
return '[Depex.%s]\n' % self.Arch
return DepexStr
#the type of build module not is USER_DEFINED.
Count = 0
for Depex in DepexList:
Count += 1
if DepexStr != '':
DepexStr += ' AND '
DepexStr += '('
for D in Depex.values():
DepexStr += ' '.join([val for val in D])
Index = DepexStr.find('END')
if Index > -1 and Index == len(DepexStr) - 3:
DepexStr = DepexStr[:-3]
DepexStr = DepexStr.strip()
DepexStr += ')'
if Count == 1:
DepexStr = DepexStr.lstrip('(').rstrip(')').strip()
if not DepexStr:
return '[Depex.%s]\n' % self.Arch
return '[Depex.%s]\n# ' % self.Arch + DepexStr
## Merge dependency expression
#
# @retval list The token list of the dependency expression after parsed
@ -2546,7 +2676,7 @@ class ModuleAutoGen(AutoGen):
## Return a list of files which can be built from source
#
# What kind of files can be built is determined by build rules in
# $(WORKSPACE)/Conf/build_rule.txt and toolchain family.
# $(CONF_DIRECTORY)/build_rule.txt and toolchain family.
#
def _GetSourceFileList(self):
if self._SourceFileList == None:
@ -2901,6 +3031,71 @@ class ModuleAutoGen(AutoGen):
self._IncludePathList.append(str(Inc))
return self._IncludePathList
## Get HII EX PCDs which maybe used by VFR
#
# efivarstore used by VFR may relate with HII EX PCDs
# Get the variable name and GUID from efivarstore and HII EX PCD
# List the HII EX PCDs in As Built INF if both name and GUID match.
#
# @retval list HII EX PCDs
#
def _GetPcdsMaybeUsedByVfr(self):
if not self.SourceFileList:
return []
NameGuids = []
for SrcFile in self.SourceFileList:
if SrcFile.Ext.lower() != '.vfr':
continue
Vfri = os.path.join(self.OutputDir, SrcFile.BaseName + '.i')
if not os.path.exists(Vfri):
continue
VfriFile = open(Vfri, 'r')
Content = VfriFile.read()
VfriFile.close()
Pos = Content.find('efivarstore')
while Pos != -1:
#
# Make sure 'efivarstore' is the start of efivarstore statement
# In case of the value of 'name' (name = efivarstore) is equal to 'efivarstore'
#
Index = Pos - 1
while Index >= 0 and Content[Index] in ' \t\r\n':
Index -= 1
if Index >= 0 and Content[Index] != ';':
Pos = Content.find('efivarstore', Pos + len('efivarstore'))
continue
#
# 'efivarstore' must be followed by name and guid
#
Name = gEfiVarStoreNamePattern.search(Content, Pos)
if not Name:
break
Guid = gEfiVarStoreGuidPattern.search(Content, Pos)
if not Guid:
break
NameArray = ConvertStringToByteArray('L"' + Name.group(1) + '"')
NameGuids.append((NameArray, GuidStructureStringToGuidString(Guid.group(1))))
Pos = Content.find('efivarstore', Name.end())
if not NameGuids:
return []
HiiExPcds = []
for Pcd in self.PlatformInfo.Platform.Pcds.values():
if Pcd.Type != TAB_PCDS_DYNAMIC_EX_HII:
continue
for SkuName in Pcd.SkuInfoList:
SkuInfo = Pcd.SkuInfoList[SkuName]
Name = ConvertStringToByteArray(SkuInfo.VariableName)
Value = GuidValue(SkuInfo.VariableGuid, self.PlatformInfo.PackageList)
if not Value:
continue
Guid = GuidStructureStringToGuidString(Value)
if (Name, Guid) in NameGuids and Pcd not in HiiExPcds:
HiiExPcds.append(Pcd)
break
return HiiExPcds
## Create AsBuilt INF file the module
#
def CreateAsBuiltInf(self):
@ -2963,6 +3158,16 @@ class ModuleAutoGen(AutoGen):
break
if Found: break
VfrPcds = self._GetPcdsMaybeUsedByVfr()
for Pkg in self.PlatformInfo.PackageList:
if Pkg in Packages:
continue
for VfrPcd in VfrPcds:
if ((VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'DynamicEx') in Pkg.Pcds or
(VfrPcd.TokenCName, VfrPcd.TokenSpaceGuidCName, 'Dynamic') in Pkg.Pcds):
Packages += [Pkg]
break
ModuleType = self.ModuleType
if ModuleType == 'UEFI_DRIVER' and self.DepexGenerated:
ModuleType = 'DXE_DRIVER'
@ -2971,14 +3176,30 @@ class ModuleAutoGen(AutoGen):
if self.PcdIsDriver != '':
DriverType = self.PcdIsDriver
Guid = self.Guid
MDefs = self.Module.Defines
AsBuiltInfDict = {
'module_name' : self.Name,
'module_guid' : self.Guid,
'module_guid' : Guid,
'module_module_type' : ModuleType,
'module_version_string' : self.Version,
'module_version_string' : [MDefs['VERSION_STRING']] if 'VERSION_STRING' in MDefs else [],
'pcd_is_driver_string' : [],
'module_uefi_specification_version' : [],
'module_pi_specification_version' : [],
'module_entry_point' : self.Module.ModuleEntryPointList,
'module_unload_image' : self.Module.ModuleUnloadImageList,
'module_constructor' : self.Module.ConstructorList,
'module_destructor' : self.Module.DestructorList,
'module_shadow' : [MDefs['SHADOW']] if 'SHADOW' in MDefs else [],
'module_pci_vendor_id' : [MDefs['PCI_VENDOR_ID']] if 'PCI_VENDOR_ID' in MDefs else [],
'module_pci_device_id' : [MDefs['PCI_DEVICE_ID']] if 'PCI_DEVICE_ID' in MDefs else [],
'module_pci_class_code' : [MDefs['PCI_CLASS_CODE']] if 'PCI_CLASS_CODE' in MDefs else [],
'module_pci_revision' : [MDefs['PCI_REVISION']] if 'PCI_REVISION' in MDefs else [],
'module_build_number' : [MDefs['BUILD_NUMBER']] if 'BUILD_NUMBER' in MDefs else [],
'module_spec' : [MDefs['SPEC']] if 'SPEC' in MDefs else [],
'module_uefi_hii_resource_section' : [MDefs['UEFI_HII_RESOURCE_SECTION']] if 'UEFI_HII_RESOURCE_SECTION' in MDefs else [],
'module_uni_file' : [MDefs['MODULE_UNI_FILE']] if 'MODULE_UNI_FILE' in MDefs else [],
'module_arch' : self.Arch,
'package_item' : ['%s' % (Package.MetaFile.File.replace('\\','/')) for Package in Packages],
'binary_item' : [],
@ -2990,7 +3211,12 @@ class ModuleAutoGen(AutoGen):
'flags_item' : [],
'libraryclasses_item' : []
}
AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion
if self.AutoGenVersion > int(gInfSpecVersion, 0):
AsBuiltInfDict['module_inf_version'] = '0x%08x' % self.AutoGenVersion
else:
AsBuiltInfDict['module_inf_version'] = gInfSpecVersion
if DriverType:
AsBuiltInfDict['pcd_is_driver_string'] += [DriverType]
@ -3036,6 +3262,8 @@ class ModuleAutoGen(AutoGen):
StartPos = Index
break
AsBuiltInfDict['header_comments'] = '\n'.join(HeaderComments[StartPos:]).replace(':#', '://')
AsBuiltInfDict['tail_comments'] = '\n'.join(self.Module.TailComments)
GenList = [
(self.ProtocolList, self._ProtocolComments, 'protocol_item'),
(self.PpiList, self._PpiComments, 'ppi_item'),
@ -3116,28 +3344,42 @@ class ModuleAutoGen(AutoGen):
if PcdComments:
PcdItem = PcdComments + '\n ' + PcdItem
AsBuiltInfDict['patchablepcd_item'].append(PcdItem)
for Pcd in Pcds:
HiiPcds = []
for Pcd in Pcds + VfrPcds:
PcdComments = ''
PcdCommentList = []
HiiInfo = ''
SkuId = ''
if Pcd.Type == TAB_PCDS_DYNAMIC_EX_HII:
for SkuName in Pcd.SkuInfoList:
SkuInfo = Pcd.SkuInfoList[SkuName]
SkuId = SkuInfo.SkuId
HiiInfo = '## %s|%s|%s' % (SkuInfo.VariableName, SkuInfo.VariableGuid, SkuInfo.VariableOffset)
break
if SkuId:
#
# Don't generate duplicated HII PCD
#
if (SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in HiiPcds:
continue
else:
HiiPcds.append((SkuId, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) in self._PcdComments:
PcdCommentList = self._PcdComments[Pcd.TokenSpaceGuidCName, Pcd.TokenCName][:]
if HiiInfo:
UsageIndex = -1
UsageStr = ''
for Index, Comment in enumerate(PcdCommentList):
for Usage in UsageList:
if Comment.find(Usage) != -1:
UsageStr = Usage
UsageIndex = Index
break
if UsageIndex != -1:
PcdCommentList[UsageIndex] = PcdCommentList[UsageIndex] + ' ' + HiiInfo
PcdCommentList[UsageIndex] = '## %s %s %s' % (UsageStr, HiiInfo, PcdCommentList[UsageIndex].replace(UsageStr, ''))
else:
PcdCommentList.append('## ' + HiiInfo)
PcdCommentList.append('## UNDEFINED ' + HiiInfo)
PcdComments = '\n '.join(PcdCommentList)
PcdEntry = Pcd.TokenSpaceGuidCName + '.' + Pcd.TokenCName
if PcdComments:
@ -3146,6 +3388,16 @@ class ModuleAutoGen(AutoGen):
for Item in self.BuildOption:
if 'FLAGS' in self.BuildOption[Item]:
AsBuiltInfDict['flags_item'] += ['%s:%s_%s_%s_%s_FLAGS = %s' % (self.ToolChainFamily, self.BuildTarget, self.ToolChain, self.Arch, Item, self.BuildOption[Item]['FLAGS'].strip())]
# Generated LibraryClasses section in comments.
for Library in self.LibraryAutoGenList:
AsBuiltInfDict['libraryclasses_item'] += [Library.MetaFile.File.replace('\\', '/')]
# Generated depex expression section in comments.
AsBuiltInfDict['depexsection_item'] = ''
DepexExpresion = self._GetDepexExpresionString()
if DepexExpresion:
AsBuiltInfDict['depexsection_item'] = DepexExpresion
AsBuiltInf = TemplateString()
AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict))

View File

@ -247,6 +247,7 @@ MODULE_FILE = ${module_file}
MODULE_FILE_BASE_NAME = ${module_file_base_name}
BASE_NAME = $(MODULE_NAME)
MODULE_RELATIVE_DIR = ${module_relative_directory}
PACKAGE_RELATIVE_DIR = ${package_relative_directory}
MODULE_DIR = $(WORKSPACE)${separator}${module_relative_directory}
MODULE_ENTRY_POINT = ${module_entry_point}
@ -552,6 +553,10 @@ cleanlib:
Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}
LibraryMakeCommandList.append(Command)
package_rel_dir = self._AutoGenObject.SourceDir
if os.sep in package_rel_dir:
package_rel_dir = package_rel_dir[package_rel_dir.index(os.sep) + 1:]
MakefileTemplateDict = {
"makefile_header" : self._FILE_HEADER_[self._FileType],
"makefile_path" : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
@ -569,7 +574,8 @@ cleanlib:
"module_file" : self._AutoGenObject.MetaFile.Name,
"module_file_base_name" : self._AutoGenObject.MetaFile.BaseName,
"module_relative_directory" : self._AutoGenObject.SourceDir,
"module_extra_defines" : ["%s = %s" % (k, v) for k,v in self._AutoGenObject.Module.Defines.iteritems()],
"package_relative_directory": package_rel_dir,
"module_extra_defines" : ["%s = %s" % (k, v) for k, v in self._AutoGenObject.Module.Defines.iteritems()],
"architecture" : self._AutoGenObject.Arch,
"toolchain_tag" : self._AutoGenObject.ToolChain,
@ -1177,7 +1183,8 @@ cleanlib:
def GetModuleBuildDirectoryList(self):
DirList = []
for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
if not ModuleAutoGen.IsBinaryModule:
DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
return DirList
## Get the root directory list for intermediate files of all libraries build
@ -1187,7 +1194,8 @@ cleanlib:
def GetLibraryBuildDirectoryList(self):
DirList = []
for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
if not LibraryAutoGen.IsBinaryModule:
DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
return DirList
_TemplateDict = property(_CreateTemplateDict)
@ -1200,7 +1208,7 @@ cleanlib:
#
class TopLevelMakefile(BuildFile):
## template used to generate toplevel makefile
_TEMPLATE_ = TemplateString('''${BEGIN}\tGenFds -f ${fdf_file} -o ${platform_build_directory} -t ${toolchain_tag} -b ${build_target} -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -C ${cap} ${END}${BEGIN} -D ${macro} ${END}''')
_TEMPLATE_ = TemplateString('''${BEGIN}\tGenFds -f ${fdf_file} --conf=${conf_directory} -o ${platform_build_directory} -t ${toolchain_tag} -b ${build_target} -p ${active_platform} -a ${build_architecture_list} ${extra_options}${END}${BEGIN} -r ${fd} ${END}${BEGIN} -i ${fv} ${END}${BEGIN} -C ${cap} ${END}${BEGIN} -D ${macro} ${END}''')
## Constructor of TopLevelMakefile
#
@ -1258,6 +1266,9 @@ class TopLevelMakefile(BuildFile):
if GlobalData.gCaseInsensitive:
ExtraOption += " -c"
if GlobalData.gIgnoreSource:
ExtraOption += " --ignore-sources"
MakefileName = self._FILE_NAME_[self._FileType]
SubBuildCommandList = []
for A in PlatformInfo.ArchList:
@ -1272,6 +1283,7 @@ class TopLevelMakefile(BuildFile):
"platform_guid" : PlatformInfo.Guid,
"platform_version" : PlatformInfo.Version,
"platform_build_directory" : PlatformInfo.BuildDir,
"conf_directory" : GlobalData.gConfDirectory,
"toolchain_tag" : PlatformInfo.ToolChain,
"build_target" : PlatformInfo.BuildTarget,
@ -1301,7 +1313,8 @@ class TopLevelMakefile(BuildFile):
def GetModuleBuildDirectoryList(self):
DirList = []
for ModuleAutoGen in self._AutoGenObject.ModuleAutoGenList:
DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
if not ModuleAutoGen.IsBinaryModule:
DirList.append(os.path.join(self._AutoGenObject.BuildDir, ModuleAutoGen.BuildDir))
return DirList
## Get the root directory list for intermediate files of all libraries build
@ -1311,7 +1324,8 @@ class TopLevelMakefile(BuildFile):
def GetLibraryBuildDirectoryList(self):
DirList = []
for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:
DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
if not LibraryAutoGen.IsBinaryModule:
DirList.append(os.path.join(self._AutoGenObject.BuildDir, LibraryAutoGen.BuildDir))
return DirList
_TemplateDict = property(_CreateTemplateDict)

View File

@ -0,0 +1,107 @@
## @file
# Parser a Inf file and Get specify section data.
#
# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<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.
#
## Import Modules
#
import Common.EdkLogger as EdkLogger
from Common.BuildToolError import *
from Common.DataType import *
class InfSectionParser():
def __init__(self, FilePath):
self._FilePath = FilePath
self._FileSectionDataList = []
self._ParserInf()
def _ParserInf(self):
Filename = self._FilePath
FileLinesList = []
UserExtFind = False
FindEnd = True
FileLastLine = False
SectionLine = ''
SectionData = []
try:
FileLinesList = open(Filename, "r", 0).readlines()
except BaseException:
EdkLogger.error("build", AUTOGEN_ERROR, 'File %s is opened failed.' % Filename)
for Index in range(0, len(FileLinesList)):
line = str(FileLinesList[Index]).strip()
if Index + 1 == len(FileLinesList):
FileLastLine = True
NextLine = ''
else:
NextLine = str(FileLinesList[Index + 1]).strip()
if UserExtFind and FindEnd == False:
if line:
SectionData.append(line)
if line.lower().startswith(TAB_SECTION_START) and line.lower().endswith(TAB_SECTION_END):
SectionLine = line
UserExtFind = True
FindEnd = False
if (NextLine != '' and NextLine[0] == TAB_SECTION_START and \
NextLine[-1] == TAB_SECTION_END) or FileLastLine:
UserExtFind = False
FindEnd = True
self._FileSectionDataList.append({SectionLine: SectionData[:]})
SectionData = []
SectionLine = ''
# Get depex expresion
#
# @return: a list include some dictionary that key is section and value is a list contain all data.
def GetDepexExpresionList(self):
DepexExpresionList = []
if not self._FileSectionDataList:
return DepexExpresionList
for SectionDataDict in self._FileSectionDataList:
for key in SectionDataDict.keys():
if key.lower() == "[depex]" or key.lower().startswith("[depex."):
SectionLine = key.lstrip(TAB_SECTION_START).rstrip(TAB_SECTION_END)
SubSectionList = [SectionLine]
if str(SectionLine).find(TAB_COMMA_SPLIT) > -1:
SubSectionList = str(SectionLine).split(TAB_COMMA_SPLIT)
for SubSection in SubSectionList:
SectionList = SubSection.split(TAB_SPLIT)
SubKey = ()
if len(SectionList) == 1:
SubKey = (TAB_ARCH_COMMON, TAB_ARCH_COMMON)
elif len(SectionList) == 2:
SubKey = (SectionList[1], TAB_ARCH_COMMON)
elif len(SectionList) == 3:
SubKey = (SectionList[1], SectionList[2])
else:
EdkLogger.error("build", AUTOGEN_ERROR, 'Section %s is invalid.' % key)
DepexExpresionList.append({SubKey: SectionDataDict[key]})
return DepexExpresionList

View File

@ -1,3 +1,7 @@
## @file
# This file is used to parse a strings file and create or add to a string database
# file.
#
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@ -7,10 +11,6 @@
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#This file is used to parse a strings file and create or add to a string database file.
#
##
# Import Modules
#

View File

@ -1,3 +1,6 @@
## @file
# This file is used to collect all defined strings in multiple uni files
#
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@ -7,10 +10,6 @@
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#This file is used to collect all defined strings in multiple uni files
#
##
# Import Modules
#

View File

@ -373,7 +373,7 @@ TAB_INF_GUIDTYPE_TSG = 'TokenSpaceGuid'
TAB_INF_GUIDTYPE_VAR = 'Variable'
TAB_INF_GUIDTYPE_PROTOCOL = 'PROTOCOL'
TAB_INF_GUIDTYPE_PPI = 'PPI'
TAB_INF_GUIDTYPE_UNDEFINED = 'UNDEFINED'
TAB_INF_USAGE_UNDEFINED = 'UNDEFINED'
#
# Dec Definitions

View File

@ -1,7 +1,7 @@
## @file
# This file is used to define common static strings used by INF/DEC/DSC files
#
# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<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
@ -69,3 +69,11 @@ gIgnoreSource = False
# FDF parser
#
gFdfParser = None
#
# If a module is built more than once with different PCDs or library classes
# a temporary INF file with same content is created, the temporary file is removed
# when build exits.
#
gTempInfs = []

View File

@ -23,6 +23,7 @@ import time
import re
import cPickle
import array
import shutil
from UserDict import IterableUserDict
from UserList import UserList
@ -43,6 +44,90 @@ gFileTimeStampCache = {} # {file path : file time stamp}
## Dictionary used to store dependencies of files
gDependencyDatabase = {} # arch : {file path : [dependent files list]}
## Routine to process duplicated INF
#
# This function is called by following two cases:
# Case 1 in DSC:
# [components.arch]
# Pkg/module/module.inf
# Pkg/module/module.inf {
# <Defines>
# FILE_GUID = 0D1B936F-68F3-4589-AFCC-FB8B7AEBC836
# }
# Case 2 in FDF:
# INF Pkg/module/module.inf
# INF FILE_GUID = 0D1B936F-68F3-4589-AFCC-FB8B7AEBC836 Pkg/module/module.inf
#
# This function copies Pkg/module/module.inf to
# Conf/.cache/0D1B936F-68F3-4589-AFCC-FB8B7AEBC836module.inf
#
# @param Path Original PathClass object
# @param BaseName New file base name
#
# @retval return the new PathClass object
#
def ProcessDuplicatedInf(Path, BaseName, Workspace):
Filename = os.path.split(Path.File)[1]
if '.' in Filename:
Filename = BaseName + Path.BaseName + Filename[Filename.rfind('.'):]
else:
Filename = BaseName + Path.BaseName
#
# If -N is specified on command line, cache is disabled
# The directory has to be created
#
DbDir = os.path.split(GlobalData.gDatabasePath)[0]
if not os.path.exists(DbDir):
os.makedirs(DbDir)
#
# A temporary INF is copied to database path which must have write permission
# The temporary will be removed at the end of build
# In case of name conflict, the file name is
# FILE_GUIDBaseName (0D1B936F-68F3-4589-AFCC-FB8B7AEBC836module.inf)
#
TempFullPath = os.path.join(DbDir,
Filename)
RtPath = PathClass(Path.File, Workspace)
#
# Modify the full path to temporary path, keep other unchanged
#
# To build same module more than once, the module path with FILE_GUID overridden has
# the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the real path
# in DSC which is used as relative path by C files and other files in INF.
# A trick was used: all module paths are PathClass instances, after the initialization
# of PathClass, the PathClass.Path is overridden by the temporary INF path.
#
# The reason for creating a temporary INF is:
# Platform.Modules which is the base to create ModuleAutoGen objects is a dictionary,
# the key is the full path of INF, the value is an object to save overridden library instances, PCDs.
# A different key for the same module is needed to create different output directory,
# retrieve overridden PCDs, library instances.
#
# The BaseName is the FILE_GUID which is also the output directory name.
#
#
RtPath.Path = TempFullPath
RtPath.BaseName = BaseName
#
# If file exists, compare contents
#
if os.path.exists(TempFullPath):
with open(str(Path), 'rb') as f1: Src = f1.read()
with open(TempFullPath, 'rb') as f2: Dst = f2.read()
if Src == Dst:
return RtPath
GlobalData.gTempInfs.append(TempFullPath)
shutil.copy2(str(Path), TempFullPath)
return RtPath
## Remove temporary created INFs whose paths were saved in gTempInfs
#
def ClearDuplicatedInf():
for File in GlobalData.gTempInfs:
if os.path.exists(File):
os.remove(File)
## callback routine for processing variable option
#
# This function can be used to process variable number of option values. The
@ -1456,6 +1541,45 @@ def CommonPath(PathList):
return os.path.sep.join(P1[:Index])
return os.path.sep.join(P1)
#
# Convert string to C format array
#
def ConvertStringToByteArray(Value):
Value = Value.strip()
if not Value:
return None
if Value[0] == '{':
if not Value.endswith('}'):
return None
Value = Value.replace(' ', '').replace('{', '').replace('}', '')
ValFields = Value.split(',')
try:
for Index in range(len(ValFields)):
ValFields[Index] = str(int(ValFields[Index], 0))
except ValueError:
return None
Value = '{' + ','.join(ValFields) + '}'
return Value
Unicode = False
if Value.startswith('L"'):
if not Value.endswith('"'):
return None
Value = Value[1:]
Unicode = True
elif not Value.startswith('"') or not Value.endswith('"'):
return None
Value = eval(Value) # translate escape character
NewValue = '{'
for Index in range(0,len(Value)):
if Unicode:
NewValue = NewValue + str(ord(Value[Index]) % 0x10000) + ','
else:
NewValue = NewValue + str(ord(Value[Index]) % 0x100) + ','
Value = NewValue + '0}'
return Value
class PathClass(object):
def __init__(self, File='', Root='', AlterRoot='', Type='', IsBinary=False,
Arch='COMMON', ToolChainFamily='', Target='', TagName='', ToolCode=''):

View File

@ -21,7 +21,7 @@ from BuildToolError import *
import GlobalData
from Common.LongFilePathSupport import OpenLongFilePath as open
gDefaultTargetTxtFile = "Conf/target.txt"
gDefaultTargetTxtFile = "target.txt"
## TargetTxtClassObject
#
@ -44,6 +44,7 @@ class TargetTxtClassObject(object):
DataType.TAB_TAT_DEFINES_TARGET_ARCH : [],
DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF : '',
}
self.ConfDirectoryPath = ""
if Filename != None:
self.LoadTargetTxtFile(Filename)
@ -78,7 +79,8 @@ class TargetTxtClassObject(object):
def ConvertTextFileToDict(self, FileName, CommentCharacter, KeySplitCharacter):
F = None
try:
F = open(FileName,'r')
F = open(FileName, 'r')
self.ConfDirectoryPath = os.path.dirname(FileName)
except:
EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=FileName)
if F != None:
@ -99,6 +101,26 @@ class TargetTxtClassObject(object):
if Key in [DataType.TAB_TAT_DEFINES_ACTIVE_PLATFORM, DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF, \
DataType.TAB_TAT_DEFINES_ACTIVE_MODULE, DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF]:
self.TargetTxtDictionary[Key] = Value.replace('\\', '/')
if Key == DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF and self.TargetTxtDictionary[Key]:
if self.TargetTxtDictionary[Key].startswith("Conf/"):
Tools_Def = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].strip())
if not os.path.exists(Tools_Def) or not os.path.isfile(Tools_Def):
# If Conf/Conf does not exist, try just the Conf/ directory
Tools_Def = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].replace("Conf/", "", 1).strip())
else:
# The File pointed to by TOOL_CHAIN_CONF is not in a Conf/ directory
Tools_Def = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].strip())
self.TargetTxtDictionary[Key] = Tools_Def
if Key == DataType.TAB_TAT_DEFINES_BUILD_RULE_CONF and self.TargetTxtDictionary[Key]:
if self.TargetTxtDictionary[Key].startswith("Conf/"):
Build_Rule = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].strip())
if not os.path.exists(Build_Rule) or not os.path.isfile(Build_Rule):
# If Conf/Conf does not exist, try just the Conf/ directory
Build_Rule = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].replace("Conf/", "", 1).strip())
else:
# The File pointed to by BUILD_RULE_CONF is not in a Conf/ directory
Build_Rule = os.path.join(self.ConfDirectoryPath, self.TargetTxtDictionary[Key].strip())
self.TargetTxtDictionary[Key] = Build_Rule
elif Key in [DataType.TAB_TAT_DEFINES_TARGET, DataType.TAB_TAT_DEFINES_TARGET_ARCH, \
DataType.TAB_TAT_DEFINES_TOOL_CHAIN_TAG]:
self.TargetTxtDictionary[Key] = Value.split()
@ -144,15 +166,15 @@ class TargetTxtClassObject(object):
print Item
## TargetTxtDict
#
# Load target.txt in input workspace dir
# Load target.txt in input Conf dir
#
# @param WorkSpace: Workspace dir
# @param ConfDir: Conf dir
#
# @retval Target An instance of TargetTxtClassObject() with loaded target.txt
#
def TargetTxtDict(WorkSpace):
def TargetTxtDict(ConfDir):
Target = TargetTxtClassObject()
Target.LoadTargetTxtFile(os.path.normpath(os.path.join(WorkSpace, gDefaultTargetTxtFile)))
Target.LoadTargetTxtFile(os.path.normpath(os.path.join(ConfDir, gDefaultTargetTxtFile)))
return Target
##

View File

@ -29,7 +29,7 @@ from Common.LongFilePathSupport import OpenLongFilePath as open
gMacroRefPattern = re.compile('(DEF\([^\(\)]+\))')
gEnvRefPattern = re.compile('(ENV\([^\(\)]+\))')
gMacroDefPattern = re.compile("DEFINE\s+([^\s]+)")
gDefaultToolsDefFile = "Conf/tools_def.txt"
gDefaultToolsDefFile = "tools_def.txt"
## ToolDefClassObject
#
@ -196,18 +196,23 @@ class ToolDefClassObject(object):
## ToolDefDict
#
# Load tools_def.txt in input workspace dir
# Load tools_def.txt in input Conf dir
#
# @param WorkSpace: Workspace dir
# @param ConfDir: Conf dir
#
# @retval ToolDef An instance of ToolDefClassObject() with loaded tools_def.txt
#
def ToolDefDict(WorkSpace):
Target = TargetTxtDict(WorkSpace)
def ToolDefDict(ConfDir):
Target = TargetTxtDict(ConfDir)
ToolDef = ToolDefClassObject()
if DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF in Target.TargetTxtDictionary:
gDefaultToolsDefFile = Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(WorkSpace, gDefaultToolsDefFile)))
ToolsDefFile = Target.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
if ToolsDefFile:
ToolDef.LoadToolDefFile(os.path.normpath(ToolsDefFile))
else:
ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(ConfDir, gDefaultToolsDefFile)))
else:
ToolDef.LoadToolDefFile(os.path.normpath(os.path.join(ConfDir, gDefaultToolsDefFile)))
return ToolDef
##

View File

@ -1,7 +1,7 @@
## @file
# This file is used to define class for data structure used in ECC
#
# Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<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
@ -29,6 +29,7 @@ MODEL_FILE_DSC = 1013
MODEL_FILE_FDF = 1014
MODEL_FILE_INC = 1015
MODEL_FILE_CIF = 1016
MODEL_FILE_UNI = 1017
MODEL_FILE_OTHERS = 1099
MODEL_IDENTIFIER_FILE_HEADER = 2001

View File

@ -18,7 +18,7 @@
from Ffs import Ffs
import Section
import subprocess
import os
import Common.LongFilePathOs as os
from GenFdsGlobalVariable import GenFdsGlobalVariable
from CommonDataClass.FdfClass import CompressSectionClassObject

View File

@ -24,6 +24,7 @@ from CommonDataClass.FdfClass import DepexSectionClassObject
from AutoGen.GenDepex import DependencyExpression
from Common import EdkLogger
from Common.BuildToolError import *
from Common.Misc import PathClass
## generate data section
#
@ -38,10 +39,22 @@ class DepexSection (DepexSectionClassObject):
def __FindGuidValue(self, CName):
for Arch in GenFdsGlobalVariable.ArchList:
for PkgDb in GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
Arch,
GenFdsGlobalVariable.TargetName,
GenFdsGlobalVariable.ToolChainTag):
PkgList = GenFdsGlobalVariable.WorkSpace.GetPackageList(GenFdsGlobalVariable.ActivePlatform,
Arch,
GenFdsGlobalVariable.TargetName,
GenFdsGlobalVariable.ToolChainTag)
for Inf in GenFdsGlobalVariable.FdfParser.Profile.InfList:
ModuleFile = PathClass(Inf, GenFdsGlobalVariable.WorkSpaceDir)
ModuleData = GenFdsGlobalVariable.WorkSpace.BuildObject[
ModuleFile,
Arch,
GenFdsGlobalVariable.TargetName,
GenFdsGlobalVariable.ToolChainTag
]
for Pkg in ModuleData.Packages:
if Pkg not in PkgList:
PkgList.append(Pkg)
for PkgDb in PkgList:
if CName in PkgDb.Ppis:
return PkgDb.Ppis[CName]
if CName in PkgDb.Protocols:

View File

@ -1,7 +1,7 @@
## @file
# process rule section generation
#
# Copyright (c) 2007, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@ -211,10 +211,10 @@ class EfiSection (EfiSectionClassObject):
"""If File List is empty"""
if FileList == [] :
if self.Optional == True:
GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
return [], None
GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!")
return [], None
else:
EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName))
EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName))
else:
"""Convert the File to Section file one by one """

View File

@ -218,6 +218,7 @@ class FdfParser:
self.CurrentFvName = None
self.__Token = ""
self.__SkippedChars = ""
GlobalData.gFdfParser = self
# Used to section info
self.__CurSection = []
@ -2356,6 +2357,9 @@ class FdfParser:
ffsInf.CurrentLineNum = self.CurrentLineNumber
ffsInf.CurrentLineContent = self.__CurrentLine()
#Replace $(SAPCE) with real space
ffsInf.InfFileName = ffsInf.InfFileName.replace('$(SPACE)', ' ')
if ffsInf.InfFileName.replace('$(WORKSPACE)', '').find('$') == -1:
#do case sensitive check for file path
ErrorCode, ErrorInfo = PathClass(NormPath(ffsInf.InfFileName), GenFdsGlobalVariable.WorkSpaceDir).Validate()
@ -2391,6 +2395,12 @@ class FdfParser:
# @param FfsInfObj for whom option is got
#
def __GetInfOptions(self, FfsInfObj):
if self.__IsKeyword("FILE_GUID"):
if not self.__IsToken("="):
raise Warning("expected '='", self.FileName, self.CurrentLineNumber)
if not self.__GetNextGuid():
raise Warning("expected GUID value", self.FileName, self.CurrentLineNumber)
FfsInfObj.OverrideGuid = self.__Token
if self.__IsKeyword( "RuleOverride"):
if not self.__IsToken( "="):
@ -2426,8 +2436,8 @@ class FdfParser:
if self.__GetNextToken():
p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\)|\*)')
if p.match(self.__Token):
p = re.compile(r'([a-zA-Z0-9\-]+|\$\(TARGET\)|\*)_([a-zA-Z0-9\-]+|\$\(TOOL_CHAIN_TAG\)|\*)_([a-zA-Z0-9\-]+|\$\(ARCH\))')
if p.match(self.__Token) and p.match(self.__Token).span()[1] == len(self.__Token):
FfsInfObj.KeyStringList.append(self.__Token)
if not self.__IsToken(","):
return
@ -2576,7 +2586,7 @@ class FdfParser:
else:
FfsFileObj.CurrentLineNum = self.CurrentLineNumber
FfsFileObj.CurrentLineContent = self.__CurrentLine()
FfsFileObj.FileName = self.__Token
FfsFileObj.FileName = self.__Token.replace('$(SPACE)', ' ')
self.__VerifyFile(FfsFileObj.FileName)
if not self.__IsToken( "}"):

View File

@ -92,6 +92,8 @@ class FileStatement (FileStatementClassObject) :
elif self.FileName != None:
self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro(self.FileName)
#Replace $(SAPCE) with real space
self.FileName = self.FileName.replace('$(SPACE)', ' ')
SectionFiles = [GenFdsGlobalVariable.MacroExtend(self.FileName, Dict)]
else:

View File

@ -30,6 +30,7 @@ from CommonDataClass.FdfClass import FfsInfStatementClassObject
from Common.String import *
from Common.Misc import PathClass
from Common.Misc import GuidStructureByteArrayToGuidString
from Common.Misc import ProcessDuplicatedInf
from Common import EdkLogger
from Common.BuildToolError import *
from GuidSection import GuidSection
@ -64,6 +65,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
self.CurrentLineContent = None
self.FileName = None
self.InfFileName = None
self.OverrideGuid = None
self.PatchedBinFile = ''
## GetFinalTargetSuffixMap() method
#
@ -145,7 +148,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)
self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')
if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :
if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\':
pass
elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :
self.InfFileName = self.InfFileName[1:]
if self.InfFileName.find('$') == -1:
@ -164,7 +169,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
if ErrorCode != 0:
EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
if self.OverrideGuid:
PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)
if self.CurrentArch != None:
Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
@ -199,6 +206,9 @@ class FfsInfStatement(FfsInfStatementClassObject):
"INF %s specified in FDF could not be found in build ARCH %s!" \
% (self.InfFileName, GenFdsGlobalVariable.ArchList))
if self.OverrideGuid:
self.ModuleGuid = self.OverrideGuid
if len(self.SourceFileList) != 0 and not self.InDsc:
EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))
@ -285,8 +295,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]:
EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \
% (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
Pcd.DefaultValue = DefaultValue
self.PatchPcds.append(Pcd)
self.PatchPcds.append((Pcd, DefaultValue))
self.InfModule = Inf
self.PcdIsDriver = Inf.PcdIsDriver
self.IsBinaryModule = Inf.IsBinaryModule
@ -308,7 +318,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
self.EfiOutputPath = self.__GetEFIOutPutPath__()
GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
## PatchEfiFile
## PatchEfiFile
#
# Patch EFI file with patch PCD
#
@ -316,18 +326,25 @@ class FfsInfStatement(FfsInfStatementClassObject):
# @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
# If passed in file does not end with efi, return as is
#
def PatchEfiFile(self, EfiFile):
if os.path.splitext(EfiFile)[1].lower() != '.efi':
return EfiFile
def PatchEfiFile(self, EfiFile, FileType):
if not self.PatchPcds:
return EfiFile
if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":
return EfiFile
if self.PatchedBinFile:
EdkLogger.error("GenFds", GENFDS_ERROR,
'Only one binary file can be patched:\n'
' a binary file has been patched: %s\n'
' current file: %s' % (self.PatchedBinFile, EfiFile),
File=self.InfFileName)
Basename = os.path.basename(EfiFile)
Output = os.path.join(self.OutputPath, Basename)
CopyLongFilePath(EfiFile, Output)
for Pcd in self.PatchPcds:
RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Pcd.DefaultValue, Pcd.MaxDatumSize)
for Pcd, Value in self.PatchPcds:
RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)
if RetVal:
EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)
self.PatchedBinFile = os.path.normpath(EfiFile)
return Output
## GenFfs() method
#
@ -349,7 +366,7 @@ class FfsInfStatement(FfsInfStatementClassObject):
#
# Allow binary type module not specify override rule in FDF file.
#
if len(self.BinFileList) >0 and not self.InDsc:
if len(self.BinFileList) > 0:
if self.Rule == None or self.Rule == "":
self.Rule = "BINARY"
@ -568,6 +585,8 @@ class FfsInfStatement(FfsInfStatementClassObject):
(ModulePath, FileName) = os.path.split(self.InfFileName)
Index = FileName.rfind('.')
FileName = FileName[0:Index]
if self.OverrideGuid:
FileName = self.OverrideGuid
Arch = "NoneArch"
if self.CurrentArch != None:
Arch = self.CurrentArch

View File

@ -36,6 +36,7 @@ from Common import EdkLogger
from Common.String import *
from Common.Misc import DirCache,PathClass
from Common.Misc import SaveFileOnChange
from Common.Misc import ClearDuplicatedInf
from Common.Misc import GuidStructureStringToGuidString
from Common.BuildVersion import gBUILD_VERSION
@ -149,15 +150,36 @@ def main():
GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform), Workspace)
BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt"))
if (Options.ConfDirectory):
# Get alternate Conf location, if it is absolute, then just use the absolute directory name
ConfDirectoryPath = os.path.normpath(Options.ConfDirectory)
if ConfDirectoryPath.startswith('"'):
ConfDirectoryPath = ConfDirectoryPath[1:]
if ConfDirectoryPath.endswith('"'):
ConfDirectoryPath = ConfDirectoryPath[:-1]
if not os.path.isabs(ConfDirectoryPath):
# Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
# This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath)
else:
# Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf
ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf')
GenFdsGlobalVariable.ConfDir = ConfDirectoryPath
BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt"))
if os.path.isfile(BuildConfigurationFile) == True:
TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile)
else:
EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile)
#Set global flag for build mode
GlobalData.gIgnoreSource = Options.IgnoreSources
if Options.Macros:
for Pair in Options.Macros:
Pair = Pair.strip('"')
if Pair.startswith('"'):
Pair = Pair[1:]
if Pair.endswith('"'):
Pair = Pair[:-1]
List = Pair.split('=')
if len(List) == 2:
if List[0].strip() == "EFI_SOURCE":
@ -177,7 +199,8 @@ def main():
os.environ["WORKSPACE"] = Workspace
"""call Workspace build create database"""
BuildWorkSpace = WorkspaceDatabase(None)
GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))
BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath)
BuildWorkSpace.InitDatabase()
#
@ -276,11 +299,13 @@ def main():
"\nPython",
CODE_ERROR,
"Tools code failure",
ExtraData="Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!\n",
ExtraData="Please send email to edk2-devel@lists.sourceforge.net for help, attaching following call stack trace!\n",
RaiseError=False
)
EdkLogger.quiet(traceback.format_exc())
ReturnCode = CODE_ERROR
finally:
ClearDuplicatedInf()
return ReturnCode
gParamCheck = []
@ -321,6 +346,9 @@ def myOptionParser():
action="callback", callback=SingleCheckCallback)
Parser.add_option("-D", "--define", action="append", type="string", dest="Macros", help="Macro: \"Name [= Value]\".")
Parser.add_option("-s", "--specifyaddress", dest="FixedAddress", action="store_true", type=None, help="Specify driver load address.")
Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")
Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")
(Options, args) = Parser.parse_args()
return Options

View File

@ -45,6 +45,7 @@ class GenFdsGlobalVariable:
LibDir = ''
WorkSpace = None
WorkSpaceDir = ''
ConfDir = ''
EdkSourceDir = ''
OutputDirFromDscDict = {}
TargetName = ''
@ -88,7 +89,7 @@ class GenFdsGlobalVariable:
def __LoadBuildRule():
if GenFdsGlobalVariable.__BuildRuleDatabase:
return GenFdsGlobalVariable.__BuildRuleDatabase
BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.WorkSpaceDir, "Conf/target.txt"))
BuildConfigurationFile = os.path.normpath(os.path.join(GenFdsGlobalVariable.ConfDir, "target.txt"))
TargetTxt = TargetTxtClassObject()
if os.path.isfile(BuildConfigurationFile) == True:
TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
@ -201,11 +202,13 @@ class GenFdsGlobalVariable:
TargetList = set()
FileList = []
for File in Inf.Sources:
if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \
File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):
FileList.append((File, DataType.TAB_UNKNOWN_FILE))
if not Inf.IsBinaryModule:
for File in Inf.Sources:
if File.TagName in ("", "*", GenFdsGlobalVariable.ToolChainTag) and \
File.ToolChainFamily in ("", "*", GenFdsGlobalVariable.ToolChainFamily):
FileList.append((File, DataType.TAB_UNKNOWN_FILE))
for File in Inf.Binaries:
if File.Target in ['COMMON', '*', GenFdsGlobalVariable.TargetName]:
FileList.append((File, File.Type))
@ -645,7 +648,8 @@ class GenFdsGlobalVariable:
'$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir,
# '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc,
'$(TARGET)' : GenFdsGlobalVariable.TargetName,
'$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag
'$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag,
'$(SPACE)' : ' '
}
OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]]
if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList:

View File

@ -198,7 +198,7 @@ class GuidSection(GuidSectionClassObject) :
HeaderLength = str(self.ExtraHeaderSize)
if self.ProcessRequired == "NONE" and HeaderLength == None:
if TempFileSize > InputFileSize and TempFileSize % 4 == 0:
if TempFileSize > InputFileSize:
FileHandleIn.seek(0)
BufferIn = FileHandleIn.read()
FileHandleOut.seek(0)
@ -247,15 +247,15 @@ class GuidSection(GuidSectionClassObject) :
if self.KeyStringList == None or self.KeyStringList == []:
Target = GenFdsGlobalVariable.TargetName
ToolChain = GenFdsGlobalVariable.ToolChainTag
ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDatabase
ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase
if ToolChain not in ToolDb['TOOL_CHAIN_TAG']:
EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain)
self.KeyStringList = [Target+'_'+ToolChain+'_'+self.CurrentArchList[0]]
for Arch in self.CurrentArchList:
if Target+'_'+ToolChain+'_'+Arch not in self.KeyStringList:
self.KeyStringList.append(Target+'_'+ToolChain+'_'+Arch)
ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.WorkSpaceDir).ToolsDefTxtDictionary
if Target + '_' + ToolChain + '_' + Arch not in self.KeyStringList:
self.KeyStringList.append(Target + '_' + ToolChain + '_' + Arch)
ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary
ToolPathTmp = None
for ToolDef in ToolDefinition.items():
if self.NameGuid == ToolDef[1]:

View File

@ -129,9 +129,11 @@ class Section (SectionClassObject):
if FileType != None:
for File in FfsInf.BinFileList:
if File.Arch == "COMMON" or FfsInf.CurrentArch == File.Arch:
if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A and FileType == 'DXE_DPEX'and File.Type == 'SMM_DEPEX'):
if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A \
and FileType == 'DXE_DPEX'and File.Type == 'SMM_DEPEX') \
or (FileType == 'TE'and File.Type == 'PE32'):
if '*' in FfsInf.TargetOverrideList or File.Target == '*' or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []:
FileList.append(FfsInf.PatchEfiFile(File.Path))
FileList.append(FfsInf.PatchEfiFile(File.Path, File.Type))
else:
GenFdsGlobalVariable.InfLogger ("\nBuild Target \'%s\' of File %s is not in the Scope of %s specified by INF %s in FDF" %(File.Target, File.File, FfsInf.TargetOverrideList, FfsInf.InfFileName))
else:

View File

@ -1,3 +1,5 @@
## @file
# Target Tool Parser
#
# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
#

View File

@ -594,7 +594,7 @@ def Main():
"\nTrim",
CODE_ERROR,
"Unknown fatal error when trimming [%s]" % InputFile,
ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
ExtraData="\n(Please send email to edk2-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
RaiseError=False
)
EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())

View File

@ -320,7 +320,7 @@ MSG_NEW_FILE_NAME_FOR_DIST = _(
MSG_UPDATE_PACKAGE_DATABASE = _("Update Distribution Package Database ...")
MSG_PYTHON_ON = _("(Python %s on %s) ")
MSG_SEARCH_FOR_HELP = _(
"\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for\n"
"\n(Please send email to edk2-devel@lists.sourceforge.net for\n"
" help, attach the following call stack trace.)\n")
MSG_REMOVE_TEMP_FILE_STARTED = _("Removing temp files started ... ")
MSG_REMOVE_TEMP_FILE_DONE = _("Removing temp files ... Done.")

View File

@ -25,4 +25,27 @@ import Common.EdkLogger as EdkLogger
UsageList = ("PRODUCES", "PRODUCED", "ALWAYS_PRODUCES", "ALWAYS_PRODUCED", "SOMETIMES_PRODUCES",
"SOMETIMES_PRODUCED", "CONSUMES", "CONSUMED", "ALWAYS_CONSUMES", "ALWAYS_CONSUMED",
"SOMETIMES_CONSUMES", "SOMETIMES_CONSUMED", "SOMETIME_CONSUMES")
ErrorMsgMap = {
MODEL_EFI_GUID : "The usage for this GUID is not listed in this INF: %s[%d]:%s",
MODEL_EFI_PPI : "The usage for this PPI is not listed in this INF: %s[%d]:%s.",
MODEL_EFI_PROTOCOL : "The usage for this Protocol is not listed in this INF: %s[%d]:%s.",
MODEL_PCD_DYNAMIC : "The usage for this PCD is not listed in this INF: %s[%d]:%s."
}
def CheckInfComment(SectionType, Comments, InfFile, LineNo, ValueList):
if SectionType in [MODEL_PCD_PATCHABLE_IN_MODULE, MODEL_PCD_DYNAMIC_EX, MODEL_PCD_DYNAMIC]:
CheckUsage(Comments, UsageList, InfFile, LineNo, ValueList[0]+'.'+ValueList[1], ErrorMsgMap[MODEL_PCD_DYNAMIC])
elif SectionType in [MODEL_EFI_GUID, MODEL_EFI_PPI]:
CheckUsage(Comments, UsageList, InfFile, LineNo, ValueList[0], ErrorMsgMap[SectionType])
elif SectionType == MODEL_EFI_PROTOCOL:
CheckUsage(Comments, UsageList + ("TO_START", "BY_START"), InfFile, LineNo, ValueList[0], ErrorMsgMap[SectionType])
def CheckUsage(Comments, Usages, InfFile, LineNo, Value, ErrorMsg):
for Comment in Comments:
for Word in Comment[0].replace('#', ' ').split():
if Word in Usages:
return
EdkLogger.error(
"Parser", FORMAT_INVALID,
ErrorMsg % (InfFile, LineNo, Value)
)

View File

@ -31,6 +31,7 @@ from CommonDataClass.Exceptions import *
from Common.LongFilePathSupport import OpenLongFilePath as open
from MetaFileTable import MetaFileStorage
from MetaFileCommentParser import CheckInfComment
## A decorator used to parse macro definition
def ParseMacro(Parser):
@ -595,6 +596,8 @@ class InfParser(MetaFileParser):
continue
if Comment:
Comments.append((Comment, Index + 1))
if GlobalData.gOptions and GlobalData.gOptions.CheckUsage:
CheckInfComment(self._SectionType, Comments, str(self.MetaFile), Index + 1, self._ValueList)
#
# Model, Value1, Value2, Value3, Arch, Platform, BelongsToItem=-1,
# LineBegin=-1, ColumnBegin=-1, LineEnd=-1, ColumnEnd=-1, Enabled=-1
@ -823,6 +826,10 @@ class DscParser(MetaFileParser):
"FIX_LOAD_TOP_MEMORY_ADDRESS"
]
SubSectionDefineKeywords = [
"FILE_GUID"
]
SymbolPattern = ValueExpression.SymbolPattern
## Constructor of DscParser
@ -1041,13 +1048,15 @@ class DscParser(MetaFileParser):
if not self._ValueList[2]:
EdkLogger.error('Parser', FORMAT_INVALID, "No value specified",
ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
if not self._ValueList[1] in self.DefineKeywords:
if (not self._ValueList[1] in self.DefineKeywords and
(self._InSubsection and self._ValueList[1] not in self.SubSectionDefineKeywords)):
EdkLogger.error('Parser', FORMAT_INVALID,
"Unknown keyword found: %s. "
"If this is a macro you must "
"add it as a DEFINE in the DSC" % self._ValueList[1],
ExtraData=self._CurrentLine, File=self.MetaFile, Line=self._LineIndex + 1)
self._Defines[self._ValueList[1]] = self._ValueList[2]
if not self._InSubsection:
self._Defines[self._ValueList[1]] = self._ValueList[2]
self._ItemType = self.DataType[TAB_DSC_DEFINES.upper()]
@ParseMacro
@ -1226,6 +1235,7 @@ class DscParser(MetaFileParser):
self.__RetrievePcdValue()
self._Content = self._RawTable.GetAll()
self._ContentIndex = 0
self._InSubsection = False
while self._ContentIndex < len(self._Content) :
Id, self._ItemType, V1, V2, V3, S1, S2, Owner, self._From, \
LineStart, ColStart, LineEnd, ColEnd, Enabled = self._Content[self._ContentIndex]
@ -1254,6 +1264,10 @@ class DscParser(MetaFileParser):
self._LineIndex = LineStart - 1
self._ValueList = [V1, V2, V3]
if Owner > 0 and Owner in self._IdMapping:
self._InSubsection = True
else:
self._InSubsection = False
try:
Processer[self._ItemType]()
except EvaluationException, Excpt:
@ -1356,6 +1370,13 @@ class DscParser(MetaFileParser):
Type, Name, Value = self._ValueList
Value = ReplaceMacro(Value, self._Macros, False)
#
# If it is <Defines>, return
#
if self._InSubsection:
self._ValueList = [Type, Name, Value]
return
if self._ItemType == MODEL_META_DATA_DEFINE:
if self._SectionType == MODEL_META_DATA_HEADER:
self._FileLocalMacros[Name] = Value

View File

@ -35,9 +35,12 @@ 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
import Common.GlobalData as GlobalData
## Platform build information from DSC file
#
# This class is used to retrieve information stored in database and convert them
@ -103,6 +106,7 @@ class DscBuildData(PlatformBuildClassObject):
self._Target = Target
self._Toolchain = Toolchain
self._Clear()
self._HandleOverridePath()
## XXX[key] = value
def __setitem__(self, key, value):
@ -147,6 +151,27 @@ class DscBuildData(PlatformBuildClassObject):
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 = os.path.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:
@ -478,6 +503,7 @@ class DscBuildData(PlatformBuildClassObject):
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]
@ -490,23 +516,11 @@ class DscBuildData(PlatformBuildClassObject):
# 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:
EdkLogger.error('build', FILE_DUPLICATED, File=self.MetaFile, ExtraData=str(ModuleFile), Line=LineNo)
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:
@ -563,6 +577,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 <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
@ -641,9 +665,26 @@ class DscBuildData(PlatformBuildClassObject):
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." % (TokenSpaceGuid, PcdCName),
"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]:
@ -1676,6 +1717,9 @@ class InfBuildData(ModuleBuildClassObject):
# items defined _PROPERTY_ don't need additional processing
if Name in self:
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'):
@ -2309,6 +2353,13 @@ 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)
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:
DepexStr = ReplaceMacro(Record[0], self._Macros, False)
@ -2570,8 +2621,6 @@ class InfBuildData(ModuleBuildClassObject):
#
class WorkspaceDatabase(object):
# default database file path
_DB_PATH_ = "Conf/.cache/build.db"
#
# internal class used for call corresponding file parser and caching the result
@ -2682,7 +2731,7 @@ class WorkspaceDatabase(object):
def __init__(self, DbPath, RenewDb=False):
self._DbClosedFlag = False
if not DbPath:
DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, self._DB_PATH_))
DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath))
# don't create necessary path for db in memory
if DbPath != ':memory:':

View File

@ -57,9 +57,8 @@ __copyright__ = "Copyright (c) 2007 - 2014, Intel Corporation All rights reserv
gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run']
## build configuration file
gBuildConfiguration = "Conf/target.txt"
gBuildCacheDir = "Conf/.cache"
gToolsDefinition = "Conf/tools_def.txt"
gBuildConfiguration = "target.txt"
gToolsDefinition = "tools_def.txt"
TemporaryTablePattern = re.compile(r'^_\d+_\d+_[a-fA-F0-9]+$')
TmpTableDict = {}
@ -630,7 +629,8 @@ class BuildTask:
#
def AddDependency(self, Dependency):
for Dep in Dependency:
self.DependencyList.append(BuildTask.New(Dep)) # BuildTask list
if not Dep.BuildObject.IsBinaryModule:
self.DependencyList.append(BuildTask.New(Dep)) # BuildTask list
## The thread wrapper of LaunchCommand function
#
@ -732,18 +732,34 @@ class Build():
self.SkipAutoGen = BuildOptions.SkipAutoGen
self.Reparse = BuildOptions.Reparse
self.SkuId = BuildOptions.SkuId
self.ConfDirectory = BuildOptions.ConfDirectory
self.SpawnMode = True
self.BuildReport = BuildReport(BuildOptions.ReportFile, BuildOptions.ReportType)
self.TargetTxt = TargetTxtClassObject()
self.ToolDef = ToolDefClassObject()
#Set global flag for build mode
GlobalData.gIgnoreSource = BuildOptions.IgnoreSources
if self.ConfDirectory:
# Get alternate Conf location, if it is absolute, then just use the absolute directory name
ConfDirectoryPath = os.path.normpath(self.ConfDirectory)
if not os.path.isabs(ConfDirectoryPath):
# Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE
# This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf
ConfDirectoryPath = os.path.join(self.WorkspaceDir, ConfDirectoryPath)
else:
# Get standard WORKSPACE/Conf use the absolute path to the WORKSPACE/Conf
ConfDirectoryPath = os.path.join(self.WorkspaceDir, 'Conf')
GlobalData.gConfDirectory = ConfDirectoryPath
GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath))
if BuildOptions.DisableCache:
self.Db = WorkspaceDatabase(":memory:")
else:
self.Db = WorkspaceDatabase(None, self.Reparse)
self.BuildDatabase = self.Db.BuildObject
self.Platform = None
self.Db = WorkspaceDatabase(GlobalData.gDatabasePath, self.Reparse)
self.BuildDatabase = self.Db.BuildObject
self.Platform = None
self.LoadFixAddress = 0
self.UniFlag = BuildOptions.Flag
self.BuildModules = []
@ -772,14 +788,14 @@ class Build():
#
# Check target.txt and tools_def.txt and Init them
#
BuildConfigurationFile = os.path.normpath(os.path.join(self.WorkspaceDir, gBuildConfiguration))
BuildConfigurationFile = os.path.normpath(os.path.join(GlobalData.gConfDirectory, gBuildConfiguration))
if os.path.isfile(BuildConfigurationFile) == True:
StatusCode = self.TargetTxt.LoadTargetTxtFile(BuildConfigurationFile)
ToolDefinitionFile = self.TargetTxt.TargetTxtDictionary[DataType.TAB_TAT_DEFINES_TOOL_CHAIN_CONF]
if ToolDefinitionFile == '':
ToolDefinitionFile = gToolsDefinition
ToolDefinitionFile = os.path.normpath(os.path.join(self.WorkspaceDir, ToolDefinitionFile))
ToolDefinitionFile = os.path.normpath(os.path.join(self.WorkspaceDir, 'Conf', ToolDefinitionFile))
if os.path.isfile(ToolDefinitionFile) == True:
StatusCode = self.ToolDef.LoadToolDefFile(ToolDefinitionFile)
else:
@ -1079,7 +1095,7 @@ class Build():
# First should close DB.
#
self.Db.Close()
RemoveDirectory(gBuildCacheDir, True)
RemoveDirectory(os.path.dirname(GlobalData.gDatabasePath), True)
except WindowsError, X:
EdkLogger.error("build", FILE_DELETE_FAILURE, ExtraData=str(X))
return True
@ -1804,19 +1820,19 @@ class Build():
EdkLogger.SetLevel(OldLogLevel)
def DumpBuildData(self):
CacheDirectory = os.path.join(self.WorkspaceDir, gBuildCacheDir)
CacheDirectory = os.path.dirname(GlobalData.gDatabasePath)
Utils.CreateDirectory(CacheDirectory)
Utils.DataDump(Utils.gFileTimeStampCache, os.path.join(CacheDirectory, "gFileTimeStampCache"))
Utils.DataDump(Utils.gDependencyDatabase, os.path.join(CacheDirectory, "gDependencyDatabase"))
def RestoreBuildData(self):
FilePath = os.path.join(self.WorkspaceDir, gBuildCacheDir, "gFileTimeStampCache")
FilePath = os.path.join(os.path.dirname(GlobalData.gDatabasePath), "gFileTimeStampCache")
if Utils.gFileTimeStampCache == {} and os.path.isfile(FilePath):
Utils.gFileTimeStampCache = Utils.DataRestore(FilePath)
if Utils.gFileTimeStampCache == None:
Utils.gFileTimeStampCache = {}
FilePath = os.path.join(self.WorkspaceDir, gBuildCacheDir, "gDependencyDatabase")
FilePath = os.path.join(os.path.dirname(GlobalData.gDatabasePath), "gDependencyDatabase")
if Utils.gDependencyDatabase == {} and os.path.isfile(FilePath):
Utils.gDependencyDatabase = Utils.DataRestore(FilePath)
if Utils.gDependencyDatabase == None:
@ -1905,6 +1921,8 @@ def MyOptionParser():
"This option can also be specified by setting *_*_*_BUILD_FLAGS in [BuildOptions] section of platform DSC. If they are both specified, this value "\
"will override the setting in [BuildOptions] section of platform DSC.")
Parser.add_option("-N", "--no-cache", action="store_true", dest="DisableCache", default=False, help="Disable build cache mechanism")
Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.")
Parser.add_option("--check-usage", action="store_true", dest="CheckUsage", default=False, help="Check usage content of entries listed in INF file.")
Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files")
(Opt, Args)=Parser.parse_args()
@ -2064,13 +2082,14 @@ def Main():
"\nbuild",
CODE_ERROR,
"Unknown fatal error when processing [%s]" % MetaFile,
ExtraData="\n(Please send email to edk2-buildtools-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
ExtraData="\n(Please send email to edk2-devel@lists.sourceforge.net for help, attaching following call stack trace!)\n",
RaiseError=False
)
EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
ReturnCode = CODE_ERROR
finally:
Utils.Progressor.Abort()
Utils.ClearDuplicatedInf()
if ReturnCode == 0:
Conclusion = "Done"

View File

@ -1,5 +1,7 @@
## @file
#
# Copyright (c) 2009 - 2010, Apple Inc. All rights reserved.<BR>
#
# Copyright (c) 2009 - 2014, Apple Inc. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License