[edk2] [Patch] BaseTools: Structure Pcd in CommandLine.

BobCF posted 1 patch 6 years, 9 months ago
Failed in applying to current master (apply log)
BaseTools/Source/Python/AutoGen/AutoGen.py        | 110 +++---------
BaseTools/Source/Python/Common/Expression.py      |   2 +-
BaseTools/Source/Python/Common/Misc.py            |   2 +-
BaseTools/Source/Python/GenFds/FfsInfStatement.py |   1 +
BaseTools/Source/Python/GenFds/GenFds.py          |   4 +-
BaseTools/Source/Python/Workspace/DscBuildData.py | 210 +++++++++++++++++++++-
BaseTools/Source/Python/build/build.py            |   2 +-
7 files changed, 233 insertions(+), 98 deletions(-)
[edk2] [Patch] BaseTools: Structure Pcd in CommandLine.
Posted by BobCF 6 years, 9 months ago
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <liming.gao@intel.com>
---
 BaseTools/Source/Python/AutoGen/AutoGen.py        | 110 +++---------
 BaseTools/Source/Python/Common/Expression.py      |   2 +-
 BaseTools/Source/Python/Common/Misc.py            |   2 +-
 BaseTools/Source/Python/GenFds/FfsInfStatement.py |   1 +
 BaseTools/Source/Python/GenFds/GenFds.py          |   4 +-
 BaseTools/Source/Python/Workspace/DscBuildData.py | 210 +++++++++++++++++++++-
 BaseTools/Source/Python/build/build.py            |   2 +-
 7 files changed, 233 insertions(+), 98 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 1cf50e872f..405bfa145a 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -396,100 +396,22 @@ class WorkspaceAutoGen(AutoGen):
 
         # apply SKU and inject PCDs from Flash Definition file
         for Arch in self.ArchList:
             Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
 
-            DecPcds = {}
-            DecPcdsKey = set()
-            PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
-            if GlobalData.BuildOptionPcd:
-                for i, pcd in enumerate(GlobalData.BuildOptionPcd):
-                    if type(pcd) is tuple:
-                        continue
-                    (pcdname, pcdvalue) = pcd.split('=')
-                    if not pcdvalue:
-                        EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
-                    if '.' in pcdname:
-                        (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')
-                        HasTokenSpace = True
-                    else:
-                        TokenCName = pcdname
-                        TokenSpaceGuidCName = ''
-                        HasTokenSpace = False
-                    TokenSpaceGuidCNameList = []
-                    FoundFlag = False
-                    PcdDatumType = ''
-                    NewValue = ''
-                    for package in PGen.PackageList:
-                        Guids = package.Guids
-                        self._GuidDict.update(Guids)
-                    for package in PGen.PackageList:
-                        for key in package.Pcds:
-                            PcdItem = package.Pcds[key]
-                            if HasTokenSpace:
-                                if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
-                                    PcdDatumType = PcdItem.DatumType
-                                    if pcdvalue.startswith('H'):
-                                        try:
-                                            pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
-                                        except BadExpression, Value:
-                                            if Value.result > 1:
-                                                EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
-                                                                (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
-                                        pcdvalue = 'H' + pcdvalue
-                                    NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
-                                    FoundFlag = True
-                            else:
-                                if PcdItem.TokenCName == TokenCName:
-                                    if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
-                                        if len (TokenSpaceGuidCNameList) < 1:
-                                            TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
-                                            PcdDatumType = PcdItem.DatumType
-                                            TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
-                                            if pcdvalue.startswith('H'):
-                                                try:
-                                                    pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
-                                                except BadExpression, Value:
-                                                    EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
-                                                                    (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
-                                                pcdvalue = 'H' + pcdvalue
-                                            NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
-                                            FoundFlag = True
-                                        else:
-                                            EdkLogger.error(
-                                                    'build',
-                                                     AUTOGEN_ERROR,
-                                                    "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
-                                                    )
 
-                    GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, NewValue)
 
-                    if not FoundFlag:
-                        if HasTokenSpace:
-                            EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))
-                        else:
-                            EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName))
 
-                    for BuildData in PGen.BuildDatabase._CACHE_.values():
-                        if BuildData.Arch != Arch:
-                            continue
-                        if BuildData.MetaFile.Ext == '.dec':
-                            continue
-                        for key in BuildData.Pcds:
-                            PcdItem = BuildData.Pcds[key]
-                            if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName):
-                                PcdItem.DefaultValue = NewValue
 
-                    if (TokenCName, TokenSpaceGuidCName) in PcdSet:
-                        PcdSet[(TokenCName, TokenSpaceGuidCName)] = NewValue
 
             SourcePcdDict = {'DynamicEx':[], 'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}
             BinaryPcdDict = {'DynamicEx':[], 'PatchableInModule':[]}
             SourcePcdDict_Keys = SourcePcdDict.keys()
             BinaryPcdDict_Keys = BinaryPcdDict.keys()
 
             # generate the SourcePcdDict and BinaryPcdDict
+            PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
             for BuildData in PGen.BuildDatabase._CACHE_.values():
                 if BuildData.Arch != Arch:
                     continue
                 if BuildData.MetaFile.Ext == '.inf':
                     for key in BuildData.Pcds:
@@ -628,10 +550,12 @@ class WorkspaceAutoGen(AutoGen):
                 if ModuleFile in Platform.Modules:
                     continue
                 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
                 PkgSet.update(ModuleData.Packages)
             Pkgs = list(PkgSet) + list(PGen.PackageList)
+            DecPcds = {}
+            DecPcdsKey = set()
             for Pkg in Pkgs:
                 for Pcd in Pkg.Pcds:
                     DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
                     DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))
 
@@ -1444,19 +1368,29 @@ class PlatformAutoGen(AutoGen):
     #  This interface should be invoked explicitly when platform action is created.
     #
     def CollectPlatformDynamicPcds(self):
         # Override the platform Pcd's value by build option
         if GlobalData.BuildOptionPcd:
