Reviewed-by: Bob Feng <bob.c.f...@intel.com> -----Original Message----- From: Rodriguez, Christian Sent: Thursday, May 30, 2019 12:27 AM To: devel@edk2.groups.io Cc: Feng, Bob C <bob.c.f...@intel.com>; Gao, Liming <liming....@intel.com>; Zhu, Yonghong <yonghong....@intel.com> Subject: [Patch V4 2/2] BaseTools: Refactor hash tracking after checking for Sources section
BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1804 After adding a check to see if [Sources] section lists all the header type files of a module, track module and library hashes for --hash feature. If above check is not in compilance for a library or module, force hash invalidation on that library or module. Signed-off-by: Christian Rodriguez <christian.rodrig...@intel.com> Cc: Bob Feng <bob.c.f...@intel.com> Cc: Liming Gao <liming....@intel.com> Cc: Yonghong Zhu <yonghong....@intel.com> --- BaseTools/Source/Python/AutoGen/AutoGen.py | 6 +- BaseTools/Source/Python/AutoGen/GenMake.py | 6 ++ BaseTools/Source/Python/Common/GlobalData.py | 3 +- BaseTools/Source/Python/build/build.py | 65 ++++++++++++-------- 4 files changed, 53 insertions(+), 27 deletions(-) diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py index a5bef4f7c6..a376bc24d6 100644 --- a/BaseTools/Source/Python/AutoGen/AutoGen.py +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py @@ -3989,7 +3989,8 @@ class ModuleAutoGen(AutoGen): for LibraryAutoGen in self.LibraryAutoGenList: LibraryAutoGen.CreateMakeFile() - if self.CanSkip(): + # Don't enable if hash feature enabled, CanSkip uses timestamps to determine build skipping + if not GlobalData.gUseHashCache and self.CanSkip(): return if len(self.CustomMakefile) == 0: @@ -4032,7 +4033,8 @@ class ModuleAutoGen(AutoGen): for LibraryAutoGen in self.LibraryAutoGenList: LibraryAutoGen.CreateCodeFile() - if self.CanSkip(): + # Don't enable if hash feature enabled, CanSkip uses timestamps to determine build skipping + if not GlobalData.gUseHashCache and self.CanSkip(): return AutoGenList = [] diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py index 5c992d7c26..212ca0fa7f 100644 --- a/BaseTools/Source/Python/AutoGen/GenMake.py +++ b/BaseTools/Source/Python/AutoGen/GenMake.py @@ -935,10 +935,16 @@ cleanlib: continue headerFileDependencySet.add(aFileName) + # Ensure that gModuleBuildTracking has been initialized per architecture + if self._AutoGenObject.Arch not in GlobalData.gModuleBuildTracking: + GlobalData.gModuleBuildTracking[self._AutoGenObject.Arch] = + dict() + # Check if a module dependency header file is missing from the module's MetaFile for aFile in headerFileDependencySet: if aFile in headerFilesInMetaFileSet: continue + if GlobalData.gUseHashCache: + GlobalData.gModuleBuildTracking[self._AutoGenObject.Arch][self._AutoGenObject] = 'FAIL_METAFILE' EdkLogger.warn("build","Module MetaFile [Sources] is missing local header!", ExtraData = "Local Header: " + aFile + " not found in " + self._AutoGenObject.MetaFile.Path ) diff --git a/BaseTools/Source/Python/Common/GlobalData.py b/BaseTools/Source/Python/Common/GlobalData.py index 95e28a988f..bd45a43728 100644 --- a/BaseTools/Source/Python/Common/GlobalData.py +++ b/BaseTools/Source/Python/Common/GlobalData.py @@ -110,7 +110,8 @@ gEnableGenfdsMultiThread = False gSikpAutoGenCache = set() # Dictionary for tracking Module build status as success or failure -# False -> Fail : True -> Success +# Top Dict: Key: Arch Type Value: Dictionary +# Second Dict: Key: AutoGen Obj Value: 'SUCCESS'\'FAIL'\'FAIL_METAFILE' gModuleBuildTracking = dict() # Dictionary of booleans that dictate whether a module or diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py index 80ceb98310..0855d4561c 100644 --- a/BaseTools/Source/Python/build/build.py +++ b/BaseTools/Source/Python/build/build.py @@ -625,8 +625,16 @@ class BuildTask: BuildTask._ErrorFlag.set() BuildTask._ErrorMessage = "%s broken\n %s [%s]" % \ (threading.currentThread().getName(), Command, WorkingDir) - if self.BuildItem.BuildObject in GlobalData.gModuleBuildTracking and not BuildTask._ErrorFlag.isSet(): - GlobalData.gModuleBuildTracking[self.BuildItem.BuildObject] = True + + # Set the value used by hash invalidation flow in GlobalData.gModuleBuildTracking to 'SUCCESS' + # If Module or Lib is being tracked, it did not fail header check test, and built successfully + if (self.BuildItem.BuildObject.Arch in GlobalData.gModuleBuildTracking and + self.BuildItem.BuildObject in GlobalData.gModuleBuildTracking[self.BuildItem.BuildObject.Arch] and + GlobalData.gModuleBuildTracking[self.BuildItem.BuildObject.Arch][self.BuildItem.BuildObject] != 'FAIL_METAFILE' and + not BuildTask._ErrorFlag.isSet() + ): + GlobalData.gModuleBuildTracking[self.BuildItem.BuildObject.Arch][self.BuildItem.BuildObject] = 'SUCCESS' + # indicate there's a thread is available for another build task BuildTask._RunningQueueLock.acquire() BuildTask._RunningQueue.pop(self.BuildItem) @@ -1154,27 +1162,30 @@ class Build(): # # def invalidateHash(self): - # GlobalData.gModuleBuildTracking contains only modules that cannot be skipped by hash - for moduleAutoGenObj in GlobalData.gModuleBuildTracking.keys(): - # False == FAIL : True == Success - # Skip invalidating for Successful module builds - if GlobalData.gModuleBuildTracking[moduleAutoGenObj] == True: - continue + # Only for hashing feature + if not GlobalData.gUseHashCache: + return + + # GlobalData.gModuleBuildTracking contains only modules or libs that cannot be skipped by hash + for moduleAutoGenObjArch in GlobalData.gModuleBuildTracking.keys(): + for moduleAutoGenObj in GlobalData.gModuleBuildTracking[moduleAutoGenObjArch].keys(): + # Skip invalidating for Successful Module/Lib builds + if GlobalData.gModuleBuildTracking[moduleAutoGenObjArch][moduleAutoGenObj] == 'SUCCESS': + continue - # The module failed to build or failed to start building, from this point on + # The module failed to build, failed to start building, + or failed the header check test from this point on - # Remove .hash from build - if GlobalData.gUseHashCache: - ModuleHashFile = path.join(moduleAutoGenObj.BuildDir, moduleAutoGenObj.Name + ".hash") + # Remove .hash from build + ModuleHashFile = + os.path.join(moduleAutoGenObj.BuildDir, moduleAutoGenObj.Name + + ".hash") if os.path.exists(ModuleHashFile): os.remove(ModuleHashFile) - # Remove .hash file from cache - if GlobalData.gBinCacheDest: - FileDir = path.join(GlobalData.gBinCacheDest, moduleAutoGenObj.Arch, moduleAutoGenObj.SourceDir, moduleAutoGenObj.MetaFile.BaseName) - HashFile = path.join(FileDir, moduleAutoGenObj.Name + '.hash') - if os.path.exists(HashFile): - os.remove(HashFile) + # Remove .hash file from cache + if GlobalData.gBinCacheDest: + FileDir = os.path.join(GlobalData.gBinCacheDest, moduleAutoGenObj.Arch, moduleAutoGenObj.SourceDir, moduleAutoGenObj.MetaFile.BaseName) + HashFile = os.path.join(FileDir, moduleAutoGenObj.Name + '.hash') + if os.path.exists(HashFile): + os.remove(HashFile) ## Build a module or platform # @@ -1825,9 +1836,11 @@ class Build(): if self.Target == "genmake": return True self.BuildModules.append(Ma) - # Initialize all modules in tracking to False (FAIL) - if Ma not in GlobalData.gModuleBuildTracking: - GlobalData.gModuleBuildTracking[Ma] = False + # Initialize all modules in tracking to 'FAIL' + if Ma.Arch not in GlobalData.gModuleBuildTracking: + GlobalData.gModuleBuildTracking[Ma.Arch] = dict() + if Ma not in GlobalData.gModuleBuildTracking[Ma.Arch]: + GlobalData.gModuleBuildTracking[Ma.Arch][Ma] = 'FAIL' self.AutoGenTime += int(round((time.time() - AutoGenStart))) MakeStart = time.time() for Ma in self.BuildModules: @@ -1911,6 +1924,7 @@ class Build(): # Save MAP buffer into MAP file. # self._SaveMapFile (MapBuffer, Wa) + self.invalidateHash() def _GenFfsCmd(self,ArchList): # convert dictionary of Cmd:(Inf,Arch) @@ -2009,9 +2023,11 @@ class Build(): if self.Target == "genmake": continue self.BuildModules.append(Ma) - # Initialize all modules in tracking to False (FAIL) - if Ma not in GlobalData.gModuleBuildTracking: - GlobalData.gModuleBuildTracking[Ma] = False + # Initialize all modules in tracking to 'FAIL' + if Ma.Arch not in GlobalData.gModuleBuildTracking: + GlobalData.gModuleBuildTracking[Ma.Arch] = dict() + if Ma not in GlobalData.gModuleBuildTracking[Ma.Arch]: + GlobalData.gModuleBuildTracking[Ma.Arch][Ma] = 'FAIL' self.Progress.Stop("done!") self.AutoGenTime += int(round((time.time() - AutoGenStart))) MakeStart = time.time() @@ -2099,6 +2115,7 @@ class Build(): # Save MAP buffer into MAP file. # self._SaveMapFile(MapBuffer, Wa) + self.invalidateHash() ## Generate GuidedSectionTools.txt in the FV directories. # -- 2.21.0.windows.1 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#41664): https://edk2.groups.io/g/devel/message/41664 Mute This Topic: https://groups.io/mt/31835556/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-