]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/Workspace/WorkspaceDatabase.py
BaseTools: Add support to merge Prebuild and Postbuild into build Process
[mirror_edk2.git] / BaseTools / Source / Python / Workspace / WorkspaceDatabase.py
index 14cd22d064113e3eea5506f6dadf4b5a20401d11..b2c4d6e4dafbf7657b2ef202eaebb0b9adbdc3f1 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # This file is used to create a database used by build tool\r
 #\r
-# Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2008 - 2016, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -21,6 +21,7 @@ import uuid
 \r
 import Common.EdkLogger as EdkLogger\r
 import Common.GlobalData as GlobalData\r
+from Common.MultipleWorkspace import MultipleWorkspace as mws\r
 \r
 from Common.String import *\r
 from Common.DataType import *\r
@@ -136,6 +137,8 @@ class DscBuildData(PlatformBuildClassObject):
         self._PcdInfoFlag       = None\r
         self._VarCheckFlag = None\r
         self._FlashDefinition   = None\r
+        self._Prebuild          = None\r
+        self._Postbuild         = None\r
         self._BuildNumber       = None\r
         self._MakefileName      = None\r
         self._BsBaseAddress     = None\r
@@ -147,6 +150,7 @@ class DscBuildData(PlatformBuildClassObject):
         self._Pcds              = None\r
         self._DecPcds           = None\r
         self._BuildOptions      = None\r
+        self._ModuleTypeOptions = None\r
         self._LoadFixAddress    = None\r
         self._RFCLanguages      = None\r
         self._ISOLanguages      = None\r
@@ -165,7 +169,7 @@ class DscBuildData(PlatformBuildClassObject):
             ModuleFile = PathClass(NormPath(Record[0]), GlobalData.gWorkspace, Arch=self._Arch)\r
             RecordList = self._RawData[MODEL_META_DATA_COMPONENT_SOURCE_OVERRIDE_PATH, self._Arch, None, ModuleId]\r
             if RecordList != []:\r
-                SourceOverridePath = os.path.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))\r
+                SourceOverridePath = mws.join(GlobalData.gWorkspace, NormPath(RecordList[0][0]))\r
 \r
                 # Check if the source override path exists\r
                 if not os.path.isdir(SourceOverridePath):\r
@@ -225,6 +229,10 @@ class DscBuildData(PlatformBuildClassObject):
                 if ErrorCode != 0:\r
                     EdkLogger.error('build', ErrorCode, File=self.MetaFile, Line=Record[-1],\r
                                     ExtraData=ErrorInfo)\r
+            elif Name == TAB_DSC_PREBUILD:\r
+                self._Prebuild = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
+            elif Name == TAB_DSC_POSTBUILD:\r
+                self._Postbuild = PathClass(NormPath(Record[2], self._Macros), GlobalData.gWorkspace)\r
             elif Name == TAB_DSC_DEFINES_SUPPORTED_ARCHITECTURES:\r
                 self._SupArchList = GetSplitValueList(Record[2], TAB_VALUE_SPLIT)\r
             elif Name == TAB_DSC_DEFINES_BUILD_TARGETS:\r
@@ -397,6 +405,22 @@ class DscBuildData(PlatformBuildClassObject):
                 self._FlashDefinition = ''\r
         return self._FlashDefinition\r
 \r
+    def _GetPrebuild(self):\r
+        if self._Prebuild == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Prebuild == None:\r
+                self._Prebuild = ''\r
+        return self._Prebuild\r
+\r
+    def _GetPostbuild(self):\r
+        if self._Postbuild == None:\r
+            if self._Header == None:\r
+                self._GetHeaderInfo()\r
+            if self._Postbuild == None:\r
+                self._Postbuild = ''\r
+        return self._Postbuild\r
+\r
     ## Retrieve FLASH_DEFINITION\r
     def _GetBuildNumber(self):\r
         if self._BuildNumber == None:\r
@@ -754,19 +778,38 @@ class DscBuildData(PlatformBuildClassObject):
         if self._BuildOptions == None:\r
             self._BuildOptions = sdict()\r
             #\r
-            # Retrieve build option for EDKII style module\r
-            #\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDKII_NAME]\r
-            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                self._BuildOptions[ToolChainFamily, ToolChain, EDKII_NAME] = Option\r
-            #\r
-            # Retrieve build option for EDK style module\r
+            # Retrieve build option for EDKII and EDK style module\r
             #\r
