public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [Patch] BaseTools: Structure Pcd in CommandLine.
@ 2018-01-31  8:49 BobCF
  2018-02-01  1:20 ` Gao, Liming
  0 siblings, 1 reply; 3+ messages in thread
From: BobCF @ 2018-01-31  8:49 UTC (permalink / raw)
  To: edk2-devel; +Cc: Bob Feng, Liming Gao

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



^ permalink raw reply related	[flat|nested] 3+ messages in thread
* [Patch] BaseTools: Structure Pcd in CommandLine.
@ 2018-01-29  5:57 BobCF
  0 siblings, 0 replies; 3+ messages in thread
From: BobCF @ 2018-01-29  5:57 UTC (permalink / raw)
  To: edk2-devel; +Cc: Bob Feng, Liming Gao

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 +++++++++++++++++++++-
 6 files changed, 232 insertions(+), 97 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index ab178c9a4a..0a253ff3bc 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]))
 
@@ -1443,19 +1367,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 55fa06d414..e2fe85730a 100644
--- a/BaseTools/Source/Python/Common/Expression.py
+++ b/BaseTools/Source/Python/Common/Expression.py
@@ -783,11 +783,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 f30d3f7e73..256fdd6875 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()
@@ -888,14 +886,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))
@@ -906,10 +1058,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]
@@ -970,11 +1124,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],
@@ -1001,11 +1203,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:
@@ -1068,11 +1270,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:
-- 
2.14.3.windows.1



^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2018-02-01  1:15 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-01-31  8:49 [Patch] BaseTools: Structure Pcd in CommandLine BobCF
2018-02-01  1:20 ` Gao, Liming
  -- strict thread matches above, loose matches on Subject: below --
2018-01-29  5:57 BobCF

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox