]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/AutoGen/AutoGen.py
MdeModulePkg/Core/Dxe: Remove extra connects for UEFI Applications
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / AutoGen.py
index 70e2e62057c1d37451779388462c2310680f59fa..5317921cbe20cb2f184066fefa23f51661d43759 100644 (file)
@@ -43,6 +43,7 @@ from Workspace.MetaFileCommentParser import UsageList
 from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 import InfSectionParser\r
 import datetime\r
+import hashlib\r
 \r
 ## Regular expression for splitting Dependency Expression string into tokens\r
 gDepexTokenPattern = re.compile("(\(|\)|\w+| \S+\.inf)")\r
@@ -265,6 +266,10 @@ class WorkspaceAutoGen(AutoGen):
         self.FvTargetList   = Fvs\r
         self.CapTargetList  = Caps\r
         self.AutoGenObjectList = []\r
+        self._BuildDir      = None\r
+        self._FvDir         = None\r
+        self._MakeFileDir   = None\r
+        self._BuildCommand  = None\r
 \r
         # there's many relative directory operations, so ...\r
         os.chdir(self.WorkspaceDir)\r
@@ -644,6 +649,14 @@ class WorkspaceAutoGen(AutoGen):
             Pa.CollectFixedAtBuildPcds()\r
             self.AutoGenObjectList.append(Pa)\r
 \r
+            #\r
+            # Generate Package level hash value\r
+            #\r
+            GlobalData.gPackageHash[Arch] = {}\r
+            if GlobalData.gUseHashCache:\r
+                for Pkg in Pkgs:\r
+                    self._GenPkgLevelHash(Pkg)\r
+\r
         #\r
         # Check PCDs token value conflict in each DEC file.\r
         #\r
@@ -657,11 +670,6 @@ class WorkspaceAutoGen(AutoGen):
 #         if self.FdfFile:\r
 #             self._CheckDuplicateInFV(Fdf)\r
 \r
-        self._BuildDir = None\r
-        self._FvDir = None\r
-        self._MakeFileDir = None\r
-        self._BuildCommand = None\r
-\r
         #\r
         # Create BuildOptions Macro & PCD metafile, also add the Active Platform and FDF file.\r
         #\r
@@ -677,6 +685,10 @@ class WorkspaceAutoGen(AutoGen):
         if self.FdfFile:\r
             content += 'Flash Image Definition: '\r
             content += str(self.FdfFile)\r
+            content += os.linesep\r
+        if GlobalData.gBinCacheDest:\r
+            content += 'Cache of .efi location: '\r
+            content += str(GlobalData.gBinCacheDest)\r
         SaveFileOnChange(os.path.join(self.BuildDir, 'BuildOptions'), content, False)\r
 \r
         #\r
@@ -706,6 +718,18 @@ class WorkspaceAutoGen(AutoGen):
                 SrcTimeStamp = os.stat(f)[8]\r
         self._SrcTimeStamp = SrcTimeStamp\r
 \r
+        if GlobalData.gUseHashCache:\r
+            m = hashlib.md5()\r
+            for files in AllWorkSpaceMetaFiles:\r
+                if files.endswith('.dec'):\r
+                    continue\r
+                f = open(files, 'r')\r
+                Content = f.read()\r
+                f.close()\r
+                m.update(Content)\r
+            SaveFileOnChange(os.path.join(self.BuildDir, 'AutoGen.hash'), m.hexdigest(), True)\r
+            GlobalData.gPlatformHash = m.hexdigest()\r
+\r
         #\r
         # Write metafile list to build directory\r
         #\r
@@ -719,6 +743,29 @@ class WorkspaceAutoGen(AutoGen):
                 print >> file, f\r
         return True\r
 \r
+    def _GenPkgLevelHash(self, Pkg):\r
+        PkgDir = os.path.join(self.BuildDir, Pkg.Arch, Pkg.PackageName)\r
+        CreateDirectory(PkgDir)\r
+        HashFile = os.path.join(PkgDir, Pkg.PackageName + '.hash')\r
+        m = hashlib.md5()\r
+        # Get .dec file's hash value\r
+        f = open(Pkg.MetaFile.Path, 'r')\r
+        Content = f.read()\r
+        f.close()\r
+        m.update(Content)\r
+        # Get include files hash value\r
+        if Pkg.Includes:\r
+            for inc in Pkg.Includes:\r
+                for Root, Dirs, Files in os.walk(str(inc)):\r
+                    for File in Files:\r
+                        File_Path = os.path.join(Root, File)\r
+                        f = open(File_Path, 'r')\r
+                        Content = f.read()\r
+                        f.close()\r
+                        m.update(Content)\r
+        SaveFileOnChange(HashFile, m.hexdigest(), True)\r
+        if Pkg.PackageName not in GlobalData.gPackageHash[Pkg.Arch]:\r
+            GlobalData.gPackageHash[Pkg.Arch][Pkg.PackageName] = m.hexdigest()\r
 \r
     def _GetMetaFiles(self, Target, Toolchain, Arch):\r
         AllWorkSpaceMetaFiles = set()\r
