From: "Liming Gao" <liming.gao@intel.com>
To: "Rodriguez, Christian" <christian.rodriguez@intel.com>,
"Feng, Bob C" <bob.c.feng@intel.com>,
"devel@edk2.groups.io" <devel@edk2.groups.io>
Cc: "Zhu, Yonghong" <yonghong.zhu@intel.com>
Subject: Re: [edk2-devel] [PATCH] BaseTools: Add a checking for Sources section in INF file
Date: Fri, 24 May 2019 04:58:53 +0000 [thread overview]
Message-ID: <4A89E2EF3DFEDB4C8BFDE51014F606A14E450A09@SHSMSX104.ccr.corp.intel.com> (raw)
In-Reply-To: <3A7DCC9A944C6149BF832E1C9B718ABC01F22900@ORSMSX112.amr.corp.intel.com>
Besides, I suggest to separate the change on add new checker. Another patch is about hash logic enhancement.
Thanks
Liming
>-----Original Message-----
>From: Rodriguez, Christian
>Sent: Thursday, May 23, 2019 9:21 PM
>To: Feng, Bob C <bob.c.feng@intel.com>; devel@edk2.groups.io
>Cc: Gao, Liming <liming.gao@intel.com>; Zhu, Yonghong
><yonghong.zhu@intel.com>
>Subject: RE: [edk2-devel] [PATCH] BaseTools: Add a checking for Sources
>section in INF file
>
>Ok, I can show the build time performance impact here. Though the way I
>invalidated a module/library build is hash specific. What is the best way to
>invalidate a build in the original incremental build? Or does it matter because
>all the modules/libraries are rebuilt or checked for rebuild in the original
>incremental build?
>
>I'm guessing it's that second choice above, so I can move the conditional check
>to just the hash invalidation part and have the rest of the header source check
>always on.
>
>Thanks,
>Christian
>
>>-----Original Message-----
>>From: Feng, Bob C
>>Sent: Thursday, May 23, 2019 2:39 AM
>>To: devel@edk2.groups.io; Rodriguez, Christian
>><christian.rodriguez@intel.com>
>>Cc: Gao, Liming <liming.gao@intel.com>; Zhu, Yonghong
>><yonghong.zhu@intel.com>
>>Subject: RE: [edk2-devel] [PATCH] BaseTools: Add a checking for Sources
>>section in INF file
>>
>>Hi Christian,
>>
>>Since this is a INF spec required checking, I think the condition of this check
>>should be removed.
>>Would you show the build time to see what's the performance impact if we
>>always do this check?
>>
>>Thanks,
>>Bob
>>
>>-----Original Message-----
>>From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
>>Christian Rodriguez
>>Sent: Tuesday, May 21, 2019 10:13 PM
>>To: devel@edk2.groups.io
>>Cc: Feng, Bob C <bob.c.feng@intel.com>; Gao, Liming
>><liming.gao@intel.com>; Zhu, Yonghong <yonghong.zhu@intel.com>
>>Subject: [edk2-devel] [PATCH] BaseTools: Add a checking for Sources section
>>in INF file
>>
>>BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=1804
>>
>>In the Edk2 INF spec 3.9, it states, All HII Unicode format files must be listed
>in
>>[Sources] section. Add a check to see if [Sources] section lists all the "source"
>>type files of a module. Performance impact should be minimal with this
>patch
>>since information is already being fetched for Makefile purposes. All other
>>information is already cached in memory. No extra IO time is needed.
>>
>>Signed-off-by: Christian Rodriguez <christian.rodriguez@intel.com>
>>Cc: Bob Feng <bob.c.feng@intel.com>
>>Cc: Liming Gao <liming.gao@intel.com>
>>Cc: Yonghong Zhu <yonghong.zhu@intel.com>
>>---
>> BaseTools/Source/Python/AutoGen/AutoGen.py | 6 ++++--
>> BaseTools/Source/Python/AutoGen/GenMake.py | 45
>>+++++++++++++++++++++++++++++++++++++++++++++
>> BaseTools/Source/Python/Common/GlobalData.py | 3 ++-
>> BaseTools/Source/Python/build/build.py | 66
>>++++++++++++++++++++++++++++++++++++++++--------------------------
>> 4 files changed, 91 insertions(+), 29 deletions(-)
>>
>>diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py
>>b/BaseTools/Source/Python/AutoGen/AutoGen.py
>>index a843f294b9..0bc27fb2b3 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 0e0f9fd9b0..8765ffa188 100644
>>--- a/BaseTools/Source/Python/AutoGen/GenMake.py
>>+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
>>@@ -905,6 +905,51 @@ cleanlib:
>> ForceIncludedFile,
>> self._AutoGenObject.IncludePathList +
>>self._AutoGenObject.BuildOptionIncPathList
>> )
>>+
>>+ # Only do it during hashing feature for now to save time on clean build
>>+ # Conditional can be removed to happen on all builds for MetaFile
>>compliance
>>+ if GlobalData.gUseHashCache:
>>+ # Check if header files are listed in metafile
>>+ # Get a list of unique module header source files from MetaFile
>>+ headerFilesInMetaFileSet = set()
>>+ for aFile in self._AutoGenObject.SourceFileList:
>>+ aFileName = str(aFile)
>>+ if not aFileName.endswith('.h'):
>>+ continue
>>+ headerFilesInMetaFileSet.add(aFileName.lower())
>>+
>>+ # Get a list of unique module autogen files
>>+ localAutoGenFileSet = set()
>>+ for aFile in self._AutoGenObject.AutoGenFileList:
>>+ localAutoGenFileSet.add(str(aFile).lower())
>>+
>>+ # Get a list of unique module dependency header files
>>+ # Exclude autogen files and files not in the source directory
>>+ headerFileDependencySet = set()
>>+ localSourceDir = str(self._AutoGenObject.SourceDir).lower()
>>+ for Dependency in FileDependencyDict.values():
>>+ for aFile in Dependency:
>>+ aFileName = str(aFile).lower()
>>+ if not aFileName.endswith('.h'):
>>+ continue
>>+ if aFileName in localAutoGenFileSet:
>>+ continue
>>+ if localSourceDir not in aFileName:
>>+ 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 not in headerFilesInMetaFileSet:
>>+
>>GlobalData.gModuleBuildTracking[self._AutoGenObject.Arch][self._AutoGe
>n
>>Object] = 'FAIL_METAFILE'
>>+ EdkLogger.warn("build","Module MetaFile [Sources] is missing
>>local header!",
>>+ ExtraData = "Local Header: " + aFile + " not found in " +
>>self._AutoGenObject.MetaFile.Path
>>+ )
>>+
>> DepSet = None
>> for File,Dependency in FileDependencyDict.items():
>> if not Dependency:
>>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 027061191c..0a58dd16ef 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.Buil
>dI
>>tem.BuildObject] != 'FAIL_METAFILE' and
>>+ not BuildTask._ErrorFlag.isSet()
>>+ ):
>>+
>>GlobalData.gModuleBuildTracking[self.BuildItem.BuildObject.Arch][self.Buil
>dI
>>tem.BuildObject] = 'SUCCESS'
>>+
>> # indicate there's a thread is available for another build task
>> BuildTask._RunningQueueLock.acquire()
>> BuildTask._RunningQueue.pop(self.BuildItem)
>>@@ -1154,27 +1162,27 @@ 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
>>+ # 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][moduleAutoG
>e
>>nObj] == '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")
>>- if os.path.exists(ModuleHashFile):
>>- os.remove(ModuleHashFile)
>>+ # Remove .hash from build
>>+ if GlobalData.gUseHashCache:
>>+ 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.gUseHashCache and 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
>> #
>>@@ -1833,9 +1841,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:
>>@@ -1919,6 +1929,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) @@ -2017,9 +2028,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() @@ -2107,6 +2120,7 @@ class Build():
>> # Save MAP buffer into MAP file.
>> #
>> self._SaveMapFile(MapBuffer, Wa)
>>+ self.invalidateHash()
>>
>> ## Generate GuidedSectionTools.txt in the FV directories.
>> #
>>--
>>2.19.1.windows.1
>>
>>
>>
prev parent reply other threads:[~2019-05-24 4:58 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-05-21 14:13 [PATCH] BaseTools: Add a checking for Sources section in INF file Christian Rodriguez
2019-05-23 9:39 ` [edk2-devel] " Bob Feng
2019-05-23 13:21 ` Christian Rodriguez
2019-05-24 4:58 ` Liming Gao [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4A89E2EF3DFEDB4C8BFDE51014F606A14E450A09@SHSMSX104.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox