diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index 7106a7c54c..c7aa84fb34 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -350,6 +350,67 @@ class WorkspaceAutoGen(AutoGen): DecPcds = {} DecPcdsKey = set() PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch) + if GlobalData.BuildOptionPcd: + for i, pcd in enumerate(GlobalData.BuildOptionPcd): + (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: + for key in package.Pcds: + PcdItem = package.Pcds[key] + if HasTokenSpace: + if (PcdItem.TokenCName, PcdItem.TokenSpaceGuidCName) == (TokenCName, TokenSpaceGuidCName): + PcdDatumType = PcdItem.DatumType + NewValue = self._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 + NewValue = self._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 + #Collect package set information from INF of FDF PkgSet = set() for Inf in ModuleList: @@ -418,6 +479,32 @@ class WorkspaceAutoGen(AutoGen): return True + def _BuildOptionPcdValueFormat(self, TokenSpaceGuidCName, TokenCName, PcdDatumType, Value): + if PcdDatumType == 'VOID*': + if Value.startswith('L'): + if not Value[1]: + EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"') + Value = Value[0] + '"' + Value[1:] + '"' + elif Value.startswith('B'): + if not Value[1]: + EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"') + Value = Value[1:] + else: + if not Value[0]: + EdkLogger.error('build', OPTION_VALUE_INVALID, 'For Void* type PCD, when specify the Value in the command line, please use the following format: "string", L"string", B"{...}"') + Value = '"' + Value + '"' + + IsValid, Cause = CheckPcdDatum(PcdDatumType, Value) + if not IsValid: + EdkLogger.error('build', FORMAT_INVALID, Cause, ExtraData="%s.%s" % (TokenSpaceGuidCName, TokenCName)) + if PcdDatumType == 'BOOLEAN': + Value = Value.upper() + if Value == 'TRUE' or Value == '1': + Value = '1' + elif Value == 'FALSE' or Value == '0': + Value = '0' + return Value + ## _CheckDuplicateInFV() method # # Check whether there is duplicate modules/files exist in FV section. @@ -953,6 +1040,18 @@ 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 gathering error information NoDatumTypePcdList = set() PcdNotInDb = [] diff --git a/BaseTools/Source/Python/AutoGen/GenC.py b/BaseTools/Source/Python/AutoGen/GenC.py index 3f0dfd90d9..842d8bd666 100644 --- a/BaseTools/Source/Python/AutoGen/GenC.py +++ b/BaseTools/Source/Python/AutoGen/GenC.py @@ -766,6 +766,13 @@ def GetPcdSize(Pcd): def CreateModulePcdCode(Info, AutoGenC, AutoGenH, Pcd): TokenSpaceGuidValue = Pcd.TokenSpaceGuidValue #Info.GuidList[Pcd.TokenSpaceGuidCName] PcdTokenNumber = Info.PlatformInfo.PcdTokenNumber + + if GlobalData.BuildOptionPcd: + for PcdItem in GlobalData.BuildOptionPcd: + if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (PcdItem[0], PcdItem[1]): + Pcd.DefaultValue = PcdItem[2] + break + # # Write PCDs # @@ -1054,7 +1061,13 @@ def CreateLibraryPcdCode(Info, AutoGenC, AutoGenH, Pcd): FixPcdSizeTokenName = '_PCD_SIZE_' + Pcd.TokenCName PatchPcdSizeTokenName = '_PCD_PATCHABLE_' + Pcd.TokenCName +'_SIZE' PatchPcdSizeVariableName = '_gPcd_BinaryPatch_Size_' + Pcd.TokenCName - + + if GlobalData.BuildOptionPcd: + for PcdItem in GlobalData.BuildOptionPcd: + if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (PcdItem[0], PcdItem[1]): + Pcd.DefaultValue = PcdItem[2] + break + # # Write PCDs # diff --git a/BaseTools/Source/Python/AutoGen/GenPcdDb.py b/BaseTools/Source/Python/AutoGen/GenPcdDb.py index 23865254d7..76d1254e72 100644 --- a/BaseTools/Source/Python/AutoGen/GenPcdDb.py +++ b/BaseTools/Source/Python/AutoGen/GenPcdDb.py @@ -1,7 +1,7 @@ ## @file # Routines for generating Pcd Database # -# Copyright (c) 2013 - 2015, Intel Corporation. All rights reserved.
+# Copyright (c) 2013 - 2016, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -1141,6 +1141,12 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): CName = Pcd.TokenCName TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName + if GlobalData.BuildOptionPcd: + for PcdItem in GlobalData.BuildOptionPcd: + if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (PcdItem[0], PcdItem[1]): + Pcd.DefaultValue = PcdItem[2] + break + EdkLogger.debug(EdkLogger.DEBUG_3, "PCD: %s %s (%s : %s)" % (CName, TokenSpaceGuidCName, Pcd.Phase, Phase)) if Pcd.Phase == 'PEI': @@ -1455,6 +1461,11 @@ def CreatePcdDatabasePhaseSpecificAutoGen (Platform, Phase): TokenSpaceGuidCName = Pcd.TokenSpaceGuidCName if Pcd.Phase != Phase: continue + if GlobalData.BuildOptionPcd: + for PcdItem in GlobalData.BuildOptionPcd: + if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (PcdItem[0], PcdItem[1]): + Pcd.DefaultValue = PcdItem[2] + break TokenSpaceGuid = GuidStructureStringToGuidValueName(Pcd.TokenSpaceGuidValue) #(Platform.PackageList, TokenSpaceGuidCName)) GeneratedTokenNumber = Platform.PcdTokenNumber[CName, TokenSpaceGuidCName] - 1 diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py index 218034ba33..4234bf5f95 100644 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -1,7 +1,7 @@ ## @file # This file is used to define common static strings used by INF/DEC/DSC files # -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.
# This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License # which accompanies this distribution. The full text of the license may be found at @@ -77,3 +77,4 @@ gFdfParser = None # gTempInfs = [] +BuildOptionPcd = [] diff --git a/BaseTools/Source/Python/build/BuildReport.py b/BaseTools/Source/Python/build/BuildReport.py index 04a4d7dbd5..2dc02c2c4e 100644 --- a/BaseTools/Source/Python/build/BuildReport.py +++ b/BaseTools/Source/Python/build/BuildReport.py @@ -42,6 +42,7 @@ from Common.DataType import TAB_BRG_LIBRARY from Common.DataType import TAB_BACK_SLASH from Common.LongFilePathSupport import OpenLongFilePath as open from Common.MultipleWorkspace import MultipleWorkspace as mws +import Common.GlobalData as GlobalData ## Pattern to extract contents in EDK DXS files gDxsDependencyPattern = re.compile(r"DEPENDENCY_START(.+)DEPENDENCY_END", re.DOTALL) @@ -727,6 +728,7 @@ class PcdReport(object): # FileWrite(File, gSectionStart) FileWrite(File, "Platform Configuration Database Report") + FileWrite(File, " *B - PCD override in the build option") FileWrite(File, " *P - Platform scoped PCD override in DSC file") FileWrite(File, " *F - Platform scoped PCD override in FDF file") FileWrite(File, " *M - Module scoped PCD override") @@ -767,6 +769,15 @@ class PcdReport(object): InfDefault, PcdValue = ModulePcdSet[Pcd.TokenCName, Pcd.TokenSpaceGuidCName, Type] if InfDefault == "": InfDefault = None + + BuildOptionMatch = False + if GlobalData.BuildOptionPcd: + for pcd in GlobalData.BuildOptionPcd: + if (Pcd.TokenSpaceGuidCName, Pcd.TokenCName) == (pcd[0], pcd[1]): + PcdValue = pcd[2] + BuildOptionMatch = True + break + if First: if ModulePcdSet == None: FileWrite(File, "") @@ -812,7 +823,9 @@ class PcdReport(object): # # Report PCD item according to their override relationship # - if DecMatch and InfMatch: + if BuildOptionMatch: + FileWrite(File, ' *B %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip())) + elif DecMatch and InfMatch: FileWrite(File, ' %-*s: %6s %10s = %-22s' % (self.MaxLen, Pcd.TokenCName, TypeName, '(' + Pcd.DatumType + ')', PcdValue.strip())) else: if DscMatch: @@ -840,17 +853,18 @@ class PcdReport(object): FileWrite(File, ' %*s = %s' % (self.MaxLen + 19, 'DEC DEFAULT', DecDefaultValue.strip())) if ModulePcdSet == None: - ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {}) - for ModulePath in ModuleOverride: - ModuleDefault = ModuleOverride[ModulePath] - if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'): - ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0) - Match = (ModulePcdDefaultValueNumber == PcdValueNumber) - else: - Match = (ModuleDefault.strip() == PcdValue.strip()) - if Match: - continue - FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault.strip())) + if not BuildOptionMatch: + ModuleOverride = self.ModulePcdOverride.get((Pcd.TokenCName, Pcd.TokenSpaceGuidCName), {}) + for ModulePath in ModuleOverride: + ModuleDefault = ModuleOverride[ModulePath] + if Pcd.DatumType in ('UINT8', 'UINT16', 'UINT32', 'UINT64'): + ModulePcdDefaultValueNumber = int(ModuleDefault.strip(), 0) + Match = (ModulePcdDefaultValueNumber == PcdValueNumber) + else: + Match = (ModuleDefault.strip() == PcdValue.strip()) + if Match: + continue + FileWrite(File, ' *M %-*s = %s' % (self.MaxLen + 19, ModulePath, ModuleDefault.strip())) if ModulePcdSet == None: FileWrite(File, gSectionEnd) diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index 23ca76e82c..5619638bd8 100644 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -53,7 +53,7 @@ import Common.GlobalData as GlobalData # Version and Copyright VersionNumber = "0.60" + ' ' + gBUILD_VERSION __version__ = "%prog Version " + VersionNumber -__copyright__ = "Copyright (c) 2007 - 2014, Intel Corporation All rights reserved." +__copyright__ = "Copyright (c) 2007 - 2016, Intel Corporation All rights reserved." ## standard targets of build command gSupportedTarget = ['all', 'genc', 'genmake', 'modules', 'libraries', 'fds', 'clean', 'cleanall', 'cleanlib', 'run'] @@ -747,6 +747,7 @@ class Build(): self.BuildReport = BuildReport(BuildOptions.ReportFile, BuildOptions.ReportType) self.TargetTxt = TargetTxtClassObject() self.ToolDef = ToolDefClassObject() + GlobalData.BuildOptionPcd = BuildOptions.OptionPcd #Set global flag for build mode GlobalData.gIgnoreSource = BuildOptions.IgnoreSources @@ -1929,6 +1930,7 @@ def MyOptionParser(): Parser.add_option("--conf", action="store", type="string", dest="ConfDirectory", help="Specify the customized Conf directory.") Parser.add_option("--check-usage", action="store_true", dest="CheckUsage", default=False, help="Check usage content of entries listed in INF file.") Parser.add_option("--ignore-sources", action="store_true", dest="IgnoreSources", default=False, help="Focus to a binary build and ignore all source files") + Parser.add_option("--pcd", action="append", dest="OptionPcd", help="Set PCD value by command line. Format: 'PcdName=Value' ") (Opt, Args) = Parser.parse_args() return (Opt, Args)