@@ -956,7 +1003,8 @@ class WorkspaceAutoGen(AutoGen):
 \r
     ## Return the directory to store all intermediate and final files built\r
     def _GetBuildDir(self):\r
-        return self.AutoGenObjectList[0].BuildDir\r
+        if self._BuildDir == None:\r
+            return self.AutoGenObjectList[0].BuildDir\r
 \r
     ## Return the build output directory platform specifies\r
     def _GetOutputDir(self):\r
@@ -1750,6 +1798,7 @@ class PlatformAutoGen(AutoGen):
                                             self.OutputDir,\r
                                             self.BuildTarget + "_" + self.ToolChain,\r
                                             )\r
+            GlobalData.gBuildDirectory = self._BuildDir\r
         return self._BuildDir\r
 \r
     ## Return directory of platform makefile\r
@@ -2335,8 +2384,18 @@ class PlatformAutoGen(AutoGen):
         if Module in self.Platform.Modules:\r
             PlatformModule = self.Platform.Modules[str(Module)]\r
             for Key  in PlatformModule.Pcds:\r
+                Flag = False\r
                 if Key in Pcds:\r
-                    self._OverridePcd(Pcds[Key], PlatformModule.Pcds[Key], Module)\r
+                    ToPcd = Pcds[Key]\r
+                    Flag = True\r
+                elif Key in GlobalData.MixedPcd:\r
+                    for PcdItem in GlobalData.MixedPcd[Key]:\r
+                        if PcdItem in Pcds:\r
+                            ToPcd = Pcds[PcdItem]\r
+                            Flag = True\r
+                            break\r
+                if Flag:\r
+                    self._OverridePcd(ToPcd, PlatformModule.Pcds[Key], Module)\r
         return Pcds.values()\r
 \r
     ## Resolve library names to library modules\r
@@ -2685,6 +2744,7 @@ class ModuleAutoGen(AutoGen):
 \r
         self.BuildDatabase = self.Workspace.BuildDatabase\r
         self.BuildRuleOrder = None\r
+        self.BuildTime      = 0\r
 \r
         self._Module          = None\r
         self._Name            = None\r
@@ -3900,9 +3960,11 @@ class ModuleAutoGen(AutoGen):
             AsBuiltInfDict['module_pi_specification_version'] += [self.Specification['PI_SPECIFICATION_VERSION']]\r
 \r
         OutputDir = self.OutputDir.replace('\\', '/').strip('/')\r
-\r
+        self.OutputFile = []\r
         for Item in self.CodaTargetList:\r
             File = Item.Target.Path.replace('\\', '/').strip('/').replace(OutputDir, '').strip('/')\r
+            if File not in self.OutputFile:\r
+                self.OutputFile.append(File)\r
             if Item.Target.Ext.lower() == '.aml':\r
                 AsBuiltInfDict['binary_item'] += ['ASL|' + File]\r
             elif Item.Target.Ext.lower() == '.acpi':\r
@@ -3912,6 +3974,8 @@ class ModuleAutoGen(AutoGen):
             else:\r
                 AsBuiltInfDict['binary_item'] += ['BIN|' + File]\r
         if self.DepexGenerated:\r
+            if self.Name + '.depex' not in self.OutputFile:\r
+                self.OutputFile.append(self.Name + '.depex')\r
             if self.ModuleType in ['PEIM']:\r
                 AsBuiltInfDict['binary_item'] += ['PEI_DEPEX|' + self.Name + '.depex']\r
             if self.ModuleType in ['DXE_DRIVER', 'DXE_RUNTIME_DRIVER', 'DXE_SAL_DRIVER', 'UEFI_DRIVER']:\r
@@ -3922,11 +3986,15 @@ class ModuleAutoGen(AutoGen):
         Bin = self._GenOffsetBin()\r
         if Bin:\r
             AsBuiltInfDict['binary_item'] += ['BIN|%s' % Bin]\r
+            if Bin not in self.OutputFile:\r
+                self.OutputFile.append(Bin)\r
 \r
         for Root, Dirs, Files in os.walk(OutputDir):\r
             for File in Files:\r
                 if File.lower().endswith('.pdb'):\r
                     AsBuiltInfDict['binary_item'] += ['DISPOSABLE|' + File]\r
+                    if File not in self.OutputFile:\r
+                        self.OutputFile.append(File)\r
         HeaderComments = self.Module.HeaderComments\r
         StartPos = 0\r
         for Index in range(len(HeaderComments)):\r
@@ -4107,7 +4175,48 @@ class ModuleAutoGen(AutoGen):
         SaveFileOnChange(os.path.join(self.OutputDir, self.Name + '.inf'), str(AsBuiltInf), False)\r
         \r
         self.IsAsBuiltInfCreated = True\r