-            for key in self.Platform.Pcds:
-                PlatformPcd = self.Platform.Pcds[key]
-                for PcdItem in GlobalData.BuildOptionPcd:
-                    if (PlatformPcd.TokenSpaceGuidCName, PlatformPcd.TokenCName) == (PcdItem[0], PcdItem[1]):
-                        PlatformPcd.DefaultValue = PcdItem[2]
-                        if PlatformPcd.SkuInfoList:
-                            Sku = PlatformPcd.SkuInfoList[PlatformPcd.SkuInfoList.keys()[0]]
-                            Sku.DefaultValue = PcdItem[2]
-                        break
+            for PcdItem in GlobalData.BuildOptionPcd:
+                PlatformPcd = self.Platform.Pcds.get((PcdItem[1],PcdItem[0]))
+                if PlatformPcd:
+                    if PlatformPcd.DatumType in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:
+                        for sku in PlatformPcd.SkuInfoList:
+                            PlatformPcd.SkuInfoList[sku].DefaultValue = PcdItem[2]
+                    else:
+                        PcdDefaultValue = StringToArray(PcdItem[2])
+                        for sku in PlatformPcd.SkuInfoList:
+                            skuinfo = PlatformPcd.SkuInfoList[sku]
+                            if skuinfo.VariableGuid:
+                                skuinfo.HiiDefaultValue = PcdDefaultValue
+                            else:
+                                skuinfo.DefaultValue = PcdDefaultValue
+                        PlatformPcd.DefaultValue = PcdDefaultValue
+                        if PlatformPcd.MaxDatumSize:
+                            PlatformPcd.MaxDatumSize = str(max([int(PlatformPcd.MaxDatumSize),len(PcdDefaultValue.split(","))]))
+                        else:
+                            PlatformPcd.MaxDatumSize = str(len(PcdDefaultValue.split(",")))
 
         for key in self.Platform.Pcds:
             for SinglePcd in GlobalData.MixedPcd:
                 if (self.Platform.Pcds[key].TokenCName, self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
                     for item in GlobalData.MixedPcd[SinglePcd]:
diff --git a/BaseTools/Source/Python/Common/Expression.py b/BaseTools/Source/Python/Common/Expression.py
index 486c537029..b8c48460ff 100644
--- a/BaseTools/Source/Python/Common/Expression.py
+++ b/BaseTools/Source/Python/Common/Expression.py
@@ -789,11 +789,11 @@ class ValueExpressionEx(ValueExpression):
                     raise BadExpression('Type %s PCD Value Size is Larger than 2 byte' % self.PcdType)
                 if self.PcdType == 'UINT32' and Size > 4:
                     raise BadExpression('Type %s PCD Value Size is Larger than 4 byte' % self.PcdType)
                 if self.PcdType == 'UINT64' and Size > 8:
                     raise BadExpression('Type %s PCD Value Size is Larger than 8 byte' % self.PcdType)
-            if self.PcdType in ['VOID*']:
+            else:
                 try:
                     TmpValue = long(PcdValue)
                     TmpList = []
                     if TmpValue.bit_length() == 0:
                         PcdValue = '{0x00}'
diff --git a/BaseTools/Source/Python/Common/Misc.py b/BaseTools/Source/Python/Common/Misc.py
index a8ed718aa5..5d2bc40275 100644
--- a/BaseTools/Source/Python/Common/Misc.py
+++ b/BaseTools/Source/Python/Common/Misc.py
@@ -2346,11 +2346,11 @@ def PackRegistryFormatGuid(Guid):
                 int(Guid[4][-4:-2], 16),
                 int(Guid[4][-2:], 16)
                 )
 
 def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):
-    if PcdDatumType == 'VOID*':
+    if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']:
         if Value.startswith('L'):
             if not Value[1]:
                 EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
             Value = Value[0] + '"' + Value[1:] + '"'
         elif Value.startswith('H'):
diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
index baee543698..b0b242be8d 100644
--- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py
+++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
@@ -235,10 +235,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
 
         self.PatchPcds = []
         InfPcds = Inf.Pcds
         Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
         FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict
+        PlatformPcds = Platform.Pcds
 
         # Workaround here: both build and GenFds tool convert the workspace path to lower case
         # But INF file path in FDF and DSC file may have real case characters.
         # Try to convert the path to lower case to see if PCDs value are override by DSC.
         DscModules = {}
diff --git a/BaseTools/Source/Python/GenFds/GenFds.py b/BaseTools/Source/Python/GenFds/GenFds.py
index 4a5d6f476a..dcba9f24cb 100644
--- a/BaseTools/Source/Python/GenFds/GenFds.py
+++ b/BaseTools/Source/Python/GenFds/GenFds.py
@@ -300,13 +300,11 @@ def main():
 
         GenFdsGlobalVariable.WorkSpace = BuildWorkSpace
         if ArchList != None:
             GenFdsGlobalVariable.ArchList = ArchList
 
-        if Options.OptionPcd:
-            GlobalData.BuildOptionPcd = Options.OptionPcd
-            CheckBuildOptionPcd()
+        # Dsc Build Data will handle Pcd Settings from CommandLine.
 
         """Modify images from build output if the feature of loading driver at fixed address is on."""
         if GenFdsGlobalVariable.FixedLoadAddress:
             GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform)
 
diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py
index 012e16a488..2bdeb1e4f1 100644
--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
@@ -160,11 +160,10 @@ class DscBuildData(PlatformBuildClassObject):
             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.SkuName, self.SkuIds)
-        arraystr = self.SkuIdMgr.DumpSkuIdArrary()
 
     ## XXX[key] = value
     def __setitem__(self, key, value):
         self.__dict__[self._PROPERTY_[key]] = value
 
@@ -449,11 +448,10 @@ class DscBuildData(PlatformBuildClassObject):
         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()
@@ -887,14 +885,168 @@ class DscBuildData(PlatformBuildClassObject):
                     PcdDefaultStoreSet = set([defaultstorename  for defaultstorename in skuobj.DefaultStoreDict])
                     mindefaultstorename = DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
                     skuobj.DefaultStoreDict['STANDARD'] = copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
         return Pcds
 