-            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, EDK_NAME]     \r
-            for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
-                self._BuildOptions[ToolChainFamily, ToolChain, EDK_NAME] = Option\r
+            for CodeBase in (EDKII_NAME, EDK_NAME):\r
+                RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, CodeBase]\r
+                for ToolChainFamily, ToolChain, Option, Dummy1, Dummy2, Dummy3, Dummy4 in RecordList:\r
+                    CurKey = (ToolChainFamily, ToolChain, CodeBase)\r
+                    #\r
+                    # Only flags can be appended\r
+                    #\r
+                    if CurKey not in self._BuildOptions or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
+                        self._BuildOptions[CurKey] = Option\r
+                    else:\r
+                        self._BuildOptions[CurKey] += ' ' + Option\r
         return self._BuildOptions\r
 \r
+    def GetBuildOptionsByModuleType(self, Edk, ModuleType):\r
+        if self._ModuleTypeOptions == None:\r
+            self._ModuleTypeOptions = sdict()\r
+        if (Edk, ModuleType) not in self._ModuleTypeOptions:\r
+            options = sdict()\r
+            self._ModuleTypeOptions[Edk, ModuleType] = options\r
+            DriverType = '%s.%s' % (Edk, ModuleType)\r
+            RecordList = self._RawData[MODEL_META_DATA_BUILD_OPTION, self._Arch, DriverType]\r
+            for ToolChainFamily, ToolChain, Option, Arch, Type, Dummy3, Dummy4 in RecordList:\r
+                if Type == DriverType:\r
+                    Key = (ToolChainFamily, ToolChain, Edk)\r
+                    if Key not in options or not ToolChain.endswith('_FLAGS') or Option.startswith('='):\r
+                        options[Key] = Option\r
+                    else:\r
+                        options[Key] += ' ' + Option\r
+        return self._ModuleTypeOptions[Edk, ModuleType]\r
+\r
     ## Retrieve non-dynamic PCD settings\r
     #\r
     #   @param  Type    PCD type\r
@@ -1116,7 +1159,7 @@ class DscBuildData(PlatformBuildClassObject):
                                                 TokenSpaceGuid,\r
                                                 self._PCD_TYPE_STRING_[Type],\r
                                                 '',\r
-                                                '',\r
+                                                InitialValue,\r
                                                 '',\r
                                                 MaxDatumSize,\r
                                                 {SkuName : SkuInfo},\r
@@ -1186,6 +1229,8 @@ class DscBuildData(PlatformBuildClassObject):
     PcdInfoFlag         = property(_GetPcdInfoFlag)\r
     VarCheckFlag = property(_GetVarCheckFlag)\r
     FlashDefinition     = property(_GetFdfFile)\r
+    Prebuild            = property(_GetPrebuild)\r
+    Postbuild           = property(_GetPostbuild)\r
     BuildNumber         = property(_GetBuildNumber)\r
     MakefileName        = property(_GetMakefileName)\r
     BsBaseAddress       = property(_GetBsBaseAddress)\r
@@ -1842,11 +1887,11 @@ class InfBuildData(ModuleBuildClassObject):
                         LineNo = Record[6]\r
                         break\r
                 EdkLogger.error("build", FORMAT_NOT_SUPPORTED,\r
-                                "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType,' '.join(l for l in SUP_MODULE_LIST)), \r
+                                "MODULE_TYPE %s is not supported for EDK II, valid values are:\n %s" % (self._ModuleType, ' '.join(l for l in SUP_MODULE_LIST)),\r
                                 File=self.MetaFile, Line=LineNo)\r
             if (self._Specification == None) or (not 'PI_SPECIFICATION_VERSION' in self._Specification) or (int(self._Specification['PI_SPECIFICATION_VERSION'], 16) < 0x0001000A):\r
                 if self._ModuleType == SUP_MODULE_SMM_CORE:\r
-                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)                \r
+                    EdkLogger.error("build", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.MetaFile)\r
             if self._Defs and 'PCI_DEVICE_ID' in self._Defs and 'PCI_VENDOR_ID' in self._Defs \\r
                and 'PCI_CLASS_CODE' in self._Defs:\r
                 self._BuildType = 'UEFI_OPTIONROM'\r
@@ -1855,7 +1900,7 @@ class InfBuildData(ModuleBuildClassObject):
                 self._BuildType = 'UEFI_HII'\r
             else:\r
                 self._BuildType = self._ModuleType.upper()\r
-            \r
+\r
             if self._DxsFile:\r
                 File = PathClass(NormPath(self._DxsFile), self._ModuleDir, Arch=self._Arch)\r
                 # check the file validation\r
@@ -1870,7 +1915,7 @@ class InfBuildData(ModuleBuildClassObject):
             if not self._ComponentType:\r
                 EdkLogger.error("build", ATTRIBUTE_NOT_AVAILABLE,\r
                                 "COMPONENT_TYPE is not given", File=self.MetaFile)\r
-            self._BuildType = self._ComponentType.upper()                \r
+            self._BuildType = self._ComponentType.upper()\r
             if self._ComponentType in self._MODULE_TYPE_:\r
                 self._ModuleType = self._MODULE_TYPE_[self._ComponentType]\r
             if self._ComponentType == 'LIBRARY':\r
@@ -1880,7 +1925,7 @@ class InfBuildData(ModuleBuildClassObject):
             Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
             Macros['PROCESSOR'] = self._Arch\r
             RecordList = self._RawData[MODEL_META_DATA_NMAKE, self._Arch, self._Platform]\r
-            for Name,Value,Dummy,Arch,Platform,ID,LineNo in RecordList:\r
+            for Name, Value, Dummy, Arch, Platform, ID, LineNo in RecordList:\r
                 Value = ReplaceMacro(Value, Macros, True)\r
                 if Name == "IMAGE_ENTRY_POINT":\r
                     if self._ModuleEntryPointList == None:\r
@@ -1934,7 +1979,13 @@ class InfBuildData(ModuleBuildClassObject):
             RecordList = self._RawData[MODEL_META_DATA_HEADER, self._Arch, self._Platform]\r
             for Record in RecordList:\r
                 if Record[1] == TAB_INF_DEFINES_INF_VERSION:\r
-                    self._AutoGenVersion = int(Record[2], 0)\r
+                    if '.' in Record[2]:\r
+                        ValueList = Record[2].split('.')\r
+                        Major = '%04o' % int(ValueList[0], 0)\r
+                        Minor = '%04o' % int(ValueList[1], 0)\r
+                        self._AutoGenVersion = int('0x' + Major + Minor, 0)\r
+                    else:\r
+                        self._AutoGenVersion = int(Record[2], 0)\r
                     break\r
             if self._AutoGenVersion == None:\r
                 self._AutoGenVersion = 0x00010000\r
@@ -1993,7 +2044,7 @@ class InfBuildData(ModuleBuildClassObject):
             if self._Header_ == None:\r
                 self._GetHeaderInfo()\r
             if self._Guid == None:\r
-                self._Guid = '00000000-0000-0000-000000000000'\r
+                self._Guid = '00000000-0000-0000-0000-000000000000'\r
         return self._Guid\r
 \r
     ## Retrieve module version\r
@@ -2159,8 +2210,11 @@ class InfBuildData(ModuleBuildClassObject):
                 if self.AutoGenVersion < 0x00010005:\r
                     Macros["EDK_SOURCE"] = GlobalData.gEcpSource\r
                     Macros['PROCESSOR'] = self._Arch\r
+                    SourceFile = NormPath(Record[0], Macros)\r
+                    if SourceFile[0] == os.path.sep:\r
+                        SourceFile = mws.join(GlobalData.gWorkspace, SourceFile[1:])\r
                     # old module source files (Edk)\r
-                    File = PathClass(NormPath(Record[0], Macros), self._ModuleDir, self._SourceOverridePath,\r
+                    File = PathClass(SourceFile, self._ModuleDir, self._SourceOverridePath,\r
                                      '', False, self._Arch, ToolChainFamily, '', TagName, ToolCode)\r
                     # check the file validation\r
                     ErrorCode, ErrorInfo = File.Validate(CaseSensitive=False)\r
@@ -2323,10 +2377,21 @@ class InfBuildData(ModuleBuildClassObject):
                     if File[0] == '.':\r
                         File = os.path.join(self._ModuleDir, File)\r
                     else:\r
-                        File = os.path.join(GlobalData.gWorkspace, File)\r
+                        File = mws.join(GlobalData.gWorkspace, File)\r
                     File = RealPath(os.path.normpath(File))\r
                     if File:\r
                         self._Includes.append(File)\r
+                    if not File and Record[0].find('EFI_SOURCE') > -1:\r
+                        # tricky to regard WorkSpace as EFI_SOURCE\r
+                        Macros['EFI_SOURCE'] = GlobalData.gWorkspace\r
+                        File = NormPath(Record[0], Macros)\r
+                        if File[0] == '.':\r
+                            File = os.path.join(self._ModuleDir, File)\r
+                        else:\r
+                            File = os.path.join(GlobalData.gWorkspace, File)\r
+                        File = RealPath(os.path.normpath(File))\r
+                        if File:\r
+                            self._Includes.append(File)\r
         return self._Includes\r
 \r
     ## Retrieve packages this module depends on\r
@@ -2373,7 +2438,7 @@ class InfBuildData(ModuleBuildClassObject):
                 ToolChainFamily = Record[0]\r
                 ToolChain = Record[1]\r
                 Option = Record[2]\r
-                if (ToolChainFamily, ToolChain) not in self._BuildOptions:\r
+                if (ToolChainFamily, ToolChain) not in self._BuildOptions or Option.startswith('='):\r
                     self._BuildOptions[ToolChainFamily, ToolChain] = Option\r
                 else:\r
                     # concatenate the option string if they're for the same tool\r
@@ -2543,7 +2608,7 @@ class InfBuildData(ModuleBuildClassObject):
                                 'build',\r
                                 FORMAT_INVALID,\r
                                 "No TokenValue for PCD [%s.%s] in [%s]!" % (TokenSpaceGuid, PcdCName, str(Package)),\r
-                                File =self.MetaFile, Line=LineNo,\r
+                                File=self.MetaFile, Line=LineNo,\r
                                 ExtraData=None\r
                                 )                        \r
                     #\r
