X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FAutoGen%2FAutoGen.py;h=a5bef4f7c62a0ec3ab7346460bce44c61cc93349;hp=f9ce17cf77b480a0c98c89826709e143b0a22e20;hb=c0fd7f734e2d33e22215899b40a47b843129541d;hpb=3f7cb70c5a38609cbef2957fccbdf5d6f6a5555b diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index f9ce17cf77..a5bef4f7c6 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -5,13 +5,7 @@ # Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.
# Copyright (c) 2019, American Megatrends, Inc. 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 -# http://opensource.org/licenses/bsd-license.php -# -# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, -# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# SPDX-License-Identifier: BSD-2-Clause-Patent # ## Import Modules @@ -474,7 +468,7 @@ class WorkspaceAutoGen(AutoGen): # generate the SourcePcdDict and BinaryPcdDict PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch) - for BuildData in PGen.BuildDatabase._CACHE_.values(): + for BuildData in list(PGen.BuildDatabase._CACHE_.values()): if BuildData.Arch != Arch: continue if BuildData.MetaFile.Ext == '.inf': @@ -580,7 +574,7 @@ class WorkspaceAutoGen(AutoGen): if NewPcd2 not in GlobalData.MixedPcd[item]: GlobalData.MixedPcd[item].append(NewPcd2) - for BuildData in PGen.BuildDatabase._CACHE_.values(): + for BuildData in list(PGen.BuildDatabase._CACHE_.values()): if BuildData.Arch != Arch: continue for key in BuildData.Pcds: @@ -661,7 +655,7 @@ class WorkspaceAutoGen(AutoGen): # # Generate Package level hash value # - GlobalData.gPackageHash[Arch] = {} + GlobalData.gPackageHash = {} if GlobalData.gUseHashCache: for Pkg in Pkgs: self._GenPkgLevelHash(Pkg) @@ -726,11 +720,11 @@ class WorkspaceAutoGen(AutoGen): for files in AllWorkSpaceMetaFiles: if files.endswith('.dec'): continue - f = open(files, 'r') + f = open(files, 'rb') Content = f.read() f.close() m.update(Content) - SaveFileOnChange(os.path.join(self.BuildDir, 'AutoGen.hash'), m.hexdigest(), True) + SaveFileOnChange(os.path.join(self.BuildDir, 'AutoGen.hash'), m.hexdigest(), False) GlobalData.gPlatformHash = m.hexdigest() # @@ -747,7 +741,7 @@ class WorkspaceAutoGen(AutoGen): return True def _GenPkgLevelHash(self, Pkg): - if Pkg.PackageName in GlobalData.gPackageHash[Pkg.Arch]: + if Pkg.PackageName in GlobalData.gPackageHash: return PkgDir = os.path.join(self.BuildDir, Pkg.Arch, Pkg.PackageName) @@ -755,7 +749,7 @@ class WorkspaceAutoGen(AutoGen): HashFile = os.path.join(PkgDir, Pkg.PackageName + '.hash') m = hashlib.md5() # Get .dec file's hash value - f = open(Pkg.MetaFile.Path, 'r') + f = open(Pkg.MetaFile.Path, 'rb') Content = f.read() f.close() m.update(Content) @@ -765,12 +759,12 @@ class WorkspaceAutoGen(AutoGen): for Root, Dirs, Files in os.walk(str(inc)): for File in sorted(Files): File_Path = os.path.join(Root, File) - f = open(File_Path, 'r') + f = open(File_Path, 'rb') Content = f.read() f.close() m.update(Content) - SaveFileOnChange(HashFile, m.hexdigest(), True) - GlobalData.gPackageHash[Pkg.Arch][Pkg.PackageName] = m.hexdigest() + SaveFileOnChange(HashFile, m.hexdigest(), False) + GlobalData.gPackageHash[Pkg.PackageName] = m.hexdigest() def _GetMetaFiles(self, Target, Toolchain, Arch): AllWorkSpaceMetaFiles = set() @@ -929,7 +923,7 @@ class WorkspaceAutoGen(AutoGen): def _CheckAllPcdsTokenValueConflict(self): for Pa in self.AutoGenObjectList: for Package in Pa.PackageList: - PcdList = Package.Pcds.values() + PcdList = list(Package.Pcds.values()) PcdList.sort(key=lambda x: int(x.TokenValue, 0)) Count = 0 while (Count < len(PcdList) - 1) : @@ -975,7 +969,7 @@ class WorkspaceAutoGen(AutoGen): Count += SameTokenValuePcdListCount Count += 1 - PcdList = Package.Pcds.values() + PcdList = list(Package.Pcds.values()) PcdList.sort(key=lambda x: "%s.%s" % (x.TokenSpaceGuidCName, x.TokenCName)) Count = 0 while (Count < len(PcdList) - 1) : @@ -1141,7 +1135,6 @@ class PlatformAutoGen(AutoGen): self.BuildTarget = Target self.Arch = Arch self.SourceDir = PlatformFile.SubDir - self.SourceOverrideDir = None self.FdTargetList = self.Workspace.FdTargetList self.FvTargetList = self.Workspace.FvTargetList # get the original module/package/platform objects @@ -1187,7 +1180,7 @@ class PlatformAutoGen(AutoGen): # @cached_class_function def CreateCodeFile(self, CreateModuleCodeFile=False): - # only module has code to be greated, so do nothing if CreateModuleCodeFile is False + # only module has code to be created, so do nothing if CreateModuleCodeFile is False if not CreateModuleCodeFile: return @@ -1300,7 +1293,7 @@ class PlatformAutoGen(AutoGen): if os.path.exists(VpdMapFilePath): OrgVpdFile.Read(VpdMapFilePath) PcdItems = OrgVpdFile.GetOffset(PcdNvStoreDfBuffer[0]) - NvStoreOffset = PcdItems.values()[0].strip() if PcdItems else '0' + NvStoreOffset = list(PcdItems.values())[0].strip() if PcdItems else '0' else: EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath) @@ -1499,7 +1492,7 @@ class PlatformAutoGen(AutoGen): if (self.Workspace.ArchList[-1] == self.Arch): for Pcd in self._DynamicPcdList: # just pick the a value to determine whether is unicode string type - Sku = Pcd.SkuInfoList.values()[0] + Sku = Pcd.SkuInfoList.get(TAB_DEFAULT) Sku.VpdOffset = Sku.VpdOffset.strip() if Pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]: @@ -1605,7 +1598,7 @@ class PlatformAutoGen(AutoGen): if not FoundFlag : # just pick the a value to determine whether is unicode string type SkuValueMap = {} - SkuObjList = DscPcdEntry.SkuInfoList.items() + SkuObjList = list(DscPcdEntry.SkuInfoList.items()) DefaultSku = DscPcdEntry.SkuInfoList.get(TAB_DEFAULT) if DefaultSku: defaultindex = SkuObjList.index((TAB_DEFAULT, DefaultSku)) @@ -1631,7 +1624,7 @@ class PlatformAutoGen(AutoGen): DscPcdEntry.TokenSpaceGuidValue = eachDec.Guids[DecPcdEntry.TokenSpaceGuidCName] # Only fix the value while no value provided in DSC file. if not Sku.DefaultValue: - DscPcdEntry.SkuInfoList[DscPcdEntry.SkuInfoList.keys()[0]].DefaultValue = DecPcdEntry.DefaultValue + DscPcdEntry.SkuInfoList[list(DscPcdEntry.SkuInfoList.keys())[0]].DefaultValue = DecPcdEntry.DefaultValue if DscPcdEntry not in self._DynamicPcdList: self._DynamicPcdList.append(DscPcdEntry) @@ -1688,7 +1681,7 @@ class PlatformAutoGen(AutoGen): PcdName,PcdGuid = PcdNvStoreDfBuffer[0].TokenCName, PcdNvStoreDfBuffer[0].TokenSpaceGuidCName if (PcdName,PcdGuid) in VpdSkuMap: DefaultSku = PcdNvStoreDfBuffer[0].SkuInfoList.get(TAB_DEFAULT) - VpdSkuMap[(PcdName,PcdGuid)] = {DefaultSku.DefaultValue:[DefaultSku]} + VpdSkuMap[(PcdName,PcdGuid)] = {DefaultSku.DefaultValue:[SkuObj for SkuObj in PcdNvStoreDfBuffer[0].SkuInfoList.values() ]} # Process VPD map file generated by third party BPDG tool if NeedProcessVpdMapFile: @@ -1713,7 +1706,7 @@ class PlatformAutoGen(AutoGen): # Delete the DynamicPcdList At the last time enter into this function for Pcd in self._DynamicPcdList: # just pick the a value to determine whether is unicode string type - Sku = Pcd.SkuInfoList.values()[0] + Sku = Pcd.SkuInfoList.get(TAB_DEFAULT) Sku.VpdOffset = Sku.VpdOffset.strip() if Pcd.DatumType not in [TAB_UINT8, TAB_UINT16, TAB_UINT32, TAB_UINT64, TAB_VOID, "BOOLEAN"]: @@ -1736,7 +1729,7 @@ class PlatformAutoGen(AutoGen): for pcd in self._DynamicPcdList: if len(pcd.SkuInfoList) == 1: for (SkuName, SkuId) in allskuset: - if type(SkuId) in (str, unicode) and eval(SkuId) == 0 or SkuId == 0: + if isinstance(SkuId, str) and eval(SkuId) == 0 or SkuId == 0: continue pcd.SkuInfoList[SkuName] = copy.deepcopy(pcd.SkuInfoList[TAB_DEFAULT]) pcd.SkuInfoList[SkuName].SkuId = SkuId @@ -1849,7 +1842,7 @@ class PlatformAutoGen(AutoGen): ## Get tool chain definition # - # Get each tool defition for given tool chain from tools_def.txt and platform + # Get each tool definition for given tool chain from tools_def.txt and platform # @cached_property def ToolDefinition(self): @@ -1906,7 +1899,7 @@ class PlatformAutoGen(AutoGen): ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value) ToolsDef += "\n" - SaveFileOnChange(self.ToolDefinitionFile, ToolsDef) + SaveFileOnChange(self.ToolDefinitionFile, ToolsDef, False) for DllPath in DllPathList: os.environ["PATH"] = DllPath + os.pathsep + os.environ["PATH"] os.environ["MAKE_FLAGS"] = MakeFlags @@ -2130,8 +2123,8 @@ class PlatformAutoGen(AutoGen): ## Override PCD setting (type, value, ...) # - # @param ToPcd The PCD to be overrided - # @param FromPcd The PCD overrideing from + # @param ToPcd The PCD to be overridden + # @param FromPcd The PCD overriding from # def _OverridePcd(self, ToPcd, FromPcd, Module="", Msg="", Library=""): # @@ -2218,7 +2211,7 @@ class PlatformAutoGen(AutoGen): ## Apply PCD setting defined platform to a module # - # @param Module The module from which the PCD setting will be overrided + # @param Module The module from which the PCD setting will be overridden # # @retval PCD_list The list PCDs with settings from platform # @@ -2286,7 +2279,7 @@ class PlatformAutoGen(AutoGen): Pcd.MaxDatumSize = str(len(Value.split(','))) else: Pcd.MaxDatumSize = str(len(Value) - 1) - return Pcds.values() + return list(Pcds.values()) @@ -2355,7 +2348,7 @@ class PlatformAutoGen(AutoGen): # Use the highest priority value. # if (len(OverrideList) >= 2): - KeyList = OverrideList.keys() + KeyList = list(OverrideList.keys()) for Index in range(len(KeyList)): NowKey = KeyList[Index] Target1, ToolChain1, Arch1, CommandType1, Attr1 = NowKey.split("_") @@ -2450,7 +2443,7 @@ class PlatformAutoGen(AutoGen): ## Append build options in platform to a module # - # @param Module The module to which the build options will be appened + # @param Module The module to which the build options will be appended # # @retval options The options appended with build options in platform # @@ -2473,9 +2466,9 @@ class PlatformAutoGen(AutoGen): if Attr == TAB_TOD_DEFINES_BUILDRULEORDER: BuildRuleOrder = Options[Tool][Attr] - AllTools = set(ModuleOptions.keys() + PlatformOptions.keys() + - PlatformModuleOptions.keys() + ModuleTypeOptions.keys() + - self.ToolDefinition.keys()) + AllTools = set(list(ModuleOptions.keys()) + list(PlatformOptions.keys()) + + list(PlatformModuleOptions.keys()) + list(ModuleTypeOptions.keys()) + + list(self.ToolDefinition.keys())) BuildOptions = defaultdict(lambda: defaultdict(str)) for Tool in AllTools: for Options in [self.ToolDefinition, ModuleOptions, PlatformOptions, ModuleTypeOptions, PlatformModuleOptions]: @@ -2559,11 +2552,6 @@ class ModuleAutoGen(AutoGen): self.SourceDir = self.MetaFile.SubDir self.SourceDir = mws.relpath(self.SourceDir, self.WorkspaceDir) - self.SourceOverrideDir = None - # use overrided path defined in DSC file - if self.MetaFile.Key in GlobalData.gOverrideDir: - self.SourceOverrideDir = GlobalData.gOverrideDir[self.MetaFile.Key] - self.ToolChain = Toolchain self.BuildTarget = Target self.Arch = Arch @@ -2685,7 +2673,7 @@ class ModuleAutoGen(AutoGen): def Guid(self): # # To build same module more than once, the module path with FILE_GUID overridden has - # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the realy path + # the file name FILE_GUIDmodule.inf, but the relative path (self.MetaFile.File) is the real path # in DSC. The overridden GUID can be retrieved from file name # if os.path.basename(self.MetaFile.File) != os.path.basename(self.MetaFile.Path): @@ -2745,7 +2733,7 @@ class ModuleAutoGen(AutoGen): self.MetaFile.BaseName )) - ## Return the directory to store the intermediate object files of the mdoule + ## Return the directory to store the intermediate object files of the module @cached_property def OutputDir(self): return _MakeDir((self.BuildDir, "OUTPUT")) @@ -2757,7 +2745,7 @@ class ModuleAutoGen(AutoGen): return path.join(self.PlatformInfo.BuildDir, TAB_FV_DIRECTORY, "Ffs", self.Guid + self.Name) return '' - ## Return the directory to store auto-gened source files of the mdoule + ## Return the directory to store auto-gened source files of the module @cached_property def DebugDir(self): return _MakeDir((self.BuildDir, "DEBUG")) @@ -2768,12 +2756,7 @@ class ModuleAutoGen(AutoGen): RetVal = {} for Type in self.Module.CustomMakefile: MakeType = gMakeTypeMap[Type] if Type in gMakeTypeMap else 'nmake' - if self.SourceOverrideDir is not None: - File = os.path.join(self.SourceOverrideDir, self.Module.CustomMakefile[Type]) - if not os.path.exists(File): - File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type]) - else: - File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type]) + File = os.path.join(self.SourceDir, self.Module.CustomMakefile[Type]) RetVal[MakeType] = File return RetVal @@ -2809,7 +2792,7 @@ class ModuleAutoGen(AutoGen): ## Get the depex string # - # @return : a string contain all depex expresion. + # @return : a string contain all depex expression. def _GetDepexExpresionString(self): DepexStr = '' DepexList = [] @@ -2819,11 +2802,11 @@ class ModuleAutoGen(AutoGen): for M in [self.Module] + self.DependentLibraryList: Filename = M.MetaFile.Path InfObj = InfSectionParser.InfSectionParser(Filename) - DepexExpresionList = InfObj.GetDepexExpresionList() - for DepexExpresion in DepexExpresionList: - for key in DepexExpresion: + DepexExpressionList = InfObj.GetDepexExpresionList() + for DepexExpression in DepexExpressionList: + for key in DepexExpression: Arch, ModuleType = key - DepexExpr = [x for x in DepexExpresion[key] if not str(x).startswith('#')] + DepexExpr = [x for x in DepexExpression[key] if not str(x).startswith('#')] # the type of build module is USER_DEFINED. # All different DEPEX section tags would be copied into the As Built INF file # and there would be separate DEPEX section tags @@ -2878,7 +2861,7 @@ class ModuleAutoGen(AutoGen): DepexList = [] # - # Append depex from dependent libraries, if not "BEFORE", "AFTER" expresion + # Append depex from dependent libraries, if not "BEFORE", "AFTER" expression # for M in [self.Module] + self.DependentLibraryList: Inherited = False @@ -2892,10 +2875,16 @@ class ModuleAutoGen(AutoGen): if '.' not in item: NewList.append(item) else: - if item not in self.FixedVoidTypePcds: + FixedVoidTypePcds = {} + if item in self.FixedVoidTypePcds: + FixedVoidTypePcds = self.FixedVoidTypePcds + elif M in self.PlatformInfo.LibraryAutoGenList: + Index = self.PlatformInfo.LibraryAutoGenList.index(M) + FixedVoidTypePcds = self.PlatformInfo.LibraryAutoGenList[Index].FixedVoidTypePcds + if item not in FixedVoidTypePcds: EdkLogger.error("build", FORMAT_INVALID, "{} used in [Depex] section should be used as FixedAtBuild type and VOID* datum type in the module.".format(item)) else: - Value = self.FixedVoidTypePcds[item] + Value = FixedVoidTypePcds[item] if len(Value.split(',')) != 16: EdkLogger.error("build", FORMAT_INVALID, "{} used in [Depex] section should be used as FixedAtBuild type and VOID* datum type and 16 bytes in the module.".format(item)) @@ -3031,13 +3020,14 @@ class ModuleAutoGen(AutoGen): # EDK II modules must not reference header files outside of the packages they depend on or # within the module's directory tree. Report error if violation. # - for Path in IncPathList: - if (Path not in self.IncludePathList) and (CommonPath([Path, self.MetaFile.Dir]) != self.MetaFile.Dir): - ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path, Tool, FlagOption) - EdkLogger.error("build", - PARAMETER_INVALID, - ExtraData=ErrMsg, - File=str(self.MetaFile)) + if GlobalData.gDisableIncludePathCheck == False: + for Path in IncPathList: + if (Path not in self.IncludePathList) and (CommonPath([Path, self.MetaFile.Dir]) != self.MetaFile.Dir): + ErrMsg = "The include directory for the EDK II module in this line is invalid %s specified in %s FLAGS '%s'" % (Path, Tool, FlagOption) + EdkLogger.error("build", + PARAMETER_INVALID, + ExtraData=ErrMsg, + File=str(self.MetaFile)) RetVal += IncPathList return RetVal @@ -3303,7 +3293,7 @@ class ModuleAutoGen(AutoGen): AutoFile = PathClass(gAutoGenStringFileName % {"module_name":self.Name}, self.DebugDir) RetVal[AutoFile] = str(StringH) self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) - if UniStringBinBuffer is not None and UniStringBinBuffer.getvalue() != "": + if UniStringBinBuffer is not None and UniStringBinBuffer.getvalue() != b"": AutoFile = PathClass(gAutoGenStringFormFileName % {"module_name":self.Name}, self.OutputDir) RetVal[AutoFile] = UniStringBinBuffer.getvalue() AutoFile.IsBinary = True @@ -3314,7 +3304,7 @@ class ModuleAutoGen(AutoGen): AutoFile = PathClass(gAutoGenImageDefFileName % {"module_name":self.Name}, self.DebugDir) RetVal[AutoFile] = str(StringIdf) self._ApplyBuildRule(AutoFile, TAB_UNKNOWN_FILE) - if IdfGenBinBuffer is not None and IdfGenBinBuffer.getvalue() != "": + if IdfGenBinBuffer is not None and IdfGenBinBuffer.getvalue() != b"": AutoFile = PathClass(gAutoGenIdfFileName % {"module_name":self.Name}, self.OutputDir) RetVal[AutoFile] = IdfGenBinBuffer.getvalue() AutoFile.IsBinary = True @@ -3323,7 +3313,7 @@ class ModuleAutoGen(AutoGen): IdfGenBinBuffer.close() return RetVal - ## Return the list of library modules explicitly or implicityly used by this module + ## Return the list of library modules explicitly or implicitly used by this module @cached_property def DependentLibraryList(self): # only merge library classes and PCD for non-library module @@ -3426,7 +3416,7 @@ class ModuleAutoGen(AutoGen): RetVal.append(PackageDir) IncludesList = Package.Includes if Package._PrivateIncludes: - if not self.MetaFile.Path.startswith(PackageDir): + if not self.MetaFile.OriginalPath.Path.startswith(PackageDir): IncludesList = list(set(Package.Includes).difference(set(Package._PrivateIncludes))) for Inc in IncludesList: if Inc not in RetVal: @@ -3519,7 +3509,7 @@ class ModuleAutoGen(AutoGen): return None MapFileName = os.path.join(self.OutputDir, self.Name + ".map") EfiFileName = os.path.join(self.OutputDir, self.Name + ".efi") - VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values()) + VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, list(VfrUniBaseName.values())) if not VfrUniOffsetList: return None @@ -3532,7 +3522,7 @@ class ModuleAutoGen(AutoGen): EdkLogger.error("build", FILE_OPEN_FAILURE, "File open failed for %s" % UniVfrOffsetFileName, None) # Use a instance of BytesIO to cache data - fStringIO = BytesIO('') + fStringIO = BytesIO() for Item in VfrUniOffsetList: if (Item[0].find("Strings") != -1): @@ -3541,9 +3531,8 @@ class ModuleAutoGen(AutoGen): # GUID + Offset # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } } # - UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66] - UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid] - fStringIO.write(''.join(UniGuid)) + UniGuid = b'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f' + fStringIO.write(UniGuid) UniValue = pack ('Q', int (Item[1], 16)) fStringIO.write (UniValue) else: @@ -3552,9 +3541,8 @@ class ModuleAutoGen(AutoGen): # GUID + Offset # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }; # - VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2] - VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid] - fStringIO.write(''.join(VfrGuid)) + VfrGuid = b'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2' + fStringIO.write(VfrGuid) VfrValue = pack ('Q', int (Item[1], 16)) fStringIO.write (VfrValue) # @@ -3814,7 +3802,7 @@ class ModuleAutoGen(AutoGen): Padding = '0x00, ' if Unicode: Padding = Padding * 2 - ArraySize = ArraySize / 2 + ArraySize = ArraySize // 2 if ArraySize < (len(PcdValue) + 1): if Pcd.MaxSizeUserSet: EdkLogger.error("build", AUTOGEN_ERROR, @@ -3896,8 +3884,8 @@ class ModuleAutoGen(AutoGen): AsBuiltInfDict['userextension_tianocore_item'] = UserExtStr # Generated depex expression section in comments. - DepexExpresion = self._GetDepexExpresionString() - AsBuiltInfDict['depexsection_item'] = DepexExpresion if DepexExpresion else '' + DepexExpression = self._GetDepexExpresionString() + AsBuiltInfDict['depexsection_item'] = DepexExpression if DepexExpression else '' AsBuiltInf = TemplateString() AsBuiltInf.Append(gAsBuiltInfHeaderString.Replace(AsBuiltInfDict)) @@ -3909,16 +3897,17 @@ class ModuleAutoGen(AutoGen): self.CopyModuleToCache() def CopyModuleToCache(self): - FileDir = path.join(GlobalData.gBinCacheDest, self.Arch, self.SourceDir, self.MetaFile.BaseName) + FileDir = path.join(GlobalData.gBinCacheDest, self.PlatformInfo.OutputDir, self.BuildTarget + "_" + self.ToolChain, self.Arch, self.SourceDir, self.MetaFile.BaseName) CreateDirectory (FileDir) HashFile = path.join(self.BuildDir, self.Name + '.hash') - ModuleFile = path.join(self.OutputDir, self.Name + '.inf') if os.path.exists(HashFile): shutil.copy2(HashFile, FileDir) - if os.path.exists(ModuleFile): - shutil.copy2(ModuleFile, FileDir) + if not self.IsLibrary: + ModuleFile = path.join(self.OutputDir, self.Name + '.inf') + if os.path.exists(ModuleFile): + shutil.copy2(ModuleFile, FileDir) if not self.OutputFile: - Ma = self.BuildDatabase[PathClass(ModuleFile), self.Arch, self.BuildTarget, self.ToolChain] + Ma = self.BuildDatabase[self.MetaFile, self.Arch, self.BuildTarget, self.ToolChain] self.OutputFile = Ma.Binaries if self.OutputFile: for File in self.OutputFile: @@ -3926,17 +3915,27 @@ class ModuleAutoGen(AutoGen): if not os.path.isabs(File): File = os.path.join(self.OutputDir, File) if os.path.exists(File): - shutil.copy2(File, FileDir) + sub_dir = os.path.relpath(File, self.OutputDir) + destination_file = os.path.join(FileDir, sub_dir) + destination_dir = os.path.dirname(destination_file) + CreateDirectory(destination_dir) + shutil.copy2(File, destination_dir) def AttemptModuleCacheCopy(self): + # If library or Module is binary do not skip by hash if self.IsBinaryModule: return False - FileDir = path.join(GlobalData.gBinCacheSource, self.Arch, self.SourceDir, self.MetaFile.BaseName) + # .inc is contains binary information so do not skip by hash as well + for f_ext in self.SourceFileList: + if '.inc' in str(f_ext): + return False + FileDir = path.join(GlobalData.gBinCacheSource, self.PlatformInfo.OutputDir, self.BuildTarget + "_" + self.ToolChain, self.Arch, self.SourceDir, self.MetaFile.BaseName) HashFile = path.join(FileDir, self.Name + '.hash') if os.path.exists(HashFile): f = open(HashFile, 'r') CacheHash = f.read() f.close() + self.GenModuleHash() if GlobalData.gModuleHash[self.Arch][self.Name]: if CacheHash == GlobalData.gModuleHash[self.Arch][self.Name]: for root, dir, files in os.walk(FileDir): @@ -3945,7 +3944,11 @@ class ModuleAutoGen(AutoGen): shutil.copy2(HashFile, self.BuildDir) else: File = path.join(root, f) - shutil.copy2(File, self.OutputDir) + sub_dir = os.path.relpath(File, FileDir) + destination_file = os.path.join(self.OutputDir, sub_dir) + destination_dir = os.path.dirname(destination_file) + CreateDirectory(destination_dir) + shutil.copy2(File, destination_dir) if self.Name == "PcdPeim" or self.Name == "PcdDxe": CreatePcdDatabaseCode(self, TemplateString(), TemplateString()) return True @@ -4091,50 +4094,86 @@ class ModuleAutoGen(AutoGen): return RetVal def GenModuleHash(self): + # Initialize a dictionary for each arch type if self.Arch not in GlobalData.gModuleHash: GlobalData.gModuleHash[self.Arch] = {} + + # Early exit if module or library has been hashed and is in memory + if self.Name in GlobalData.gModuleHash[self.Arch]: + return GlobalData.gModuleHash[self.Arch][self.Name].encode('utf-8') + + # Initialze hash object m = hashlib.md5() + # Add Platform level hash - m.update(GlobalData.gPlatformHash) + m.update(GlobalData.gPlatformHash.encode('utf-8')) + # Add Package level hash if self.DependentPackageList: for Pkg in sorted(self.DependentPackageList, key=lambda x: x.PackageName): - if Pkg.PackageName in GlobalData.gPackageHash[self.Arch]: - m.update(GlobalData.gPackageHash[self.Arch][Pkg.PackageName]) + if Pkg.PackageName in GlobalData.gPackageHash: + m.update(GlobalData.gPackageHash[Pkg.PackageName].encode('utf-8')) # Add Library hash if self.LibraryAutoGenList: for Lib in sorted(self.LibraryAutoGenList, key=lambda x: x.Name): if Lib.Name not in GlobalData.gModuleHash[self.Arch]: Lib.GenModuleHash() - m.update(GlobalData.gModuleHash[self.Arch][Lib.Name]) + m.update(GlobalData.gModuleHash[self.Arch][Lib.Name].encode('utf-8')) # Add Module self - f = open(str(self.MetaFile), 'r') + f = open(str(self.MetaFile), 'rb') Content = f.read() f.close() m.update(Content) + # Add Module's source files if self.SourceFileList: for File in sorted(self.SourceFileList, key=lambda x: str(x)): - f = open(str(File), 'r') + f = open(str(File), 'rb') Content = f.read() f.close() m.update(Content) - ModuleHashFile = path.join(self.BuildDir, self.Name + ".hash") - if self.Name not in GlobalData.gModuleHash[self.Arch]: - GlobalData.gModuleHash[self.Arch][self.Name] = m.hexdigest() - if GlobalData.gBinCacheSource: - if self.AttemptModuleCacheCopy(): - return False - return SaveFileOnChange(ModuleHashFile, m.hexdigest(), True) + GlobalData.gModuleHash[self.Arch][self.Name] = m.hexdigest() + + return GlobalData.gModuleHash[self.Arch][self.Name].encode('utf-8') ## Decide whether we can skip the ModuleAutoGen process def CanSkipbyHash(self): - if GlobalData.gUseHashCache: - return not self.GenModuleHash() - return False + # Hashing feature is off + if not GlobalData.gUseHashCache: + return False + + # Initialize a dictionary for each arch type + if self.Arch not in GlobalData.gBuildHashSkipTracking: + GlobalData.gBuildHashSkipTracking[self.Arch] = dict() + + # If library or Module is binary do not skip by hash + if self.IsBinaryModule: + return False + + # .inc is contains binary information so do not skip by hash as well + for f_ext in self.SourceFileList: + if '.inc' in str(f_ext): + return False + + # Use Cache, if exists and if Module has a copy in cache + if GlobalData.gBinCacheSource and self.AttemptModuleCacheCopy(): + return True + + # Early exit for libraries that haven't yet finished building + HashFile = path.join(self.BuildDir, self.Name + ".hash") + if self.IsLibrary and not os.path.exists(HashFile): + return False + + # Return a Boolean based on if can skip by hash, either from memory or from IO. + if self.Name not in GlobalData.gBuildHashSkipTracking[self.Arch]: + # If hashes are the same, SaveFileOnChange() will return False. + GlobalData.gBuildHashSkipTracking[self.Arch][self.Name] = not SaveFileOnChange(HashFile, self.GenModuleHash(), True) + return GlobalData.gBuildHashSkipTracking[self.Arch][self.Name] + else: + return GlobalData.gBuildHashSkipTracking[self.Arch][self.Name] ## Decide whether we can skip the ModuleAutoGen process # If any source file is newer than the module than we cannot skip