X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FWorkspace%2FDscBuildData.py;h=517385a32262cf15b99f6ff7cb20bfa9b2bf28f1;hb=34d808add3dc23aaa37e1c9edb2fcc2b50118367;hp=9d787702c2e6624414234a1c55278d6e96152bb4;hpb=1667eec6990fae902981504887546f5a4913fde0;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/Workspace/DscBuildData.py b/BaseTools/Source/Python/Workspace/DscBuildData.py index 9d787702c2..517385a322 100644 --- a/BaseTools/Source/Python/Workspace/DscBuildData.py +++ b/BaseTools/Source/Python/Workspace/DscBuildData.py @@ -21,7 +21,7 @@ from Common.String import * from Common.DataType import * from Common.Misc import * from types import * - +from Common.Expression import * from CommonDataClass.CommonClass import SkuInfoClass from Common.TargetTxtClassObject import * from Common.ToolDefClassObject import * @@ -95,6 +95,67 @@ MAKEROOT ?= $(EDK_TOOLS_PATH)/Source/C LIBS = -lCommon ''' +## Regular expression for finding header file inclusions +from AutoGen.GenMake import gIncludePattern + +## Find dependencies for one source file +# +# By searching recursively "#include" directive in file, find out all the +# files needed by given source file. The dependecies will be only searched +# in given search path list. +# +# @param SearchPathList The list of search path +# +# @retval list The list of files the given source file depends on +# +def GetDependencyList(FileStack,SearchPathList): + DepDb = dict() + DependencySet = set(FileStack) + while len(FileStack) > 0: + F = FileStack.pop() + FullPathDependList = [] + CurrentFileDependencyList = [] + if F in DepDb: + CurrentFileDependencyList = DepDb[F] + else: + try: + Fd = open(F, 'r') + FileContent = Fd.read() + except BaseException, X: + EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=F + "\n\t" + str(X)) + finally: + if "Fd" in dir(locals()): + Fd.close() + + if len(FileContent) == 0: + continue + + if FileContent[0] == 0xff or FileContent[0] == 0xfe: + FileContent = unicode(FileContent, "utf-16") + IncludedFileList = gIncludePattern.findall(FileContent) + + for Inc in IncludedFileList: + Inc = Inc.strip() + Inc = os.path.normpath(Inc) + CurrentFileDependencyList.append(Inc) + DepDb[F] = CurrentFileDependencyList + + CurrentFilePath = os.path.dirname(F) + PathList = [CurrentFilePath] + SearchPathList + for Inc in CurrentFileDependencyList: + for SearchPath in PathList: + FilePath = os.path.join(SearchPath, Inc) + if not os.path.exists(FilePath): + continue + if FilePath not in DependencySet: + FileStack.append(FilePath) + FullPathDependList.append(FilePath) + break + DependencySet.update(FullPathDependList) + DependencyList = list(DependencySet) # remove duplicate ones + + return DependencyList + class DscBuildData(PlatformBuildClassObject): # dict used to convert PCD type in database to string used by build tool _PCD_TYPE_STRING_ = { @@ -893,48 +954,18 @@ class DscBuildData(PlatformBuildClassObject): 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: - if (pcd[1],pcd[0]) not in self._Pcds: - pcdvalue = pcd[3] if len(pcd) == 4 else pcd[2] - pcdset.append((pcd[0],pcd[1],pcdvalue)) - #else: - # remove the settings from command line since it has been handled. - 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 UpdateCommandLineValue(pcd): + if pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_FIXED_AT_BUILD], + self._PCD_TYPE_STRING_[MODEL_PCD_PATCHABLE_IN_MODULE]]: + pcd.PcdValueFromComm = pcd.DefaultValue + elif pcd.Type in [self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_HII], self._PCD_TYPE_STRING_[MODEL_PCD_DYNAMIC_EX_HII]]: + pcd.PcdValueFromComm = pcd.SkuInfoList.get("DEFAULT").HiiDefaultValue + else: + pcd.PcdValueFromComm = pcd.SkuInfoList.get("DEFAULT").DefaultValue + for pcd in self._Pcds: + if isinstance(self._Pcds[pcd],StructurePcd) and (self._Pcds[pcd].PcdValueFromComm or self._Pcds[pcd].PcdFieldValueFromComm): + UpdateCommandLineValue(self._Pcds[pcd]) + def __ParsePcdFromCommandLine(self): if GlobalData.BuildOptionPcd: for i, pcd in enumerate(GlobalData.BuildOptionPcd): @@ -975,148 +1006,119 @@ class DscBuildData(PlatformBuildClassObject): TokenSpaceGuidCNameList = [] FoundFlag = False PcdDatumType = '' - NewValue = '' + DisplayName = TokenCName + if FieldName: + DisplayName = TokenCName + '.' + FieldName 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 + PcdItem = self.DecPcds[key] + if TokenCName == PcdItem.TokenCName: + if not PcdItem.TokenSpaceGuidCName in TokenSpaceGuidCNameList: + if len (TokenSpaceGuidCNameList) < 1: + TokenSpaceGuidCNameList.append(PcdItem.TokenSpaceGuidCName) + TokenSpaceGuidCName = PcdItem.TokenSpaceGuidCName + PcdDatumType = PcdItem.DatumType + FoundFlag = True + else: + EdkLogger.error( + 'build', + AUTOGEN_ERROR, + "The Pcd %s is found under multiple different TokenSpaceGuid: %s and %s." % (DisplayName, PcdItem.TokenSpaceGuidCName, TokenSpaceGuidCNameList[0]) + ) else: if (TokenCName, TokenSpaceGuidCName) in self.DecPcds: + PcdDatumType = self.DecPcds[(TokenCName, TokenSpaceGuidCName)].DatumType FoundFlag = True - if FieldName: - NewValue = self.GetFieldValueFromComm(pcdvalue, TokenSpaceGuidCName, TokenCName, FieldName) - GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName,NewValue,("build command options",1)) - else: - # Replace \' to ', \\\' to \' - pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'") - 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: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']: - pcdvalue = 'H' + pcdvalue - elif pcdvalue.startswith("L'"): - try: - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True) - except BadExpression, Value: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']: - pcdvalue = 'H' + pcdvalue - elif pcdvalue.startswith("'"): - try: - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True) - except BadExpression, Value: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']: - pcdvalue = 'H' + pcdvalue - elif pcdvalue.startswith('L'): - pcdvalue = 'L"' + pcdvalue[1:] + '"' - try: - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True) - except BadExpression, Value: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - else: - try: - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True) - except BadExpression, Value: - try: - pcdvalue = '"' + pcdvalue + '"' - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True) - except BadExpression, Value: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - 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)) - if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64,'BOOLEAN']: - pcdvalue = 'H' + pcdvalue - elif pcdvalue.startswith("L'"): - try: - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)( - True) - except BadExpression, Value: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']: - pcdvalue = 'H' + pcdvalue - elif pcdvalue.startswith("'"): - try: - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)( - True) - except BadExpression, Value: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - if PcdDatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, 'BOOLEAN']: - pcdvalue = 'H' + pcdvalue - elif pcdvalue.startswith('L'): - pcdvalue = 'L"' + pcdvalue[1:] + '"' - try: - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)( - True) - except BadExpression, Value: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - else: - try: - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True) - except BadExpression, Value: - try: - pcdvalue = '"' + pcdvalue + '"' - pcdvalue = ValueExpressionEx(pcdvalue, PcdDatumType, self._GuidDict)(True) - except BadExpression, Value: - EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % - (TokenSpaceGuidCName, TokenCName, pcdvalue, Value)) - 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)) + EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s.%s is not found in the DEC file." % (TokenSpaceGuidCName, DisplayName)) else: - EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (TokenCName)) + EdkLogger.error('build', AUTOGEN_ERROR, "The Pcd %s is not found in the DEC file." % (DisplayName)) + pcdvalue = pcdvalue.replace("\\\\\\'", '\\\\\\"').replace('\\\'', '\'').replace('\\\\\\"', "\\'") + if FieldName: + pcdvalue = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict, FieldName) + else: + pcdvalue = self.HandleFlexiblePcd(TokenSpaceGuidCName, TokenCName, pcdvalue, PcdDatumType, self._GuidDict) + IsValid, Cause = CheckPcdDatum(PcdDatumType, pcdvalue) + if not IsValid: + EdkLogger.error("build", FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName)) + GlobalData.BuildOptionPcd[i] = (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue,("build command options",1)) + 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 + PcdItem.DefaultValue = pcdvalue + + def HandleFlexiblePcd(self, TokenSpaceGuidCName, TokenCName, PcdValue, PcdDatumType, GuidDict, FieldName=''): + if FieldName: + IsArray = False + TokenCName += '.' + FieldName + if PcdValue.startswith('H'): + if FieldName and IsFieldValueAnArray(PcdValue[1:]): + PcdDatumType = 'VOID*' + IsArray = True + if FieldName and not IsArray: + return PcdValue + try: + PcdValue = ValueExpressionEx(PcdValue[1:], PcdDatumType, GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % + (TokenSpaceGuidCName, TokenCName, PcdValue, Value)) + elif PcdValue.startswith("L'") or PcdValue.startswith("'"): + if FieldName and IsFieldValueAnArray(PcdValue): + PcdDatumType = 'VOID*' + IsArray = True + if FieldName and not IsArray: + return PcdValue + try: + PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % + (TokenSpaceGuidCName, TokenCName, PcdValue, Value)) + elif PcdValue.startswith('L'): + PcdValue = 'L"' + PcdValue[1:] + '"' + if FieldName and IsFieldValueAnArray(PcdValue): + PcdDatumType = 'VOID*' + IsArray = True + if FieldName and not IsArray: + return PcdValue + try: + PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % + (TokenSpaceGuidCName, TokenCName, PcdValue, Value)) + else: + if PcdValue.upper() == 'FALSE': + PcdValue = str(0) + if PcdValue.upper() == 'TRUE': + PcdValue = str(1) + if not FieldName: + if PcdDatumType not in ['UINT8','UINT16','UINT32','UINT64','BOOLEAN']: + PcdValue = '"' + PcdValue + '"' + else: + IsArray = False + Base = 10 + if PcdValue.upper().startswith('0X'): + Base = 16 + try: + Num = int(PcdValue, Base) + except: + PcdValue = '"' + PcdValue + '"' + if IsFieldValueAnArray(PcdValue): + PcdDatumType = 'VOID*' + IsArray = True + if not IsArray: + return PcdValue + try: + PcdValue = ValueExpressionEx(PcdValue, PcdDatumType, GuidDict)(True) + except BadExpression, Value: + EdkLogger.error('Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % + (TokenSpaceGuidCName, TokenCName, PcdValue, Value)) + return PcdValue + ## Retrieve all PCD settings in platform def _GetPcds(self): if self._Pcds == None: @@ -1242,6 +1244,7 @@ class DscBuildData(PlatformBuildClassObject): if isinstance(self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName), None),StructurePcd): self._DecPcds.get((Pcd.TokenCName,Pcd.TokenSpaceGuidCName)).PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0] else: + Pcd.PcdValueFromComm = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0] Pcd.DefaultValue = NoFiledValues[(Pcd.TokenSpaceGuidCName,Pcd.TokenCName)][0] for sku in Pcd.SkuInfoList: SkuInfo = Pcd.SkuInfoList[sku] @@ -1266,9 +1269,8 @@ class DscBuildData(PlatformBuildClassObject): Pcd.MaxDatumSize = str(MaxSize) else: PcdInDec = self.DecPcds.get((Name,Guid)) - if isinstance(PcdInDec,StructurePcd): - PcdInDec.PcdValueFromComm = NoFiledValues[(Guid,Name)][0] if PcdInDec: + PcdInDec.PcdValueFromComm = NoFiledValues[(Guid,Name)][0] 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) @@ -1555,22 +1557,6 @@ class DscBuildData(PlatformBuildClassObject): return str(max([pcd_size for pcd_size in [get_length(item) for item in sku_values]])) - def IsFieldValueAnArray (self, Value): - Value = Value.strip() - if Value.startswith('GUID') and Value.endswith(')'): - return True - if Value.startswith('L"') and Value.endswith('"') and len(list(Value[2:-1])) > 1: - return True - if Value[0] == '"' and Value[-1] == '"' and len(list(Value[1:-1])) > 1: - return True - if Value[0] == '{' and Value[-1] == '}': - return True - if Value.startswith("L'") and Value.endswith("'") and len(list(Value[2:-1])) > 1: - return True - if Value[0] == "'" and Value[-1] == "'" and len(list(Value[1:-1])) > 1: - return True - return False - def ExecuteCommand (self, Command): try: Process = subprocess.Popen(Command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) @@ -1617,7 +1603,7 @@ class DscBuildData(PlatformBuildClassObject): continue for FieldName in FieldList: FieldName = "." + FieldName - IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')): try: Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) @@ -1647,7 +1633,7 @@ class DscBuildData(PlatformBuildClassObject): continue for FieldName in FieldList: FieldName = "." + FieldName - IsArray = self.IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName.strip(".")][0]) if IsArray and not (FieldList[FieldName.strip(".")][0].startswith('{GUID') and FieldList[FieldName.strip(".")][0].endswith('}')): try: Value = ValueExpressionEx(FieldList[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) @@ -1671,7 +1657,7 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + "// From Command Line \n" for FieldName in Pcd.PcdFieldValueFromComm: FieldName = "." + FieldName - IsArray = self.IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]) + IsArray = IsFieldValueAnArray(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0]) if IsArray and not (Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].startswith('{GUID') and Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0].endswith('}')): try: Value = ValueExpressionEx(Pcd.PcdFieldValueFromComm[FieldName.strip(".")][0], "VOID*", self._GuidDict)(True) @@ -1704,13 +1690,14 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' UINT32 FieldSize;\n' CApp = CApp + ' CHAR8 *Value;\n' DefaultValueFromDec = Pcd.DefaultValueFromDec - IsArray = self.IsFieldValueAnArray(Pcd.DefaultValueFromDec) + IsArray = IsFieldValueAnArray(Pcd.DefaultValueFromDec) if IsArray: try: DefaultValueFromDec = ValueExpressionEx(Pcd.DefaultValueFromDec, "VOID*")(True) except BadExpression: EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DEC: %s" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, DefaultValueFromDec)) + DefaultValueFromDec = StringToArray(DefaultValueFromDec) Value, ValueSize = ParseFieldValue (DefaultValueFromDec) if isinstance(Value, str): CApp = CApp + ' Pcd = %s; // From DEC Default Value %s\n' % (Value, Pcd.DefaultValueFromDec) @@ -1724,7 +1711,7 @@ class DscBuildData(PlatformBuildClassObject): if not FieldList: continue for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) if IsArray: try: FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) @@ -1774,7 +1761,7 @@ class DscBuildData(PlatformBuildClassObject): if not FieldList: continue if pcddefaultvalue and FieldList == pcddefaultvalue: - IsArray = self.IsFieldValueAnArray(FieldList) + IsArray = IsFieldValueAnArray(FieldList) if IsArray: try: FieldList = ValueExpressionEx(FieldList, "VOID*")(True) @@ -1804,7 +1791,7 @@ class DscBuildData(PlatformBuildClassObject): continue if (SkuName,DefaultStoreName) == ('DEFAULT','STANDARD') or (( (SkuName,'') not in Pcd.ValueChain) and ( (SkuName,DefaultStoreName) not in Pcd.ValueChain )): for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) if IsArray: try: FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) @@ -1845,12 +1832,12 @@ class DscBuildData(PlatformBuildClassObject): if not FieldList: continue if pcddefaultvalue and FieldList == pcddefaultvalue: - IsArray = self.IsFieldValueAnArray(FieldList) + IsArray = IsFieldValueAnArray(FieldList) if IsArray: try: FieldList = ValueExpressionEx(FieldList, "VOID*")(True) except BadExpression: - EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from DSC: %s" % + EdkLogger.error("Build", FORMAT_INVALID, "Invalid value format for %s.%s, from Command: %s" % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, FieldList)) Value, ValueSize = ParseFieldValue (FieldList) @@ -1864,7 +1851,7 @@ class DscBuildData(PlatformBuildClassObject): CApp = CApp + ' memcpy (Pcd, Value, %d);\n' % (ValueSize) continue for FieldName in FieldList: - IsArray = self.IsFieldValueAnArray(FieldList[FieldName][0]) + IsArray = IsFieldValueAnArray(FieldList[FieldName][0]) if IsArray: try: FieldList[FieldName][0] = ValueExpressionEx(FieldList[FieldName][0], "VOID*", self._GuidDict)(True) @@ -1992,11 +1979,13 @@ class DscBuildData(PlatformBuildClassObject): CApp = PcdMainCHeader Includes = {} + IncludeFiles = set() for PcdName in StructuredPcds: Pcd = StructuredPcds[PcdName] for IncludeFile in Pcd.StructuredPcdIncludeFile: if IncludeFile not in Includes: Includes[IncludeFile] = True + IncludeFiles.add(IncludeFile) CApp = CApp + '#include <%s>\n' % (IncludeFile) CApp = CApp + '\n' for PcdName in StructuredPcds: @@ -2055,6 +2044,7 @@ class DscBuildData(PlatformBuildClassObject): MakeApp = MakeApp + 'APPNAME = %s\n' % (PcdValueInitName) + 'OBJECTS = %s/%s.o\n' % (self.OutputPath, PcdValueInitName) + \ 'include $(MAKEROOT)/Makefiles/app.makefile\n' + 'INCLUDE +=' + IncSearchList = [] PlatformInc = {} for Cache in self._Bdb._CACHE_.values(): if Cache.MetaFile.Ext.lower() != '.dec': @@ -2077,6 +2067,7 @@ class DscBuildData(PlatformBuildClassObject): if pkg in PlatformInc: for inc in PlatformInc[pkg]: MakeApp += '-I' + str(inc) + ' ' + IncSearchList.append(inc) MakeApp = MakeApp + '\n' CC_FLAGS = LinuxCFLAGS @@ -2124,7 +2115,23 @@ class DscBuildData(PlatformBuildClassObject): if sys.platform == "win32": MakeApp = MakeApp + PcdMakefileEnd + MakeApp = MakeApp + '\n' + IncludeFileFullPaths = [] + for includefile in IncludeFiles: + for includepath in IncSearchList: + includefullpath = os.path.join(str(includepath),includefile) + if os.path.exists(includefullpath): + IncludeFileFullPaths.append(os.path.normpath(includefullpath)) + break + SearchPathList = [] + SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Include"))) + SearchPathList.append(os.path.normpath(mws.join(GlobalData.gWorkspace, "BaseTools/Source/C/Common"))) + SearchPathList.extend([str(item) for item in IncSearchList]) + IncFileList = GetDependencyList(IncludeFileFullPaths,SearchPathList) + for include_file in IncFileList: + MakeApp += "$(OBJECTS) : %s\n" % include_file MakeFileName = os.path.join(self.OutputPath, 'Makefile') + MakeApp += "$(OBJECTS) : %s\n" % MakeFileName SaveFileOnChange(MakeFileName, MakeApp, False) InputValueFile = os.path.join(self.OutputPath, 'Input.txt') @@ -2136,59 +2143,61 @@ class DscBuildData(PlatformBuildClassObject): PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Source', 'C', 'bin', PcdValueInitName) else: PcdValueInitExe = os.path.join(os.getenv("EDK_TOOLS_PATH"), 'Bin', 'Win32', PcdValueInitName) +".exe" - if not os.path.exists(PcdValueInitExe) or self.NeedUpdateOutput(OutputValueFile, CAppBaseFileName + '.c',MakeFileName,InputValueFile): - Messages = '' - if sys.platform == "win32": - MakeCommand = 'nmake clean & nmake -f %s' % (MakeFileName) - returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand) - Messages = StdOut - else: - MakeCommand = 'make clean & make -f %s' % (MakeFileName) - returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand) - Messages = StdErr - Messages = Messages.split('\n') - MessageGroup = [] - if returncode <>0: - CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName) - File = open (CAppBaseFileName + '.c', 'r') - FileData = File.readlines() - File.close() - for Message in Messages: - if " error" in Message or "warning" in Message: - FileInfo = Message.strip().split('(') - if len (FileInfo) > 1: - FileName = FileInfo [0] - FileLine = FileInfo [1].split (')')[0] + + Messages = '' + if sys.platform == "win32": + MakeCommand = 'nmake -f %s' % (MakeFileName) + returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand) + Messages = StdOut + else: + MakeCommand = 'make -f %s' % (MakeFileName) + returncode, StdOut, StdErr = self.ExecuteCommand (MakeCommand) + Messages = StdErr + Messages = Messages.split('\n') + MessageGroup = [] + if returncode <>0: + CAppBaseFileName = os.path.join(self.OutputPath, PcdValueInitName) + File = open (CAppBaseFileName + '.c', 'r') + FileData = File.readlines() + File.close() + for Message in Messages: + if " error" in Message or "warning" in Message: + FileInfo = Message.strip().split('(') + if len (FileInfo) > 1: + FileName = FileInfo [0] + FileLine = FileInfo [1].split (')')[0] + else: + FileInfo = Message.strip().split(':') + FileName = FileInfo [0] + FileLine = FileInfo [1] + if FileLine.isdigit(): + error_line = FileData[int (FileLine) - 1] + if r"//" in error_line: + c_line,dsc_line = error_line.split(r"//") else: - FileInfo = Message.strip().split(':') - FileName = FileInfo [0] - FileLine = FileInfo [1] - if FileLine.isdigit(): - error_line = FileData[int (FileLine) - 1] - if r"//" in error_line: - c_line,dsc_line = error_line.split(r"//") - else: - dsc_line = error_line - message_itmes = Message.split(":") - Index = 0 - if "PcdValueInit.c" not in Message: - if not MessageGroup: - MessageGroup.append(Message) - break - else: - for item in message_itmes: - if "PcdValueInit.c" in item: - Index = message_itmes.index(item) - message_itmes[Index] = dsc_line.strip() - break - MessageGroup.append(":".join(message_itmes[Index:]).strip()) - continue + dsc_line = error_line + message_itmes = Message.split(":") + Index = 0 + if "PcdValueInit.c" not in Message: + if not MessageGroup: + MessageGroup.append(Message) + break else: - MessageGroup.append(Message) - if MessageGroup: - EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) ) - else: - EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand) + for item in message_itmes: + if "PcdValueInit.c" in item: + Index = message_itmes.index(item) + message_itmes[Index] = dsc_line.strip() + break + MessageGroup.append(":".join(message_itmes[Index:]).strip()) + continue + else: + MessageGroup.append(Message) + if MessageGroup: + EdkLogger.error("build", PCD_STRUCTURE_PCD_ERROR, "\n".join(MessageGroup) ) + else: + EdkLogger.error('Build', COMMAND_FAILURE, 'Can not execute command: %s' % MakeCommand) + + if self.NeedUpdateOutput(OutputValueFile, PcdValueInitExe ,InputValueFile): Command = PcdValueInitExe + ' -i %s -o %s' % (InputValueFile, OutputValueFile) returncode, StdOut, StdErr = self.ExecuteCommand (Command) if returncode <> 0: @@ -2205,13 +2214,11 @@ class DscBuildData(PlatformBuildClassObject): StructurePcdSet.append((PcdInfo[0],PcdInfo[1], PcdInfo[2], PcdInfo[3], PcdValue[2].strip())) return StructurePcdSet - def NeedUpdateOutput(self,OutputFile, ValueCFile, MakeFile, StructureInput): + def NeedUpdateOutput(self,OutputFile, ValueCFile, StructureInput): if not os.path.exists(OutputFile): return True if os.stat(OutputFile).st_mtime <= os.stat(ValueCFile).st_mtime: return True - if os.stat(OutputFile).st_mtime <= os.stat(MakeFile).st_mtime: - return True if os.stat(OutputFile).st_mtime <= os.stat(StructureInput).st_mtime: return True return False