+    def RecoverCommandLinePcd(self):
+        pcdset = []
+        if GlobalData.BuildOptionPcd:
+            for pcd in GlobalData.BuildOptionPcd:
+                if pcd[2] == "":
+                    pcdset.append((pcd[0],pcd[1],pcd[3]))
+                else:
+                    pcdobj = self._Pcds.get((pcd[1],pcd[0]))
+                    if pcdobj:
+                        pcdset.append((pcd[0],pcd[1], pcdobj.DefaultValue))
+                    else:
+                        pcdset.append((pcd[0],pcd[1],pcd[3]))
+        GlobalData.BuildOptionPcd = pcdset
+    def GetFieldValueFromComm(self,ValueStr,TokenSpaceGuidCName, TokenCName, FieldName):
+        PredictedFieldType = "VOID*"
+        if ValueStr.startswith('L'):
+            if not ValueStr[1]:
+                EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
+            ValueStr = ValueStr[0] + '"' + ValueStr[1:] + '"'
+            PredictedFieldType = "VOID*"
+        elif ValueStr.startswith('H') or ValueStr.startswith('{'):
+            EdkLogger.error("build", FORMAT_INVALID, 'Currently we do not support assign H"{...}" format for Pcd field.', ExtraData="%s.%s.%s from command line" % (TokenSpaceGuidCName, TokenCName, FieldName))
+            ValueStr = ValueStr[1:]
+            PredictedFieldType = "VOID*"
+        elif ValueStr.upper() in ['TRUE', '0X1', '0X01', '1', 'FALSE', '0X0', '0X00', '0']:
+            PredictedFieldType = "BOOLEAN"
+        elif ValueStr.isdigit() or ValueStr.upper().startswith('0X'):
+            PredictedFieldType = TAB_UINT16
+        else:
+            if not ValueStr[0]:
+                EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", H"{...}"')
+            ValueStr = '"' + ValueStr + '"'
+            PredictedFieldType = "VOID*"
+        IsValid, Cause = CheckPcdDatum(PredictedFieldType, ValueStr)
+        if not IsValid:
+            EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s.%s from command line" % (TokenSpaceGuidCName, TokenCName, FieldName))
+        if PredictedFieldType == 'BOOLEAN':
+            ValueStr = ValueStr.upper()
+            if ValueStr == 'TRUE' or ValueStr == '1':
+                ValueStr = '1'
+            elif ValueStr == 'FALSE' or ValueStr == '0':
+                ValueStr = '0'
+        return  ValueStr
+    def __ParsePcdFromCommandLine(self):
+        if GlobalData.BuildOptionPcd:
+            for i, pcd in enumerate(GlobalData.BuildOptionPcd):
+                if type(pcd) is tuple:
+                    continue
+                (pcdname, pcdvalue) = pcd.split('=')
+                if not pcdvalue:
+                    EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for the PCD %s." % (pcdname))
+                if '.' in pcdname:
+                    (Name1, Name2) = pcdname.split('.',1)
+                    if "." in Name2:
+                        (Name3, FieldName) = Name2.split(".",1)
+                        if ((Name3,Name1)) in self.DecPcds:
+                            HasTokenSpace = True
+                            TokenCName = Name3
+                            TokenSpaceGuidCName = Name1
+                        else:
+                            FieldName = Name2
+                            TokenCName = Name1
+                            TokenSpaceGuidCName = ''
+                            HasTokenSpace = False
+                    else:
+                        if ((Name2,Name1)) in self.DecPcds:
+                            HasTokenSpace = True
+                            TokenCName = Name2
+                            TokenSpaceGuidCName = Name1
+                            FieldName =""
+                        else:
+                            FieldName = Name2
+                            TokenCName = Name1
+                            TokenSpaceGuidCName = ''
+                            HasTokenSpace = False
+                else:
+                    FieldName = ""
+                    TokenCName = pcdname
+                    TokenSpaceGuidCName = ''
+                    HasTokenSpace = False
+                TokenSpaceGuidCNameList = []
+                FoundFlag = False
+                PcdDatumType = ''
+                NewValue = ''
+                if not HasTokenSpace:
+                    for key in self.DecPcds:
+                        if TokenCName == key[0]:
+                            if TokenSpaceGuidCName:
+                                EdkLogger.error(
+                                                'build',
+                                                 AUTOGEN_ERROR,
+                                                "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, TokenSpaceGuidCName, key[1])
+                                                )
+                            else:
+                                TokenSpaceGuidCName = key[1]
+                                FoundFlag = True
+                else:
+                    if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
+                        FoundFlag = True
+                if FieldName:
+                    NewValue = self.GetFieldValueFromComm(pcdvalue, TokenSpaceGuidCName, TokenCName, FieldName)
+                    GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1))
+                else:
+                    for key in self.DecPcds:
+                        PcdItem = self.DecPcds[key]
+                        if HasTokenSpace:
+                            if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName):
+                                PcdDatumType = PcdItem.DatumType
+                                if pcdvalue.startswith('H'):
+                                    try:
+                                        pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
+                                    except BadExpression, Value:
+                                        if Value.result > 1:
+                                            EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s",  %s' %
+                                                            (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
+                                    pcdvalue = 'H' + pcdvalue
+                                NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
+                                FoundFlag = True
+                        else:
+                            if PcdItem.TokenCName == TokenCName:
+                                if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList:
+                                    if len (TokenSpaceGuidCNameList) < 1:
+                                        TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
+                                        PcdDatumType = PcdItem.DatumType
+                                        TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName
+                                        if pcdvalue.startswith('H'):
+                                            try:
+                                                pcdvalue = ValueExpressionEx(pcdvalue[1:], PcdDatumType, self._GuidDict)(True)
+                                            except BadExpression, Value:
+                                                EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' %
+                                                                (TokenSpaceGuidCName, TokenCName, pcdvalue, Value))
+                                            pcdvalue = 'H' + pcdvalue
+                                        NewValue = BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName, PcdDatumType, pcdvalue)
+                                        FoundFlag = True
+                                    else:
+                                        EdkLogger.error(
+                                                'build',
+                                                 AUTOGEN_ERROR,
+                                                "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (TokenCName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
+                                                )
+                    GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1))
+                if not FoundFlag:
+                    if HasTokenSpace:
+                        EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))
+                    else:
+                        EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName))
+                for BuildData in self._Bdb._CACHE_.values():
+                    if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext == '.dsc':
+                        continue
+                    for key in BuildData.Pcds:
+                        PcdItem = BuildData.Pcds[key]
+                        if (TokenSpaceGuidCName, TokenCName) == (PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName =="":
+                            PcdItem.DefaultValue = NewValue
     ## Retrieve all PCD settings in platform
     def _GetPcds(self):
         if self._Pcds == None:
             self._Pcds = sdict()
+            self.__ParsePcdFromCommandLine()
             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))
@@ -905,10 +1057,12 @@ class DscBuildData(PlatformBuildClassObject):
 
             self._Pcds = self.CompletePcdValues(self._Pcds)
             self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST, self._Pcds)
             self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
             self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
+            self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)
+            self.RecoverCommandLinePcd()
         return self._Pcds
 
     def _dumpPcdInfo(self,Pcds):
         for pcd in Pcds:
             pcdobj = Pcds[pcd]
@@ -969,11 +1123,59 @@ class DscBuildData(PlatformBuildClassObject):
             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 OverrideByFdfComm(self,StruPcds):
+        StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for item in GlobalData.BuildOptionPcd if len(item) == 5 and (item[1],item[0]) in StruPcds } if GlobalData.BuildOptionPcd else {}
+        GlobalPcds = set([(item[0],item[1]) for item in StructurePcdInCom.keys()])
+        for Pcd in StruPcds.values():
+            if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
+                continue
+            FieldValues = {item[2]:StructurePcdInCom[item] for item in StructurePcdInCom if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) == (item[0],item[1]) and item[2]}
+            for sku in Pcd.SkuOverrideValues:
+                for defaultstore in Pcd.SkuOverrideValues[sku]:
+                    for field in FieldValues:
+                        if field not in Pcd.SkuOverrideValues[sku][defaultstore]:
+                            Pcd.SkuOverrideValues[sku][defaultstore][field] = ["","",""]
+                        Pcd.SkuOverrideValues[sku][defaultstore][field][0] = FieldValues[field][0]
+                        Pcd.SkuOverrideValues[sku][defaultstore][field][1] = FieldValues[field][1][0]
+                        Pcd.SkuOverrideValues[sku][defaultstore][field][2] = FieldValues[field][1][1]
+        return StruPcds
+    def OverrideByFdfCommOverAll(self,AllPcds):
+        def CheckStructureInComm(commpcds):
+            if not commpcds:
+                return False
+            if len(commpcds[0]) == 5:
+                return True
+            return False
 
+        if CheckStructureInComm(GlobalData.BuildOptionPcd):
+            StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for item in GlobalData.BuildOptionPcd } if GlobalData.BuildOptionPcd else {}
+            NoFiledValues = {(item[0],item[1]):StructurePcdInCom[item] for item in StructurePcdInCom if not item[2]}
+        else:
+            NoFiledValues = {(item[0],item[1]):[item[2]] for item in GlobalData.BuildOptionPcd}
+        for Guid,Name in NoFiledValues:
+            if (Name,Guid) in AllPcds:
+                Pcd = AllPcds.get((Name,Guid))
+                Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
+                for sku in Pcd.SkuInfoList:
+                    SkuInfo = Pcd.SkuInfoList[sku]
+                    if SkuInfo.DefaultValue:
+                        SkuInfo.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
+                    else:
+                        SkuInfo.HiiDefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
+                        for defaultstore in SkuInfo.DefaultStoreDict:
+                            SkuInfo.DefaultStoreDict[defaultstore] = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
+            else:
+                PcdInDec = self.DecPcds.get((Name,Guid))
+                if PcdInDec:
+                    if PcdInDec.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
+                                        self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
+                        self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
+                        self.Pcds[Name, Guid].DefaultValue = NoFiledValues[( Guid,Name)][0]
+        return AllPcds
     def UpdateStructuredPcds(self, TypeList, AllPcds):
 
         DynamicPcdType = [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
@@ -1000,11 +1202,11 @@ class DscBuildData(PlatformBuildClassObject):
             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]))
+                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:
@@ -1067,11 +1269,11 @@ class DscBuildData(PlatformBuildClassObject):
                     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])
-
+        S_pcd_set = self.OverrideByFdfComm(S_pcd_set)
         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:
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index e4adee2beb..24f9962c9d 100644
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -770,11 +770,11 @@ class Build():
         self.TargetTxt      = TargetTxtClassObject()
         self.ToolDef        = ToolDefClassObject()
         self.AutoGenTime    = 0
         self.MakeTime       = 0
         self.GenFdsTime     = 0
-        GlobalData.BuildOptionPcd     = BuildOptions.OptionPcd
+        GlobalData.BuildOptionPcd     = BuildOptions.OptionPcd if BuildOptions.OptionPcd else {}
         #Set global flag for build mode
         GlobalData.gIgnoreSource = BuildOptions.IgnoreSources
         GlobalData.gUseHashCache = BuildOptions.UseHashCache
         GlobalData.gBinCacheDest   = BuildOptions.BinCacheDest
         GlobalData.gBinCacheSource = BuildOptions.BinCacheSource
-- 
2.14.3.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
Re: [edk2] [Patch] BaseTools: Structure Pcd in CommandLine.
Posted by Gao, Liming 6 years, 9 months ago
Reviewed-by: Liming Gao <liming.gao@intel.com>

