summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--BaseTools/Source/Python/AutoGen/AutoGen.py136
-rw-r--r--BaseTools/Source/Python/AutoGen/GenMake.py3
-rw-r--r--BaseTools/Source/Python/GenFds/FdfParser.py4
-rw-r--r--BaseTools/Source/Python/Workspace/MetaFileParser.py4
4 files changed, 147 insertions, 0 deletions
diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py b/BaseTools/Source/Python/AutoGen/AutoGen.py
index 06e674a..70c6c91 100644
--- a/BaseTools/Source/Python/AutoGen/AutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/AutoGen.py
@@ -42,6 +42,7 @@ from GenPcdDb import CreatePcdDatabaseCode
from Workspace.MetaFileCommentParser import UsageList
from Common.MultipleWorkspace import MultipleWorkspace as mws
import InfSectionParser
+import datetime
## Regular expression for splitting Dependency Expression string into tokens
gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")
@@ -640,6 +641,41 @@ class WorkspaceAutoGen(AutoGen):
self._MakeFileDir = None
self._BuildCommand = None
+ #
+ # Create BuildOptions Macro & PCD metafile.
+ #
+ content = 'gCommandLineDefines: '
+ content += str(GlobalData.gCommandLineDefines)
+ content += os.linesep
+ content += 'BuildOptionPcd: '
+ content += str(GlobalData.BuildOptionPcd)
+ SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)
+
+ #
+ # Get set of workspace metafiles
+ #
+ AllWorkSpaceMetaFiles = self._GetMetaFiles(Target, Toolchain, Arch)
+
+ #
+ # Retrieve latest modified time of all metafiles
+ #
+ SrcTimeStamp = 0
+ for f in AllWorkSpaceMetaFiles:
+ if os.stat(f)[8] > SrcTimeStamp:
+ SrcTimeStamp = os.stat(f)[8]
+ self._SrcTimeStamp = SrcTimeStamp
+
+ #
+ # Write metafile list to build directory
+ #
+ AutoGenFilePath = os.path.join(self.BuildDir, 'AutoGen')
+ if os.path.exists (AutoGenFilePath):
+ os.remove(AutoGenFilePath)
+ if not os.path.exists(self.BuildDir):
+ os.makedirs(self.BuildDir)
+ with open(os.path.join(self.BuildDir, 'AutoGen'), 'w+') as file:
+ for f in AllWorkSpaceMetaFiles:
+ print >> file, f
return True
def _BuildOptionPcdValueFormat(self, TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):
@@ -668,6 +704,45 @@ class WorkspaceAutoGen(AutoGen):
Value = '0'
return Value
+ def _GetMetaFiles(self, Target, Toolchain, Arch):
+ AllWorkSpaceMetaFiles = set()
+ #
+ # add fdf
+ #
+ if self.FdfFile:
+ AllWorkSpaceMetaFiles.add (self.FdfFile.Path)
+ if self.FdfFile:
+ FdfFiles = GlobalData.gFdfParser.GetAllIncludedFile()
+ for f in FdfFiles:
+ AllWorkSpaceMetaFiles.add (f.FileName)
+ #
+ # add dsc
+ #
+ AllWorkSpaceMetaFiles.add(self.MetaFile.Path)
+
+ #
+ # add BuildOption metafile
+ #
+ AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'BuildOptions'))
+
+ for Arch in self.ArchList:
+ Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]
+ PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)
+
+ #
+ # add dec
+ #
+ for Package in PGen.PackageList:
+ AllWorkSpaceMetaFiles.add(Package.MetaFile.Path)
+
+ #
+ # add included dsc
+ #
+ for filePath in Platform._RawData.IncludedFiles:
+ AllWorkSpaceMetaFiles.add(filePath.Path)
+
+ return AllWorkSpaceMetaFiles
+
## _CheckDuplicateInFV() method
#
# Check whether there is duplicate modules/files exist in FV section.
@@ -2532,6 +2607,10 @@ class PlatformAutoGen(AutoGen):
# to the [depex] section in module's inf file.
#
class ModuleAutoGen(AutoGen):
+ ## Cache the timestamps of metafiles of every module in a class variable
+ #
+ TimeDict = {}
+
## The real constructor of ModuleAutoGen
#
# This method is not supposed to be called by users of ModuleAutoGen. It's
@@ -2632,6 +2711,11 @@ class ModuleAutoGen(AutoGen):
self._FinalBuildTargetList = None
self._FileTypes = None
self._BuildRules = None
+
+ self._TimeStampPath = None
+
+ self.AutoGenDepSet = set()
+
## The Modules referenced to this Library
# Only Library has this attribute
@@ -3968,6 +4052,8 @@ class ModuleAutoGen(AutoGen):
if self.IsMakeFileCreated:
return
+ if self.CanSkip():
+ return
if not self.IsLibrary and CreateLibraryMakeFile:
for LibraryAutoGen in self.LibraryAutoGenList:
@@ -3984,6 +4070,7 @@ class ModuleAutoGen(AutoGen):
EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %
(self.Name, self.Arch))
+ self.CreateTimeStamp(Makefile)
self.IsMakeFileCreated = True
def CopyBinaryFiles(self):
@@ -3999,6 +4086,8 @@ class ModuleAutoGen(AutoGen):
def CreateCodeFile(self, CreateLibraryCodeFile=True):
if self.IsCodeFileCreated:
return
+ if self.CanSkip():
+ return
# Need to generate PcdDatabase even PcdDriver is binarymodule
if self.IsBinaryModule and self.PcdIsDriver != '':
@@ -4078,6 +4167,53 @@ class ModuleAutoGen(AutoGen):
self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)
return self._LibraryAutoGenList
+ ## Decide whether we can skip the ModuleAutoGen process
+ # If any source file is newer than the modeule than we cannot skip
+ #
+ def CanSkip(self):
+ if not os.path.exists(self.GetTimeStampPath()):
+ return False
+ #last creation time of the module
+ DstTimeStamp = os.stat(self.GetTimeStampPath())[8]
+
+ SrcTimeStamp = self.Workspace._SrcTimeStamp
+ if SrcTimeStamp > DstTimeStamp:
+ return False
+
+ with open(self.GetTimeStampPath(),'r') as f:
+ for source in f:
+ source = source.rstrip('\n')
+ if source not in ModuleAutoGen.TimeDict :
+ ModuleAutoGen.TimeDict[source] = os.stat(source)[8]
+ if ModuleAutoGen.TimeDict[source] > DstTimeStamp:
+ return False
+ return True
+
+ def GetTimeStampPath(self):
+ if self._TimeStampPath == None:
+ self._TimeStampPath = os.path.join(self.MakeFileDir, 'AutoGenTimeStamp')
+ return self._TimeStampPath
+ def CreateTimeStamp(self, Makefile):
+
+ FileSet = set()
+
+ FileSet.add (self.MetaFile.Path)
+
+ for SourceFile in self.Module.Sources:
+ FileSet.add (SourceFile.Path)
+
+ for Lib in self.DependentLibraryList:
+ FileSet.add (Lib.MetaFile.Path)
+
+ for f in self.AutoGenDepSet:
+ FileSet.add (f.Path)
+
+ if os.path.exists (self.GetTimeStampPath()):
+ os.remove (self.GetTimeStampPath())
+ with open(self.GetTimeStampPath(), 'w+') as file:
+ for f in FileSet:
+ print >> file, f
+
Module = property(_GetModule)
Name = property(_GetBaseName)
Guid = property(_GetGuid)
diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index 51c5238..ea07b97 100644
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -801,6 +801,9 @@ cleanlib:
if not self.FileDependency[File]:
self.FileDependency[File] = ['$(FORCE_REBUILD)']
continue
+
+ self._AutoGenObject.AutoGenDepSet |= set(self.FileDependency[File])
+
# skip non-C files
if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":
continue
diff --git a/BaseTools/Source/Python/GenFds/FdfParser.py b/BaseTools/Source/Python/GenFds/FdfParser.py
index 27688e2..a1825ba 100644
--- a/BaseTools/Source/Python/GenFds/FdfParser.py
+++ b/BaseTools/Source/Python/GenFds/FdfParser.py
@@ -4797,6 +4797,10 @@ class FdfParser:
return False
+ def GetAllIncludedFile (self):
+ global AllIncludeFileList
+ return AllIncludeFileList
+
if __name__ == "__main__":
import sys
try:
diff --git a/BaseTools/Source/Python/Workspace/MetaFileParser.py b/BaseTools/Source/Python/Workspace/MetaFileParser.py
index 37a7f5d..d094403 100644
--- a/BaseTools/Source/Python/Workspace/MetaFileParser.py
+++ b/BaseTools/Source/Python/Workspace/MetaFileParser.py
@@ -859,6 +859,8 @@ class DscParser(MetaFileParser):
SymbolPattern = ValueExpression.SymbolPattern
+ IncludedFiles = set()
+
## Constructor of DscParser
#
# Initialize object of DscParser
@@ -1501,6 +1503,8 @@ class DscParser(MetaFileParser):
Parser = DscParser(IncludedFile1, self._FileType, self._Arch, IncludedFileTable,
Owner=Owner, From=Owner)
+ self.IncludedFiles.add (IncludedFile1)
+
# Does not allow lower level included file to include upper level included file
if Parser._From != Owner and int(Owner) > int (Parser._From):
EdkLogger.error('parser', FILE_ALREADY_EXIST, File=self._FileWithError,