summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/Workspace
diff options
context:
space:
mode:
authorYonghong Zhu <yonghong.zhu@intel.com>2016-05-10 17:58:26 +0800
committerYonghong Zhu <yonghong.zhu@intel.com>2016-05-18 08:59:30 +0800
commitc28d2e1047816164ffec552e4a3375122cbcc6b6 (patch)
tree20c8ba16e7f4ed1a8ef4f135ef82e79f83ae3580 /BaseTools/Source/Python/Workspace
parentbba734ab4c7c9b4386d39420983bf61484f65dda (diff)
downloadedk2-platforms-c28d2e1047816164ffec552e4a3375122cbcc6b6.tar.xz
BaseTools: support private package definition
EDKII build spec and DEC spec updated to support private package definition. If GUID, Protocol or PPI is listed in a DEC file, where the Private modifier is used in the section tag ([Guids.common.Private] for example), only modules within the package are permitted to use the GUID, Protocol or PPI. If a module or library instance outside of the package attempts to use the item, the build must fail with an appropriate error message. Cc: Liming Gao <liming.gao@intel.com> Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Yonghong Zhu <yonghong.zhu@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
Diffstat (limited to 'BaseTools/Source/Python/Workspace')
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileParser.py12
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileTable.py4
-rw-r--r--BaseTools/Source/Python/Workspace/WorkspaceDatabase.py59
3 files changed, 61 insertions, 14 deletions
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 209f47c9eb..82d874f8dd 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -1722,6 +1722,7 @@ class DecParser(MetaFileParser):
self._SectionName = ''
self._SectionType = []
ArchList = set()
+ PrivateList = set()
Line = self._CurrentLine.replace("%s%s" % (TAB_COMMA_SPLIT, TAB_SPACE_SPLIT), TAB_COMMA_SPLIT)
for Item in Line[1:-1].split(TAB_COMMA_SPLIT):
if Item == '':
@@ -1757,8 +1758,14 @@ class DecParser(MetaFileParser):
# S2 may be Platform or ModuleType
if len(ItemList) > 2:
S2 = ItemList[2].upper()
+ # only Includes, GUIDs, PPIs, Protocols section have Private tag
+ if self._SectionName in [TAB_INCLUDES.upper(), TAB_GUIDS.upper(), TAB_PROTOCOLS.upper(), TAB_PPIS.upper()]:
+ if S2 != 'PRIVATE':
+ EdkLogger.error("Parser", FORMAT_INVALID, 'Please use keyword "Private" as section tag modifier.',
+ File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
else:
S2 = 'COMMON'
+ PrivateList.add(S2)
if [S1, S2, self.DataType[self._SectionName]] not in self._Scope:
self._Scope.append([S1, S2, self.DataType[self._SectionName]])
@@ -1767,6 +1774,11 @@ class DecParser(MetaFileParser):
EdkLogger.error('Parser', FORMAT_INVALID, "'common' ARCH must not be used with specific ARCHs",
File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
+ # It is not permissible to mix section tags without the Private attribute with section tags with the Private attribute
+ if 'COMMON' in PrivateList and len(PrivateList) > 1:
+ EdkLogger.error('Parser', FORMAT_INVALID, "Can't mix section tags without the Private attribute with section tags with the Private attribute",
+ File=self.MetaFile, Line=self._LineIndex + 1, ExtraData=self._CurrentLine)
+
## [guids], [ppis] and [protocols] section parser
@ParseMacro
def _GuidParser(self):
diff --git a/BaseTools/Source/Python/Workspace/MetaFileTable.py b/BaseTools/Source/Python/Workspace/MetaFileTable.py
index 449e56efcc..ab1807046e 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileTable.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileTable.py
@@ -1,7 +1,7 @@
## @file
# This file is used to create/update/query/erase a meta file table
#
-# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2008 - 2016, 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
@@ -218,7 +218,7 @@ class PackageTable(MetaFileTable):
#
def Query(self, Model, Arch=None):
ConditionString = "Model=%s AND Enabled>=0" % Model
- ValueString = "Value1,Value2,Value3,Scope1,ID,StartLine"
+ ValueString = "Value1,Value2,Value3,Scope1,Scope2,ID,StartLine"
if Arch != None and Arch != 'COMMON':
ConditionString += " AND (Scope1='%s' OR Scope1='COMMON')" % Arch
diff --git a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
index 7cd0004688..5168e838a8 100644
--- a/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
+++ b/BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
@@ -1328,6 +1328,10 @@ class DecBuildData(PackageBuildClassObject):
self._LibraryClasses = None
self._Pcds = None
self.__Macros = None
+ self._PrivateProtocols = None
+ self._PrivatePpis = None
+ self._PrivateGuids = None
+ self._PrivateIncludes = None
## Get current effective macros
def _GetMacros(self):
@@ -1402,21 +1406,30 @@ class DecBuildData(PackageBuildClassObject):
# protocol defition for given ARCH
#
ProtocolDict = tdict(True)
+ PrivateProtocolDict = tdict(True)
NameList = []
+ PrivateNameList = []
# find out all protocol definitions for specific and 'common' arch
RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch]
- for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivateProtocolDict[Arch, Name] = Guid
if Name not in NameList:
NameList.append(Name)
ProtocolDict[Arch, Name] = Guid
# use sdict to keep the order
self._Protocols = sdict()
+ self._PrivateProtocols = sdict()
for Name in NameList:
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
self._Protocols[Name] = ProtocolDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivateProtocols[Name] = PrivateProtocolDict[self._Arch, Name]
return self._Protocols
## Retrieve PPI definitions (name/value pairs)
@@ -1427,21 +1440,30 @@ class DecBuildData(PackageBuildClassObject):
# PPI defition for given ARCH
#
PpiDict = tdict(True)
+ PrivatePpiDict = tdict(True)
NameList = []
+ PrivateNameList = []
# find out all PPI definitions for specific arch and 'common' arch
RecordList = self._RawData[MODEL_EFI_PPI, self._Arch]
- for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivatePpiDict[Arch, Name] = Guid
if Name not in NameList:
NameList.append(Name)
PpiDict[Arch, Name] = Guid
# use sdict to keep the order
self._Ppis = sdict()
+ self._PrivatePpis = sdict()
for Name in NameList:
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
self._Ppis[Name] = PpiDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivatePpis[Name] = PrivatePpiDict[self._Arch, Name]
return self._Ppis
## Retrieve GUID definitions (name/value pairs)
@@ -1452,27 +1474,37 @@ class DecBuildData(PackageBuildClassObject):
# GUID defition for given ARCH
#
GuidDict = tdict(True)
+ PrivateGuidDict = tdict(True)
NameList = []
+ PrivateNameList = []
# find out all protocol definitions for specific and 'common' arch
RecordList = self._RawData[MODEL_EFI_GUID, self._Arch]
- for Name, Guid, Dummy, Arch, ID, LineNo in RecordList:
+ for Name, Guid, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
+ if PrivateFlag == 'PRIVATE':
+ if Name not in PrivateNameList:
+ PrivateNameList.append(Name)
+ PrivateGuidDict[Arch, Name] = Guid
if Name not in NameList:
NameList.append(Name)
GuidDict[Arch, Name] = Guid
# use sdict to keep the order
self._Guids = sdict()
+ self._PrivateGuids = sdict()
for Name in NameList:
#
# limit the ARCH to self._Arch, if no self._Arch found, tdict
# will automatically turn to 'common' ARCH for trying
#
self._Guids[Name] = GuidDict[self._Arch, Name]
+ for Name in PrivateNameList:
+ self._PrivateGuids[Name] = PrivateGuidDict[self._Arch, Name]
return self._Guids
## Retrieve public include paths declared in this package
def _GetInclude(self):
if self._Includes == None:
self._Includes = []
+ self._PrivateIncludes = []
RecordList = self._RawData[MODEL_EFI_INCLUDE, self._Arch]
Macros = self._Macros
Macros["EDK_SOURCE"] = GlobalData.gEcpSource
@@ -1487,6 +1519,9 @@ class DecBuildData(PackageBuildClassObject):
# avoid duplicate include path
if File not in self._Includes:
self._Includes.append(File)
+ if Record[4] == 'PRIVATE':
+ if File not in self._PrivateIncludes:
+ self._PrivateIncludes.append(File)
return self._Includes
## Retrieve library class declarations (not used in build at present)
@@ -1500,7 +1535,7 @@ class DecBuildData(PackageBuildClassObject):
LibraryClassSet = set()
RecordList = self._RawData[MODEL_EFI_LIBRARY_CLASS, self._Arch]
Macros = self._Macros
- for LibraryClass, File, Dummy, Arch, ID, LineNo in RecordList:
+ for LibraryClass, File, Dummy, Arch, PrivateFlag, ID, LineNo in RecordList:
File = PathClass(NormPath(File, Macros), self._PackageDir, Arch=self._Arch)
# check the file validation
ErrorCode, ErrorInfo = File.Validate()
@@ -1536,7 +1571,7 @@ class DecBuildData(PackageBuildClassObject):
PcdSet = set()
# find out all PCDs of the 'type'
RecordList = self._RawData[Type, self._Arch]
- for TokenSpaceGuid, PcdCName, Setting, Arch, Dummy1, Dummy2 in RecordList:
+ for TokenSpaceGuid, PcdCName, Setting, Arch, PrivateFlag, Dummy1, Dummy2 in RecordList:
PcdDict[Arch, PcdCName, TokenSpaceGuid] = Setting
PcdSet.add((PcdCName, TokenSpaceGuid))
@@ -2275,7 +2310,7 @@ class InfBuildData(ModuleBuildClassObject):
RecordList = self._RawData[MODEL_EFI_PROTOCOL, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = ProtocolValue(CName, self.Packages)
+ Value = ProtocolValue(CName, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -2300,7 +2335,7 @@ class InfBuildData(ModuleBuildClassObject):
RecordList = self._RawData[MODEL_EFI_PPI, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = PpiValue(CName, self.Packages)
+ Value = PpiValue(CName, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -2325,7 +2360,7 @@ class InfBuildData(ModuleBuildClassObject):
RecordList = self._RawData[MODEL_EFI_GUID, self._Arch, self._Platform]
for Record in RecordList:
CName = Record[0]
- Value = GuidValue(CName, self.Packages)
+ Value = GuidValue(CName, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -2494,11 +2529,11 @@ class InfBuildData(ModuleBuildClassObject):
DepexList.append(Module.Guid)
else:
# get the GUID value now
- Value = ProtocolValue(Token, self.Packages)
+ Value = ProtocolValue(Token, self.Packages, self.MetaFile.Path)
if Value == None:
- Value = PpiValue(Token, self.Packages)
+ Value = PpiValue(Token, self.Packages, self.MetaFile.Path)
if Value == None:
- Value = GuidValue(Token, self.Packages)
+ Value = GuidValue(Token, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,
@@ -2541,7 +2576,7 @@ class InfBuildData(ModuleBuildClassObject):
PcdList.append((PcdCName, TokenSpaceGuid))
# get the guid value
if TokenSpaceGuid not in self.Guids:
- Value = GuidValue(TokenSpaceGuid, self.Packages)
+ Value = GuidValue(TokenSpaceGuid, self.Packages, self.MetaFile.Path)
if Value == None:
PackageList = "\n\t".join([str(P) for P in self.Packages])
EdkLogger.error('build', RESOURCE_NOT_AVAILABLE,