-        \r
+        if GlobalData.gBinCacheDest:\r
+            self.CopyModuleToCache()\r
+\r
+    def CopyModuleToCache(self):\r
+        FileDir = path.join(GlobalData.gBinCacheDest, self.Arch, self.SourceDir, self.MetaFile.BaseName)\r
+        CreateDirectory (FileDir)\r
+        HashFile = path.join(self.BuildDir, self.Name + '.hash')\r
+        ModuleFile = path.join(self.OutputDir, self.Name + '.inf')\r
+        if os.path.exists(HashFile):\r
+            shutil.copy2(HashFile, FileDir)\r
+        if os.path.exists(ModuleFile):\r
+            shutil.copy2(ModuleFile, FileDir)\r
+        if self.OutputFile:\r
+            for File in self.OutputFile:\r
+                if not os.path.isabs(File):\r
+                    File = os.path.join(self.OutputDir, File)\r
+                if os.path.exists(File):\r
+                    shutil.copy2(File, FileDir)\r
+\r
+    def AttemptModuleCacheCopy(self):\r
+        if self.IsBinaryModule:\r
+            return False\r
+        FileDir = path.join(GlobalData.gBinCacheSource, self.Arch, self.SourceDir, self.MetaFile.BaseName)\r
+        HashFile = path.join(FileDir, self.Name + '.hash')\r
+        if os.path.exists(HashFile):\r
+            f = open(HashFile, 'r')\r
+            CacheHash = f.read()\r
+            f.close()\r
+            if GlobalData.gModuleHash[self.Arch][self.Name]:\r
+                if CacheHash == GlobalData.gModuleHash[self.Arch][self.Name]:\r
+                    for root, dir, files in os.walk(FileDir):\r
+                        for f in files:\r
+                            if self.Name + '.hash' in f:\r
+                                shutil.copy2(HashFile, self.BuildDir)\r
+                            else:\r
+                                File = path.join(root, f)\r
+                                shutil.copy2(File, self.OutputDir)\r
+                    if self.Name == "PcdPeim" or self.Name == "PcdDxe":\r
+                        CreatePcdDatabaseCode(self, TemplateString(), TemplateString())\r
+                    return True\r
+        return False\r
+\r
     ## Create makefile for the module and its dependent libraries\r
     #\r
     #   @param      CreateLibraryMakeFile   Flag indicating if or not the makefiles of\r
@@ -4235,8 +4344,54 @@ class ModuleAutoGen(AutoGen):
                         self._ApplyBuildRule(Lib.Target, TAB_UNKNOWN_FILE)\r
         return self._LibraryAutoGenList\r
 \r
+    def GenModuleHash(self):\r
+        if self.Arch not in GlobalData.gModuleHash:\r
+            GlobalData.gModuleHash[self.Arch] = {}\r
+        m = hashlib.md5()\r
+        # Add Platform level hash\r
+        m.update(GlobalData.gPlatformHash)\r
+        # Add Package level hash\r
+        if self.DependentPackageList:\r
+            for Pkg in self.DependentPackageList:\r
+                if Pkg.PackageName in GlobalData.gPackageHash[self.Arch]:\r
+                    m.update(GlobalData.gPackageHash[self.Arch][Pkg.PackageName])\r
+\r
+        # Add Library hash\r
+        if self.LibraryAutoGenList:\r
+            for Lib in self.LibraryAutoGenList:\r
+                if Lib.Name not in GlobalData.gModuleHash[self.Arch]:\r
+                    Lib.GenModuleHash()\r
+                m.update(GlobalData.gModuleHash[self.Arch][Lib.Name])\r
+\r
+        # Add Module self\r
+        f = open(str(self.MetaFile), 'r')\r
+        Content = f.read()\r
+        f.close()\r
+        m.update(Content)\r
+        # Add Module's source files\r
+        if self.SourceFileList:\r
+            for File in self.SourceFileList:\r
+                f = open(str(File), 'r')\r
+                Content = f.read()\r
+                f.close()\r
+                m.update(Content)\r
+\r
+        ModuleHashFile = path.join(self.BuildDir, self.Name + ".hash")\r
+        if self.Name not in GlobalData.gModuleHash[self.Arch]:\r
+            GlobalData.gModuleHash[self.Arch][self.Name] = m.hexdigest()\r
+        if GlobalData.gBinCacheSource:\r
+            CacheValid = self.AttemptModuleCacheCopy()\r
+            if CacheValid:\r
+                return False\r
+        return SaveFileOnChange(ModuleHashFile, m.hexdigest(), True)\r
+\r
+    ## Decide whether we can skip the ModuleAutoGen process\r
+    def CanSkipbyHash(self):\r
+        if GlobalData.gUseHashCache:\r
+            return not self.GenModuleHash()\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
+    #  If any source file is newer than the module than we cannot skip\r
     #\r
     def CanSkip(self):\r
         if not os.path.exists(self.GetTimeStampPath()):\r