@@ -2556,7 +2621,7 @@ class InfBuildData(ModuleBuildClassObject):
                                     'build',\r
                                     FORMAT_INVALID,\r
                                     "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid:" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
-                                    File =self.MetaFile, Line=LineNo,\r
+                                    File=self.MetaFile, Line=LineNo,\r
                                     ExtraData=None\r
                                     )\r
                             \r
@@ -2570,19 +2635,19 @@ class InfBuildData(ModuleBuildClassObject):
                                 EdkLogger.error(\r
                                             'build',\r
                                             FORMAT_INVALID,\r
-                                            "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
-                                            File =self.MetaFile, Line=LineNo,\r
+                                            "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, as a decimal it should between: 0 - 4294967295!" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
+                                            File=self.MetaFile, Line=LineNo,\r
                                             ExtraData=None\r
-                                            )                                \r
+                                            )\r
                         except:\r
                             EdkLogger.error(\r
                                         'build',\r
                                         FORMAT_INVALID,\r
-                                        "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!"% (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
-                                        File =self.MetaFile, Line=LineNo,\r
+                                        "The format of TokenValue [%s] of PCD [%s.%s] in [%s] is invalid, it should be hexadecimal or decimal!" % (Pcd.TokenValue, TokenSpaceGuid, PcdCName, str(Package)),\r
+                                        File=self.MetaFile, Line=LineNo,\r
                                         ExtraData=None\r
                                         )\r
-                    \r
+\r
                     Pcd.DatumType = PcdInPackage.DatumType\r
                     Pcd.MaxDatumSize = PcdInPackage.MaxDatumSize\r
                     Pcd.InfDefaultValue = Pcd.DefaultValue\r
@@ -2594,7 +2659,7 @@ class InfBuildData(ModuleBuildClassObject):
                             'build',\r
                             FORMAT_INVALID,\r
                             "PCD [%s.%s] in [%s] is not found in dependent packages:" % (TokenSpaceGuid, PcdCName, self.MetaFile),\r
-                            File =self.MetaFile, Line=LineNo,\r
+                            File=self.MetaFile, Line=LineNo,\r
                             ExtraData="\t%s" % '\n\t'.join([str(P) for P in self.Packages])\r
                             )\r
             Pcds[PcdCName, TokenSpaceGuid] = Pcd\r
@@ -2777,7 +2842,7 @@ class WorkspaceDatabase(object):
     def __init__(self, DbPath, RenewDb=False):\r
         self._DbClosedFlag = False\r
         if not DbPath:\r
-            DbPath = os.path.normpath(os.path.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath))\r
+            DbPath = os.path.normpath(mws.join(GlobalData.gWorkspace, 'Conf', GlobalData.gDatabasePath))\r
 \r
         # don't create necessary path for db in memory\r
         if DbPath != ':memory:':\r
@@ -2905,7 +2970,7 @@ determine whether database file is out of date!\n")
     ## Summarize all packages in the database\r
     def GetPackageList(self, Platform, Arch, TargetName, ToolChainTag):\r
         self.Platform = Platform\r
-        PackageList =[]\r
+        PackageList = []\r
         Pa = self.BuildObject[self.Platform, 'COMMON']\r
         #\r
         # Get Package related to Modules\r
@@ -2922,8 +2987,8 @@ determine whether database file is out of date!\n")
             LibObj = self.BuildObject[Lib, Arch, TargetName, ToolChainTag]\r
             for Package in LibObj.Packages:\r
                 if Package not in PackageList:\r
-                    PackageList.append(Package)            \r
-        \r
+                    PackageList.append(Package)\r
+\r
         return PackageList\r
 \r
     ## Summarize all platforms in the database\r
@@ -2938,6 +3003,13 @@ determine whether database file is out of date!\n")
                 PlatformList.append(Platform)\r
         return PlatformList\r
 \r
+    def _MapPlatform(self, Dscfile):\r
+        try:\r
+            Platform = self.BuildObject[PathClass(Dscfile), 'COMMON']\r
+        except:\r
+            Platform = None\r
+        return Platform\r
+\r
     PlatformList = property(_GetPlatformList)\r
 \r
 ##\r