from Workspace.MetaFileCommentParser import UsageList\r
from Common.MultipleWorkspace import MultipleWorkspace as mws\r
import InfSectionParser\r
+import datetime\r
\r
## Regular expression for splitting Dependency Expression string into tokens\r
gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
self._MakeFileDir = None\r
self._BuildCommand = None\r
\r
+ #\r
+ # Create BuildOptions Macro & PCD metafile.\r
+ #\r
+ content = 'gCommandLineDefines: '\r
+ content += str(GlobalData.gCommandLineDefines)\r
+ content += os.linesep\r
+ content += 'BuildOptionPcd: '\r
+ content += str(GlobalData.BuildOptionPcd)\r
+ SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)\r
+\r
+ #\r
+ # Get set of workspace metafiles\r
+ #\r
+ AllWorkSpaceMetaFiles = self._GetMetaFiles(Target, Toolchain, Arch)\r
+\r
+ #\r
+ # Retrieve latest modified time of all metafiles\r
+ #\r
+ SrcTimeStamp = 0\r
+ for f in AllWorkSpaceMetaFiles:\r
+ if os.stat(f)[8] > SrcTimeStamp:\r
+ SrcTimeStamp = os.stat(f)[8]\r
+ self._SrcTimeStamp = SrcTimeStamp\r
+\r
+ #\r
+ # Write metafile list to build directory\r
+ #\r
+ AutoGenFilePath = os.path.join(self.BuildDir, 'AutoGen')\r
+ if os.path.exists (AutoGenFilePath):\r
+ os.remove(AutoGenFilePath)\r
+ if not os.path.exists(self.BuildDir):\r
+ os.makedirs(self.BuildDir)\r
+ with open(os.path.join(self.BuildDir, 'AutoGen'), 'w+') as file:\r
+ for f in AllWorkSpaceMetaFiles:\r
+ print >> file, f\r
return True\r
\r
def _BuildOptionPcdValueFormat(self, TokenSpaceGuidCName, TokenCName, PcdDatumType, Value):\r
Value = '0'\r
return Value\r
\r
+ def _GetMetaFiles(self, Target, Toolchain, Arch):\r
+ AllWorkSpaceMetaFiles = set()\r
+ #\r
+ # add fdf\r
+ #\r
+ if self.FdfFile:\r
+ AllWorkSpaceMetaFiles.add (self.FdfFile.Path)\r
+ if self.FdfFile:\r
+ FdfFiles = GlobalData.gFdfParser.GetAllIncludedFile()\r
+ for f in FdfFiles:\r
+ AllWorkSpaceMetaFiles.add (f.FileName)\r
+ #\r
+ # add dsc\r
+ #\r
+ AllWorkSpaceMetaFiles.add(self.MetaFile.Path)\r
+\r
+ #\r
+ # add BuildOption metafile\r
+ #\r
+ AllWorkSpaceMetaFiles.add(os.path.join(self.BuildDir, 'BuildOptions'))\r
+\r
+ for Arch in self.ArchList:\r
+ Platform = self.BuildDatabase[self.MetaFile, Arch, Target, Toolchain]\r
+ PGen = PlatformAutoGen(self, self.MetaFile, Target, Toolchain, Arch)\r
+\r
+ #\r
+ # add dec\r
+ #\r
+ for Package in PGen.PackageList:\r
+ AllWorkSpaceMetaFiles.add(Package.MetaFile.Path)\r
+\r
+ #\r
+ # add included dsc\r
+ #\r
+ for filePath in Platform._RawData.IncludedFiles:\r
+ AllWorkSpaceMetaFiles.add(filePath.Path)\r
+\r
+ return AllWorkSpaceMetaFiles\r
+\r
## _CheckDuplicateInFV() method\r
#\r
# Check whether there is duplicate modules/files exist in FV section. \r
# to the [depex] section in module's inf file.\r
#\r
class ModuleAutoGen(AutoGen):\r
+ ## Cache the timestamps of metafiles of every module in a class variable\r
+ #\r
+ TimeDict = {}\r
+\r
## The real constructor of ModuleAutoGen\r
#\r
# This method is not supposed to be called by users of ModuleAutoGen. It's\r
self._FinalBuildTargetList = None\r
self._FileTypes = None\r
self._BuildRules = None\r
+\r
+ self._TimeStampPath = None\r
+\r
+ self.AutoGenDepSet = set()\r
+\r
\r
## The Modules referenced to this Library\r
# Only Library has this attribute\r
\r
if self.IsMakeFileCreated:\r
return\r
+ if self.CanSkip():\r
+ return\r
\r
if not self.IsLibrary and CreateLibraryMakeFile:\r
for LibraryAutoGen in self.LibraryAutoGenList:\r
EdkLogger.debug(EdkLogger.DEBUG_9, "Skipped the generation of makefile for module %s [%s]" %\r
(self.Name, self.Arch))\r
\r
+ self.CreateTimeStamp(Makefile)\r
self.IsMakeFileCreated = True\r
\r
def CopyBinaryFiles(self):\r
def CreateCodeFile(self, CreateLibraryCodeFile=True):\r
if self.IsCodeFileCreated:\r
return\r
+ if self.CanSkip():\r
+ return\r
\r
# Need to generate PcdDatabase even PcdDriver is binarymodule\r
if self.IsBinaryModule and self.PcdIsDriver != '':\r
self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)\r
return self._LibraryAutoGenList\r
\r
+ ## Decide whether we can skip the ModuleAutoGen process\r
+ # If any source file is newer than the modeule than we cannot skip\r
+ #\r
+ def CanSkip(self):\r
+ if not os.path.exists(self.GetTimeStampPath()):\r
+ return False\r
+ #last creation time of the module\r
+ DstTimeStamp = os.stat(self.GetTimeStampPath())[8]\r
+\r
+ SrcTimeStamp = self.Workspace._SrcTimeStamp\r
+ if SrcTimeStamp > DstTimeStamp:\r
+ return False\r
+\r
+ with open(self.GetTimeStampPath(),'r') as f:\r
+ for source in f:\r
+ source = source.rstrip('\n')\r
+ if source not in ModuleAutoGen.TimeDict :\r
+ ModuleAutoGen.TimeDict[source] = os.stat(source)[8]\r
+ if ModuleAutoGen.TimeDict[source] > DstTimeStamp:\r
+ return False\r
+ return True\r
+\r
+ def GetTimeStampPath(self):\r
+ if self._TimeStampPath == None:\r
+ self._TimeStampPath = os.path.join(self.MakeFileDir, 'AutoGenTimeStamp')\r
+ return self._TimeStampPath\r
+ def CreateTimeStamp(self, Makefile):\r
+\r
+ FileSet = set()\r
+\r
+ FileSet.add (self.MetaFile.Path)\r
+\r
+ for SourceFile in self.Module.Sources:\r
+ FileSet.add (SourceFile.Path)\r
+\r
+ for Lib in self.DependentLibraryList:\r
+ FileSet.add (Lib.MetaFile.Path)\r
+\r
+ for f in self.AutoGenDepSet:\r
+ FileSet.add (f.Path)\r
+\r
+ if os.path.exists (self.GetTimeStampPath()):\r
+ os.remove (self.GetTimeStampPath())\r
+ with open(self.GetTimeStampPath(), 'w+') as file:\r
+ for f in FileSet:\r
+ print >> file, f\r
+\r
Module = property(_GetModule)\r
Name = property(_GetBaseName)\r
Guid = property(_GetGuid)\r