>-----Original Message-----
>From: Feng, Bob C
>Sent: Wednesday, January 31, 2018 4:49 PM
>To: edk2-devel@lists.01.org
>Cc: Feng, Bob C <bob.c.feng@intel.com>; Gao, Liming <liming.gao@intel.com>
>Subject: [Patch] BaseTools: Structure Pcd in CommandLine.
>
>Contributed-under: TianoCore Contribution Agreement 1.1
>Signed-off-by: Bob Feng <bob.c.feng@intel.com>
>Cc: Liming Gao <liming.gao@intel.com>
>---
> BaseTools/Source/Python/AutoGen/AutoGen.py        | 110 +++---------
> BaseTools/Source/Python/Common/Expression.py      |   2 +-
> BaseTools/Source/Python/Common/Misc.py            |   2 +-
> BaseTools/Source/Python/GenFds/FfsInfStatement.py |   1 +
> BaseTools/Source/Python/GenFds/GenFds.py          |   4 +-
> BaseTools/Source/Python/Workspace/DscBuildData.py | 210
>+++++++++++++++++++++-
> BaseTools/Source/Python/build/build.py            |   2 +-
> 7 files changed, 233 insertions(+), 98 deletions(-)
>
>diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py
>b/BaseTools/Source/Python/AutoGen/AutoGen.py
>index 1cf50e872f..405bfa145a 100644
>--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
>+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
>@@ -396,100 +396,22 @@ class WorkspaceAutoGen(AutoGen):
>
>         # apply SKU and inject PCDs from Flash Definition file
>         for Arch in self.ArchList:
>             Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
>
>-            DecPcds = {}
>-            DecPcdsKey = set()
>-            PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
>-            if GlobalData.BuildOptionPcd:
>-                for i, pcd in enumerate(GlobalData.BuildOptionPcd):
>-                    if type(pcd) is tuple:
>-                        continue
>-                    (pcdname, pcdvalue) = pcd.split('=')
>-                    if not pcdvalue:
>-                        EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified
>for the PCD %s." % (pcdname))
>-                    if '.' in pcdname:
>-                        (TokenSpaceGuidCName, TokenCName) = pcdname.split('.')
>-                        HasTokenSpace = True
>-                    else:
>-                        TokenCName = pcdname
>-                        TokenSpaceGuidCName = ''
>-                        HasTokenSpace = False
>-                    TokenSpaceGuidCNameList = []
>-                    FoundFlag = False
>-                    PcdDatumType = ''
>-                    NewValue = ''
>-                    for package in PGen.PackageList:
>-                        Guids = package.Guids
>-                        self._GuidDict.update(Guids)
>-                    for package in PGen.PackageList:
>-                        for key in package.Pcds:
>-                            PcdItem = package.Pcds[key]
>-                            if HasTokenSpace:
>-                                if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName)
>== (TokenCName, TokenSpaceGuidCName):
>-                                    PcdDatumType = PcdItem.DatumType
>-                                    if pcdvalue.startswith('H'):
>-                                        try:
>-                                            pcdvalue = ValueExpressionEx(pcdvalue[1:],
>PcdDatumType, self._GuidDict)(True)
>-                                        except BadExpression, Value:
>-                                            if Value.result > 1:
>-                                                EdkLogger.error('Parser', FORMAT_INVALID, 'PCD
>[%s.%s] Value "%s",  %s' %
>-                                                                (TokenSpaceGuidCName, TokenCName,
>pcdvalue, Value))
>-                                        pcdvalue = 'H' + pcdvalue
>-                                    NewValue =
>BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName,
>PcdDatumType, pcdvalue)
>-                                    FoundFlag = True
>-                            else:
>-                                if PcdItem.TokenCName == TokenCName:
>-                                    if not PcdItem.TokenSpaceGuidCName in
>TokenSpaceGuidCNameList:
>-                                        if len (TokenSpaceGuidCNameList) < 1:
>-
>TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
>-                                            PcdDatumType = PcdItem.DatumType
>-                                            TokenSpaceGuidCName =
>PcdItem.TokenSpaceGuidCName
>-                                            if pcdvalue.startswith('H'):
>-                                                try:
>-                                                    pcdvalue = ValueExpressionEx(pcdvalue[1:],
>PcdDatumType, self._GuidDict)(True)
>-                                                except BadExpression, Value:
>-                                                    EdkLogger.error('Parser', FORMAT_INVALID, 'PCD
>[%s.%s] Value "%s", %s' %
>-                                                                    (TokenSpaceGuidCName, TokenCName,
>pcdvalue, Value))
>-                                                pcdvalue = 'H' + pcdvalue
>-                                            NewValue =
>BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName,
>PcdDatumType, pcdvalue)
>-                                            FoundFlag = True
>-                                        else:
>-                                            EdkLogger.error(
>-                                                    'build',
>-                                                     AUTOGEN_ERROR,
>-                                                    "The Pcd %s is found under multiple different
>TokenSpaceGuid: %s and %s." % (TokenCName,
>PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
>-                                                    )
>
>-                    GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName,
>TokenCName, NewValue)
>
>-                    if not FoundFlag:
>-                        if HasTokenSpace:
>-                            EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is
>not found in the DEC file." % (TokenSpaceGuidCName, TokenCName))
>-                        else:
>-                            EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not
>found in the DEC file." % (TokenCName))
>
>-                    for BuildData in PGen.BuildDatabase._CACHE_.values():
>-                        if BuildData.Arch != Arch:
>-                            continue
>-                        if BuildData.MetaFile.Ext == '.dec':
>-                            continue
>-                        for key in BuildData.Pcds:
>-                            PcdItem = BuildData.Pcds[key]
>-                            if (TokenSpaceGuidCName, TokenCName) ==
>(PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName):
>-                                PcdItem.DefaultValue = NewValue
>
>-                    if (TokenCName, TokenSpaceGuidCName) in PcdSet:
>-                        PcdSet[(TokenCName, TokenSpaceGuidCName)] = NewValue
>
>             SourcePcdDict = {'DynamicEx':[],
>'PatchableInModule':[],'Dynamic':[],'FixedAtBuild':[]}
>             BinaryPcdDict = {'DynamicEx':[], 'PatchableInModule':[]}
>             SourcePcdDict_Keys = SourcePcdDict.keys()
>             BinaryPcdDict_Keys = BinaryPcdDict.keys()
>
>             # generate the SourcePcdDict and BinaryPcdDict
>+            PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
>             for BuildData in PGen.BuildDatabase._CACHE_.values():
>                 if BuildData.Arch != Arch:
>                     continue
>                 if BuildData.MetaFile.Ext == '.inf':
>                     for key in BuildData.Pcds:
>@@ -628,10 +550,12 @@ class WorkspaceAutoGen(AutoGen):
>                 if ModuleFile in Platform.Modules:
>                     continue
>                 ModuleData = self.BuildDatabase[ModuleFile, Arch, Target, Toolchain]
>                 PkgSet.update(ModuleData.Packages)
>             Pkgs = list(PkgSet) + list(PGen.PackageList)
>+            DecPcds = {}
>+            DecPcdsKey = set()
>             for Pkg in Pkgs:
>                 for Pcd in Pkg.Pcds:
>                     DecPcds[Pcd[0], Pcd[1]] = Pkg.Pcds[Pcd]
>                     DecPcdsKey.add((Pcd[0], Pcd[1], Pcd[2]))
>
>@@ -1444,19 +1368,29 @@ class PlatformAutoGen(AutoGen):
>     #  This interface should be invoked explicitly when platform action is
>created.
>     #
>     def CollectPlatformDynamicPcds(self):
>         # Override the platform Pcd's value by build option
>         if GlobalData.BuildOptionPcd:
>-            for key in self.Platform.Pcds:
>-                PlatformPcd = self.Platform.Pcds[key]
>-                for PcdItem in GlobalData.BuildOptionPcd:
>-                    if (PlatformPcd.TokenSpaceGuidCName,
>PlatformPcd.TokenCName) == (PcdItem[0], PcdItem[1]):
>-                        PlatformPcd.DefaultValue = PcdItem[2]
>-                        if PlatformPcd.SkuInfoList:
>-                            Sku =
>PlatformPcd.SkuInfoList[PlatformPcd.SkuInfoList.keys()[0]]
>-                            Sku.DefaultValue = PcdItem[2]
>-                        break
>+            for PcdItem in GlobalData.BuildOptionPcd:
>+                PlatformPcd = self.Platform.Pcds.get((PcdItem[1],PcdItem[0]))
>+                if PlatformPcd:
>+                    if PlatformPcd.DatumType in [TAB_UINT8, TAB_UINT16,
>TAB_UINT32, TAB_UINT64,'BOOLEAN']:
>+                        for sku in PlatformPcd.SkuInfoList:
>+                            PlatformPcd.SkuInfoList[sku].DefaultValue = PcdItem[2]
>+                    else:
>+                        PcdDefaultValue = StringToArray(PcdItem[2])
>+                        for sku in PlatformPcd.SkuInfoList:
>+                            skuinfo = PlatformPcd.SkuInfoList[sku]
>+                            if skuinfo.VariableGuid:
>+                                skuinfo.HiiDefaultValue = PcdDefaultValue
>+                            else:
>+                                skuinfo.DefaultValue = PcdDefaultValue
>+                        PlatformPcd.DefaultValue = PcdDefaultValue
>+                        if PlatformPcd.MaxDatumSize:
>+                            PlatformPcd.MaxDatumSize =
>str(max([int(PlatformPcd.MaxDatumSize),len(PcdDefaultValue.split(","))]))
>+                        else:
>+                            PlatformPcd.MaxDatumSize =
>str(len(PcdDefaultValue.split(",")))
>
>         for key in self.Platform.Pcds:
>             for SinglePcd in GlobalData.MixedPcd:
>                 if (self.Platform.Pcds[key].TokenCName,
>self.Platform.Pcds[key].TokenSpaceGuidCName) == SinglePcd:
>                     for item in GlobalData.MixedPcd[SinglePcd]:
>diff --git a/BaseTools/Source/Python/Common/Expression.py
>b/BaseTools/Source/Python/Common/Expression.py
>index 486c537029..b8c48460ff 100644
>--- a/BaseTools/Source/Python/Common/Expression.py
>+++ b/BaseTools/Source/Python/Common/Expression.py
>@@ -789,11 +789,11 @@ class ValueExpressionEx(ValueExpression):
>                     raise BadExpression('Type %s PCD Value Size is Larger than 2 byte' %
>self.PcdType)
>                 if self.PcdType == 'UINT32' and Size > 4:
>                     raise BadExpression('Type %s PCD Value Size is Larger than 4 byte' %
>self.PcdType)
>                 if self.PcdType == 'UINT64' and Size > 8:
>                     raise BadExpression('Type %s PCD Value Size is Larger than 8 byte' %
>self.PcdType)
>-            if self.PcdType in ['VOID*']:
>+            else:
>                 try:
>                     TmpValue = long(PcdValue)
>                     TmpList = []
>                     if TmpValue.bit_length() == 0:
>                         PcdValue = '{0x00}'
>diff --git a/BaseTools/Source/Python/Common/Misc.py
>b/BaseTools/Source/Python/Common/Misc.py
>index a8ed718aa5..5d2bc40275 100644
>--- a/BaseTools/Source/Python/Common/Misc.py
>+++ b/BaseTools/Source/Python/Common/Misc.py
>@@ -2346,11 +2346,11 @@ def PackRegistryFormatGuid(Guid):
>                 int(Guid[4][-4:-2], 16),
>                 int(Guid[4][-2:], 16)
>                 )
>
> def BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName,
>PcdDatumType, Value):
>-    if PcdDatumType == 'VOID*':
>+    if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32,
>TAB_UINT64,'BOOLEAN']:
>         if Value.startswith('L'):
>             if not Value[1]:
>                 EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD,
>when specify the Value in the command line, please use the following format:
>"string", L"string", H"{...}"')
>             Value = Value[0] + '"' + Value[1:] + '"'
>         elif Value.startswith('H'):
>diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py
>b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
>index baee543698..b0b242be8d 100644
>--- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py
>+++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py
>@@ -235,10 +235,11 @@ class FfsInfStatement(FfsInfStatementClassObject):
>
>         self.PatchPcds = []
>         InfPcds = Inf.Pcds
>         Platform =
>GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActiveP
>latform, self.CurrentArch, GenFdsGlobalVariable.TargetName,
>GenFdsGlobalVariable.ToolChainTag]
>         FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict
>+        PlatformPcds = Platform.Pcds
>
>         # Workaround here: both build and GenFds tool convert the workspace
>path to lower case
>         # But INF file path in FDF and DSC file may have real case characters.
>         # Try to convert the path to lower case to see if PCDs value are override
>by DSC.
>         DscModules = {}
>diff --git a/BaseTools/Source/Python/GenFds/GenFds.py
>b/BaseTools/Source/Python/GenFds/GenFds.py
>index 4a5d6f476a..dcba9f24cb 100644
>--- a/BaseTools/Source/Python/GenFds/GenFds.py
>+++ b/BaseTools/Source/Python/GenFds/GenFds.py
>@@ -300,13 +300,11 @@ def main():
>
>         GenFdsGlobalVariable.WorkSpace = BuildWorkSpace
>         if ArchList != None:
>             GenFdsGlobalVariable.ArchList = ArchList
>
>-        if Options.OptionPcd:
>-            GlobalData.BuildOptionPcd = Options.OptionPcd
>-            CheckBuildOptionPcd()
>+        # Dsc Build Data will handle Pcd Settings from CommandLine.
>
>         """Modify images from build output if the feature of loading driver at
>fixed address is on."""
>         if GenFdsGlobalVariable.FixedLoadAddress:
>             GenFds.PreprocessImage(BuildWorkSpace,
>GenFdsGlobalVariable.ActivePlatform)
>
>diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py
>b/BaseTools/Source/Python/Workspace/DscBuildData.py
>index 012e16a488..2bdeb1e4f1 100644
>--- a/BaseTools/Source/Python/Workspace/DscBuildData.py
>+++ b/BaseTools/Source/Python/Workspace/DscBuildData.py
>@@ -160,11 +160,10 @@ class DscBuildData(PlatformBuildClassObject):
>             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.SkuName, self.SkuIds)
>-        arraystr = self.SkuIdMgr.DumpSkuIdArrary()
>
>     ## XXX[key] = value
>     def __setitem__(self, key, value):
>         self.__dict__[self._PROPERTY_[key]] = value
>
>@@ -449,11 +448,10 @@ class DscBuildData(PlatformBuildClassObject):
>         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()
>@@ -887,14 +885,168 @@ class DscBuildData(PlatformBuildClassObject):
>                     PcdDefaultStoreSet = set([defaultstorename  for defaultstorename
>in skuobj.DefaultStoreDict])
>                     mindefaultstorename =
>DefaultStoreMgr.GetMin(PcdDefaultStoreSet)
>                     skuobj.DefaultStoreDict['STANDARD'] =
>copy.deepcopy(skuobj.DefaultStoreDict[mindefaultstorename])
>         return Pcds
>
>+    def RecoverCommandLinePcd(self):
>+        pcdset = []
>+        if GlobalData.BuildOptionPcd:
>+            for pcd in GlobalData.BuildOptionPcd:
>+                if pcd[2] == "":
>+                    pcdset.append((pcd[0],pcd[1],pcd[3]))
>+                else:
>+                    pcdobj = self._Pcds.get((pcd[1],pcd[0]))
>+                    if pcdobj:
>+                        pcdset.append((pcd[0],pcd[1], pcdobj.DefaultValue))
>+                    else:
>+                        pcdset.append((pcd[0],pcd[1],pcd[3]))
>+        GlobalData.BuildOptionPcd = pcdset
>+    def GetFieldValueFromComm(self,ValueStr,TokenSpaceGuidCName,
>TokenCName, FieldName):
>+        PredictedFieldType = "VOID*"
>+        if ValueStr.startswith('L'):
>+            if not ValueStr[1]:
>+                EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD,
>when specify the Value in the command line, please use the following format:
>"string", L"string", H"{...}"')
>+            ValueStr = ValueStr[0] + '"' + ValueStr[1:] + '"'
>+            PredictedFieldType = "VOID*"
>+        elif ValueStr.startswith('H') or ValueStr.startswith('{'):
>+            EdkLogger.error("build", FORMAT_INVALID, 'Currently we do not
>support assign H"{...}" format for Pcd field.', ExtraData="%s.%s.%s from
>command line" % (TokenSpaceGuidCName, TokenCName, FieldName))
>+            ValueStr = ValueStr[1:]
>+            PredictedFieldType = "VOID*"
>+        elif ValueStr.upper() in ['TRUE', '0X1', '0X01', '1', 'FALSE', '0X0', '0X00', '0']:
>+            PredictedFieldType = "BOOLEAN"
>+        elif ValueStr.isdigit() or ValueStr.upper().startswith('0X'):
>+            PredictedFieldType = TAB_UINT16
>+        else:
>+            if not ValueStr[0]:
>+                EdkLogger.error("build", FORMAT_INVALID, 'For Void* type PCD,
>when specify the Value in the command line, please use the following format:
>"string", L"string", H"{...}"')
>+            ValueStr = '"' + ValueStr + '"'
>+            PredictedFieldType = "VOID*"
>+        IsValid, Cause = CheckPcdDatum(PredictedFieldType, ValueStr)
>+        if not IsValid:
>+            EdkLogger.error("build", FORMAT_INVALID, Cause,
>ExtraData="%s.%s.%s from command line" % (TokenSpaceGuidCName,
>TokenCName, FieldName))
>+        if PredictedFieldType == 'BOOLEAN':
>+            ValueStr = ValueStr.upper()
>+            if ValueStr == 'TRUE' or ValueStr == '1':
>+                ValueStr = '1'
>+            elif ValueStr == 'FALSE' or ValueStr == '0':
>+                ValueStr = '0'
>+        return  ValueStr
>+    def __ParsePcdFromCommandLine(self):
>+        if GlobalData.BuildOptionPcd:
>+            for i, pcd in enumerate(GlobalData.BuildOptionPcd):
>+                if type(pcd) is tuple:
>+                    continue
>+                (pcdname, pcdvalue) = pcd.split('=')
>+                if not pcdvalue:
>+                    EdkLogger.error('build', AUTOGEN_ERROR, "No Value specified for
>the PCD %s." % (pcdname))
>+                if '.' in pcdname:
>+                    (Name1, Name2) = pcdname.split('.',1)
>+                    if "." in Name2:
>+                        (Name3, FieldName) = Name2.split(".",1)
>+                        if ((Name3,Name1)) in self.DecPcds:
>+                            HasTokenSpace = True
>+                            TokenCName = Name3
>+                            TokenSpaceGuidCName = Name1
>+                        else:
>+                            FieldName = Name2
>+                            TokenCName = Name1
>+                            TokenSpaceGuidCName = ''
>+                            HasTokenSpace = False
>+                    else:
>+                        if ((Name2,Name1)) in self.DecPcds:
>+                            HasTokenSpace = True
>+                            TokenCName = Name2
>+                            TokenSpaceGuidCName = Name1
>+                            FieldName =""
>+                        else:
>+                            FieldName = Name2
>+                            TokenCName = Name1
>+                            TokenSpaceGuidCName = ''
>+                            HasTokenSpace = False
>+                else:
>+                    FieldName = ""
>+                    TokenCName = pcdname
>+                    TokenSpaceGuidCName = ''
>+                    HasTokenSpace = False
>+                TokenSpaceGuidCNameList = []
>+                FoundFlag = False
>+                PcdDatumType = ''
>+                NewValue = ''
>+                if not HasTokenSpace:
>+                    for key in self.DecPcds:
>+                        if TokenCName == key[0]:
>+                            if TokenSpaceGuidCName:
>+                                EdkLogger.error(
>+                                                'build',
>+                                                 AUTOGEN_ERROR,
>+                                                "The Pcd %s is found under multiple different
>TokenSpaceGuid: %s and %s." % (TokenCName, TokenSpaceGuidCName,
>key[1])
>+                                                )
>+                            else:
>+                                TokenSpaceGuidCName = key[1]
>+                                FoundFlag = True
>+                else:
>+                    if (TokenCName, TokenSpaceGuidCName) in self.DecPcds:
>+                        FoundFlag = True
>+                if FieldName:
>+                    NewValue = self.GetFieldValueFromComm(pcdvalue,
>TokenSpaceGuidCName, TokenCName, FieldName)
>+                    GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName,
>TokenCName, FieldName,NewValue,("build command options",1))
>+                else:
>+                    for key in self.DecPcds:
>+                        PcdItem = self.DecPcds[key]
>+                        if HasTokenSpace:
>+                            if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName)
>== (TokenCName, TokenSpaceGuidCName):
>+                                PcdDatumType = PcdItem.DatumType
>+                                if pcdvalue.startswith('H'):
>+                                    try:
>+                                        pcdvalue = ValueExpressionEx(pcdvalue[1:],
>PcdDatumType, self._GuidDict)(True)
>+                                    except BadExpression, Value:
>+                                        if Value.result > 1:
>+                                            EdkLogger.error('Parser', FORMAT_INVALID, 'PCD
>[%s.%s] Value "%s",  %s' %
>+                                                            (TokenSpaceGuidCName, TokenCName,
>pcdvalue, Value))
>+                                    pcdvalue = 'H' + pcdvalue
>+                                NewValue =
>BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName,
>PcdDatumType, pcdvalue)
>+                                FoundFlag = True
>+                        else:
>+                            if PcdItem.TokenCName == TokenCName:
>+                                if not PcdItem.TokenSpaceGuidCName in
>TokenSpaceGuidCNameList:
>+                                    if len (TokenSpaceGuidCNameList) < 1:
>+
>TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName)
>+                                        PcdDatumType = PcdItem.DatumType
>+                                        TokenSpaceGuidCName =
>PcdItem.TokenSpaceGuidCName
>+                                        if pcdvalue.startswith('H'):
>+                                            try:
>+                                                pcdvalue = ValueExpressionEx(pcdvalue[1:],
>PcdDatumType, self._GuidDict)(True)
>+                                            except BadExpression, Value:
>+                                                EdkLogger.error('Parser', FORMAT_INVALID, 'PCD
>[%s.%s] Value "%s", %s' %
>+                                                                (TokenSpaceGuidCName, TokenCName,
>pcdvalue, Value))
>+                                            pcdvalue = 'H' + pcdvalue
>+                                        NewValue =
>BuildOptionPcdValueFormat(TokenSpaceGuidCName, TokenCName,
>PcdDatumType, pcdvalue)
>+                                        FoundFlag = True
>+                                    else:
>+                                        EdkLogger.error(
>+                                                'build',
>+                                                 AUTOGEN_ERROR,
>+                                                "The Pcd %s is found under multiple different
>TokenSpaceGuid: %s and %s." % (TokenCName,
>PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0])
>+                                                )
>+                    GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName,
>TokenCName, FieldName,NewValue,("build command options",1))
>+                if not FoundFlag:
>+                    if HasTokenSpace:
>+                        EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not
>found in the DEC file." % (TokenSpaceGuidCName, TokenCName))
>+                    else:
>+                        EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not
>found in the DEC file." % (TokenCName))
>+                for BuildData in self._Bdb._CACHE_.values():
>+                    if BuildData.MetaFile.Ext == '.dec' or BuildData.MetaFile.Ext ==
>'.dsc':
>+                        continue
>+                    for key in BuildData.Pcds:
>+                        PcdItem = BuildData.Pcds[key]
>+                        if (TokenSpaceGuidCName, TokenCName) ==
>(PcdItem.TokenSpaceGuidCName, PcdItem.TokenCName) and FieldName
>=="":
>+                            PcdItem.DefaultValue = NewValue
>     ## Retrieve all PCD settings in platform
>     def _GetPcds(self):
>         if self._Pcds == None:
>             self._Pcds = sdict()
>+            self.__ParsePcdFromCommandLine()
>             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))
>@@ -905,10 +1057,12 @@ class DscBuildData(PlatformBuildClassObject):
>
>             self._Pcds = self.CompletePcdValues(self._Pcds)
>             self._Pcds = self.UpdateStructuredPcds(MODEL_PCD_TYPE_LIST,
>self._Pcds)
>             self._Pcds = self.CompleteHiiPcdsDefaultStores(self._Pcds)
>             self._Pcds = self._FilterPcdBySkuUsage(self._Pcds)
>+            self._Pcds = self.OverrideByFdfCommOverAll(self._Pcds)
>+            self.RecoverCommandLinePcd()
>         return self._Pcds
>
>     def _dumpPcdInfo(self,Pcds):
>         for pcd in Pcds:
>             pcdobj = Pcds[pcd]
>@@ -969,11 +1123,59 @@ class DscBuildData(PlatformBuildClassObject):
>             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 OverrideByFdfComm(self,StruPcds):
>+        StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for
>item in GlobalData.BuildOptionPcd if len(item) == 5 and (item[1],item[0]) in
>StruPcds } if GlobalData.BuildOptionPcd else {}
>+        GlobalPcds = set([(item[0],item[1]) for item in
>StructurePcdInCom.keys()])
>+        for Pcd in StruPcds.values():
>+            if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) not in GlobalPcds:
>+                continue
>+            FieldValues = {item[2]:StructurePcdInCom[item] for item in
>StructurePcdInCom if (Pcd.TokenSpaceGuidCName,Pcd.TokenCName) ==
>(item[0],item[1]) and item[2]}
>+            for sku in Pcd.SkuOverrideValues:
>+                for defaultstore in Pcd.SkuOverrideValues[sku]:
>+                    for field in FieldValues:
>+                        if field not in Pcd.SkuOverrideValues[sku][defaultstore]:
>+                            Pcd.SkuOverrideValues[sku][defaultstore][field] = ["","",""]
>+                        Pcd.SkuOverrideValues[sku][defaultstore][field][0] =
>FieldValues[field][0]
>+                        Pcd.SkuOverrideValues[sku][defaultstore][field][1] =
>FieldValues[field][1][0]
>+                        Pcd.SkuOverrideValues[sku][defaultstore][field][2] =
>FieldValues[field][1][1]
>+        return StruPcds
>+    def OverrideByFdfCommOverAll(self,AllPcds):
>+        def CheckStructureInComm(commpcds):
>+            if not commpcds:
>+                return False
>+            if len(commpcds[0]) == 5:
>+                return True
>+            return False
>
>+        if CheckStructureInComm(GlobalData.BuildOptionPcd):
>+            StructurePcdInCom = {(item[0],item[1],item[2] ):(item[3],item[4]) for
>item in GlobalData.BuildOptionPcd } if GlobalData.BuildOptionPcd else {}
>+            NoFiledValues = {(item[0],item[1]):StructurePcdInCom[item] for item
>in StructurePcdInCom if not item[2]}
>+        else:
>+            NoFiledValues = {(item[0],item[1]):[item[2]] for item in
>GlobalData.BuildOptionPcd}
>+        for Guid,Name in NoFiledValues:
>+            if (Name,Guid) in AllPcds:
>+                Pcd = AllPcds.get((Name,Guid))
>+                Pcd.DefaultValue =
>NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
>+                for sku in Pcd.SkuInfoList:
>+                    SkuInfo = Pcd.SkuInfoList[sku]
>+                    if SkuInfo.DefaultValue:
>+                        SkuInfo.DefaultValue =
>NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
>+                    else:
>+                        SkuInfo.HiiDefaultValue =
>NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
>+                        for defaultstore in SkuInfo.DefaultStoreDict:
>+                            SkuInfo.DefaultStoreDict[defaultstore] =
>NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0]
>+            else:
>+                PcdInDec = self.DecPcds.get((Name,Guid))
>+                if PcdInDec:
>+                    if PcdInDec.Type in
>[self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD],
>+
>self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]:
>+                        self.Pcds[Name, Guid] = copy.deepcopy(PcdInDec)
>+                        self.Pcds[Name, Guid].DefaultValue =
>NoFiledValues[( Guid,Name)][0]
>+        return AllPcds
>     def UpdateStructuredPcds(self, TypeList, AllPcds):
>
>         DynamicPcdType =
>[self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_DEFAULT],
>                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII],
>                         self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_VPD],
>@@ -1000,11 +1202,11 @@ class DscBuildData(PlatformBuildClassObject):
>             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]))
>+
>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:
>@@ -1067,11 +1269,11 @@ class DscBuildData(PlatformBuildClassObject):
>                     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][mindefaultstorenam
>e])
>-
>+        S_pcd_set = self.OverrideByFdfComm(S_pcd_set)
>         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:
>diff --git a/BaseTools/Source/Python/build/build.py
>b/BaseTools/Source/Python/build/build.py
>index e4adee2beb..24f9962c9d 100644
>--- a/BaseTools/Source/Python/build/build.py
>+++ b/BaseTools/Source/Python/build/build.py
>@@ -770,11 +770,11 @@ class Build():
>         self.TargetTxt      = TargetTxtClassObject()
>         self.ToolDef        = ToolDefClassObject()
>         self.AutoGenTime    = 0
>         self.MakeTime       = 0
>         self.GenFdsTime     = 0
>-        GlobalData.BuildOptionPcd     = BuildOptions.OptionPcd
>+        GlobalData.BuildOptionPcd     = BuildOptions.OptionPcd if
>BuildOptions.OptionPcd else {}
>         #Set global flag for build mode
>         GlobalData.gIgnoreSource = BuildOptions.IgnoreSources
>         GlobalData.gUseHashCache = BuildOptions.UseHashCache
>         GlobalData.gBinCacheDest   = BuildOptions.BinCacheDest
>         GlobalData.gBinCacheSource = BuildOptions.BinCacheSource
>--
>2.14.3.windows.1

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel