]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/AutoGen/PlatformAutoGen.py
BaseTools/Source/Python: New Target/ToolChain/Arch in DSC [BuildOptions]
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / PlatformAutoGen.py
index 1e17b6687129315e4d4b35beae44478f1a14188f..21e72438e59e83b430f25b81007fa1d21673a671 100644 (file)
@@ -1,7 +1,8 @@
 ## @file\r
 # Create makefile for MS nmake and GNU make\r
 #\r
-# Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2019 - 2021, Intel Corporation. All rights reserved.<BR>\r
+#  Copyright (c) 2020, ARM Limited. All rights reserved.<BR>\r
 # SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
@@ -106,8 +107,9 @@ class PlatformAutoGen(AutoGen):
         self.BuildDatabase = Workspace.BuildDatabase\r
         self.DscBuildDataObj = Workspace.Platform\r
 \r
-        # flag indicating if the makefile/C-code file has been created or not\r
-        self.IsMakeFileCreated  = False\r
+        # MakeFileName is used to get the Makefile name and as a flag\r
+        # indicating whether the file has been created.\r
+        self.MakeFileName = ""\r
 \r
         self._DynamicPcdList = None    # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
         self._NonDynamicPcdList = None # [(TokenCName1, TokenSpaceGuidCName1), (TokenCName2, TokenSpaceGuidCName2), ...]\r
@@ -148,7 +150,7 @@ class PlatformAutoGen(AutoGen):
     #\r
     @cached_class_function\r
     def __hash__(self):\r
-        return hash((self.MetaFile, self.Arch))\r
+        return hash((self.MetaFile, self.Arch,self.ToolChain,self.BuildTarget))\r
     @cached_class_function\r
     def __repr__(self):\r
         return "%s [%s]" % (self.MetaFile, self.Arch)\r
@@ -191,16 +193,15 @@ class PlatformAutoGen(AutoGen):
         self.CreateLibModuelDirs()\r
 \r
     def CreateLibModuelDirs(self):\r
-        # no need to create makefile for the platform more than once\r
-        if self.IsMakeFileCreated:\r
+        # No need to create makefile for the platform more than once.\r
+        if self.MakeFileName:\r
             return\r
 \r
         # create library/module build dirs for platform\r
         Makefile = GenMake.PlatformMakefile(self)\r
         self.LibraryBuildDirectoryList = Makefile.GetLibraryBuildDirectoryList()\r
         self.ModuleBuildDirectoryList = Makefile.GetModuleBuildDirectoryList()\r
-\r
-        self.IsMakeFileCreated = True\r
+        self.MakeFileName = Makefile.getMakefileName()\r
 \r
     @property\r
     def AllPcdList(self):\r
@@ -252,7 +253,7 @@ class PlatformAutoGen(AutoGen):
         VariableInfo.SetVpdRegionMaxSize(VpdRegionSize)\r
         VariableInfo.SetVpdRegionOffset(VpdRegionBase)\r
         Index = 0\r
-        for Pcd in DynamicPcdSet:\r
+        for Pcd in sorted(DynamicPcdSet):\r
             pcdname = ".".join((Pcd.TokenSpaceGuidCName, Pcd.TokenCName))\r
             for SkuName in Pcd.SkuInfoList:\r
                 Sku = Pcd.SkuInfoList[SkuName]\r
@@ -275,11 +276,11 @@ class PlatformAutoGen(AutoGen):
             PcdNvStoreDfBuffer = [item for item in self._DynamicPcdList if item.TokenCName == "PcdNvStoreDefaultValueBuffer" and item.TokenSpaceGuidCName == "gEfiMdeModulePkgTokenSpaceGuid"]\r
 \r
             if PcdNvStoreDfBuffer:\r
-                if os.path.exists(VpdMapFilePath):\r
+                try:\r
                     OrgVpdFile.Read(VpdMapFilePath)\r
                     PcdItems = OrgVpdFile.GetOffset(PcdNvStoreDfBuffer[0])\r
                     NvStoreOffset = list(PcdItems.values())[0].strip() if PcdItems else '0'\r
-                else:\r
+                except:\r
                     EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)\r
 \r
                 NvStoreOffset = int(NvStoreOffset, 16) if NvStoreOffset.upper().startswith("0X") else int(NvStoreOffset)\r
@@ -441,7 +442,7 @@ class PlatformAutoGen(AutoGen):
                             File=self.MetaFile,\r
                             ExtraData="\n\tPCD(s) without MaxDatumSize:\n\t\t%s\n"\r
                                       % NoDatumTypePcdListString)\r
-        self._NonDynamicPcdList = self._NonDynaPcdList_\r
+        self._NonDynamicPcdList = sorted(self._NonDynaPcdList_)\r
         self._DynamicPcdList = self._DynaPcdList_\r
 \r
     def SortDynamicPcd(self):\r
@@ -665,7 +666,7 @@ class PlatformAutoGen(AutoGen):
                 # Process VPD map file generated by third party BPDG tool\r
                 if NeedProcessVpdMapFile:\r
                     VpdMapFilePath = os.path.join(self.BuildDir, TAB_FV_DIRECTORY, "%s.map" % self.Platform.VpdToolGuid)\r
-                    if os.path.exists(VpdMapFilePath):\r
+                    try:\r
                         VpdFile.Read(VpdMapFilePath)\r
 \r
                         # Fixup TAB_STAR offset\r
@@ -679,7 +680,7 @@ class PlatformAutoGen(AutoGen):
                                     for item in vpdinfo:\r
                                         if item[2] == pcdvalue:\r
                                             sku.VpdOffset = item[1]\r
-                    else:\r
+                    except:\r
                         EdkLogger.error("build", FILE_READ_FAILURE, "Can not find VPD map file %s to fix up VPD offset." % VpdMapFilePath)\r
 \r
             # Delete the DynamicPcdList At the last time enter into this function\r
@@ -704,6 +705,7 @@ class PlatformAutoGen(AutoGen):
         self._DynamicPcdList.extend(list(UnicodePcdArray))\r
         self._DynamicPcdList.extend(list(HiiPcdArray))\r
         self._DynamicPcdList.extend(list(OtherPcdArray))\r
+        self._DynamicPcdList.sort()\r
         allskuset = [(SkuName, Sku.SkuId) for pcd in self._DynamicPcdList for (SkuName, Sku) in pcd.SkuInfoList.items()]\r
         for pcd in self._DynamicPcdList:\r
             if len(pcd.SkuInfoList) == 1:\r
@@ -803,22 +805,55 @@ class PlatformAutoGen(AutoGen):
     #\r
     @cached_property\r
     def BuildCommand(self):\r
-        RetVal = []\r
-        if "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:\r
-            RetVal += _SplitOption(self.ToolDefinition["MAKE"]["PATH"])\r
-            if "FLAGS" in self.ToolDefinition["MAKE"]:\r
-                NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()\r
-                if NewOption != '':\r
-                    RetVal += _SplitOption(NewOption)\r
-            if "MAKE" in self.EdkIIBuildOption:\r
-                if "FLAGS" in self.EdkIIBuildOption["MAKE"]:\r
-                    Flags = self.EdkIIBuildOption["MAKE"]["FLAGS"]\r
-                    if Flags.startswith('='):\r
-                        RetVal = [RetVal[0]] + [Flags[1:]]\r
-                    else:\r
-                        RetVal.append(Flags)\r
+        if "MAKE" in self.EdkIIBuildOption and "PATH" in self.EdkIIBuildOption["MAKE"]:\r
+            # MAKE_PATH in DSC [BuildOptions] section is higher priority\r
+            Path = self.EdkIIBuildOption["MAKE"]["PATH"]\r
+            if Path.startswith('='):\r
+                Path = Path[1:].strip()\r
+            RetVal = _SplitOption(Path)\r
+        elif "MAKE" in self.ToolDefinition and "PATH" in self.ToolDefinition["MAKE"]:\r
+            RetVal = _SplitOption(self.ToolDefinition["MAKE"]["PATH"])\r
+        else:\r
+            return []\r
+        if "MAKE" in self.ToolDefinition and "FLAGS" in self.ToolDefinition["MAKE"]:\r
+            NewOption = self.ToolDefinition["MAKE"]["FLAGS"].strip()\r
+            if NewOption != '':\r
+                RetVal += _SplitOption(NewOption)\r
+        if "MAKE" in self.EdkIIBuildOption and "FLAGS" in self.EdkIIBuildOption["MAKE"]:\r
+            Flags = self.EdkIIBuildOption["MAKE"]["FLAGS"]\r
+            if Flags.startswith('='):\r
+                RetVal = [RetVal[0]] + _SplitOption(Flags[1:].strip())\r
+            else:\r
+                RetVal = RetVal + _SplitOption(Flags.strip())\r
         return RetVal\r
 \r
+    ## Compute a tool defintion key priority value in range 0..15\r
+    #\r
+    #  TARGET_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE  15\r
+    #  ******_TOOLCHAIN_ARCH_COMMANDTYPE_ATTRIBUTE  14\r
+    #  TARGET_*********_ARCH_COMMANDTYPE_ATTRIBUTE  13\r
+    #  ******_*********_ARCH_COMMANDTYPE_ATTRIBUTE  12\r
+    #  TARGET_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE  11\r
+    #  ******_TOOLCHAIN_****_COMMANDTYPE_ATTRIBUTE  10\r
+    #  TARGET_*********_****_COMMANDTYPE_ATTRIBUTE   9\r
+    #  ******_*********_****_COMMANDTYPE_ATTRIBUTE   8\r
+    #  TARGET_TOOLCHAIN_ARCH_***********_ATTRIBUTE   7\r
+    #  ******_TOOLCHAIN_ARCH_***********_ATTRIBUTE   6\r
+    #  TARGET_*********_ARCH_***********_ATTRIBUTE   5\r
+    #  ******_*********_ARCH_***********_ATTRIBUTE   4\r
+    #  TARGET_TOOLCHAIN_****_***********_ATTRIBUTE   3\r
+    #  ******_TOOLCHAIN_****_***********_ATTRIBUTE   2\r
+    #  TARGET_*********_****_***********_ATTRIBUTE   1\r
+    #  ******_*********_****_***********_ATTRIBUTE   0\r
+    #\r
+    def ToolDefinitionPriority (self,Key):\r
+        KeyList = Key.split('_')\r
+        Priority = 0\r
+        for Index in range (0, min(4, len(KeyList))):\r
+            if KeyList[Index] != '*':\r
+                Priority += (1 << Index)\r
+        return Priority\r
+\r
     ## Get tool chain definition\r
     #\r
     #  Get each tool definition for given tool chain from tools_def.txt and platform\r
@@ -831,8 +866,16 @@ class PlatformAutoGen(AutoGen):
                             ExtraData="[%s]" % self.MetaFile)\r
         RetVal = OrderedDict()\r
         DllPathList = set()\r
-        for Def in ToolDefinition:\r
+\r
+        PrioritizedDefList = sorted(ToolDefinition.keys(), key=self.ToolDefinitionPriority, reverse=True)\r
+        for Def in PrioritizedDefList:\r
             Target, Tag, Arch, Tool, Attr = Def.split("_")\r
+            if Target == TAB_STAR:\r
+                Target = self.BuildTarget\r
+            if Tag == TAB_STAR:\r
+                Tag = self.ToolChain\r
+            if Arch == TAB_STAR:\r
+                Arch = self.Arch\r
             if Target != self.BuildTarget or Tag != self.ToolChain or Arch != self.Arch:\r
                 continue\r
 \r
@@ -842,9 +885,14 @@ class PlatformAutoGen(AutoGen):
                 DllPathList.add(Value)\r
                 continue\r
 \r
+            #\r
+            # ToolDefinition is sorted from highest priority to lowest priority.\r
+            # Only add the first(highest priority) match to RetVal\r
+            #\r
             if Tool not in RetVal:\r
                 RetVal[Tool] = OrderedDict()\r
-            RetVal[Tool][Attr] = Value\r
+            if Attr not in RetVal[Tool]:\r
+                RetVal[Tool][Attr] = Value\r
 \r
         ToolsDef = ''\r
         if GlobalData.gOptions.SilentMode and "MAKE" in RetVal:\r
@@ -852,9 +900,21 @@ class PlatformAutoGen(AutoGen):
                 RetVal["MAKE"]["FLAGS"] = ""\r
             RetVal["MAKE"]["FLAGS"] += " -s"\r
         MakeFlags = ''\r
-        for Tool in RetVal:\r
-            for Attr in RetVal[Tool]:\r
-                Value = RetVal[Tool][Attr]\r
+\r
+        ToolList = list(RetVal.keys())\r
+        ToolList.sort()\r
+        for Tool in ToolList:\r
+            if Tool == TAB_STAR:\r
+                continue\r
+            AttrList = list(RetVal[Tool].keys())\r
+            if TAB_STAR in ToolList:\r
+                AttrList += list(RetVal[TAB_STAR])\r
+            AttrList.sort()\r
+            for Attr in AttrList:\r
+                if Attr in RetVal[Tool]:\r
+                    Value = RetVal[Tool][Attr]\r
+                else:\r
+                    Value = RetVal[TAB_STAR][Attr]\r
                 if Tool in self._BuildOptionWithToolDef(RetVal) and Attr in self._BuildOptionWithToolDef(RetVal)[Tool]:\r
                     # check if override is indicated\r
                     if self._BuildOptionWithToolDef(RetVal)[Tool][Attr].startswith('='):\r
@@ -864,11 +924,12 @@ class PlatformAutoGen(AutoGen):
                             Value += " " + self._BuildOptionWithToolDef(RetVal)[Tool][Attr]\r
                         else:\r
                             Value = self._BuildOptionWithToolDef(RetVal)[Tool][Attr]\r
-\r
+                            Def = '_'.join([self.BuildTarget, self.ToolChain, self.Arch, Tool, Attr])\r
+                            self.Workspace.ToolDef.ToolsDefTxtDictionary[Def] = Value\r
                 if Attr == "PATH":\r
                     # Don't put MAKE definition in the file\r
                     if Tool != "MAKE":\r
-                        ToolsDef += "%s = %s\n" % (Tool, Value)\r
+                        ToolsDef += "%s_%s = %s\n" % (Tool, Attr, Value)\r
                 elif Attr != "DLL":\r
                     # Don't put MAKE definition in the file\r
                     if Tool == "MAKE":\r
@@ -974,6 +1035,7 @@ class PlatformAutoGen(AutoGen):
                 continue\r
             ModuleData = self.BuildDatabase[ModuleFile, self.Arch, self.BuildTarget, self.ToolChain]\r
             RetVal.update(ModuleData.Packages)\r
+        RetVal.update(self.Platform.Packages)\r
         return list(RetVal)\r
 \r
     @cached_property\r
@@ -1033,13 +1095,18 @@ class PlatformAutoGen(AutoGen):
                 TokenNumber += 1\r
 \r
         for Pcd in self.NonDynamicPcdList:\r
-            RetVal[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = TokenNumber\r
-            TokenNumber += 1\r
+            RetVal[Pcd.TokenCName, Pcd.TokenSpaceGuidCName] = 0\r
         return RetVal\r
 \r
     @cached_property\r
     def _MbList(self):\r
-        return [self.BuildDatabase[m, self.Arch, self.BuildTarget, self.ToolChain] for m in self.Platform.Modules]\r
+        ModuleList = []\r
+        for m in self.Platform.Modules:\r
+            component = self.Platform.Modules[m]\r
+            module = self.BuildDatabase[m, self.Arch, self.BuildTarget, self.ToolChain]\r
+            module.Guid = component.Guid\r
+            ModuleList.append(module)\r
+        return ModuleList\r
 \r
     @cached_property\r
     def _MaList(self):\r
@@ -1454,14 +1521,31 @@ class PlatformAutoGen(AutoGen):
             Family = Key[0]\r
             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
             # if tool chain family doesn't match, skip it\r
-            if Tool in ToolDef and Family != "":\r
-                FamilyIsNull = False\r
-                if ToolDef[Tool].get(TAB_TOD_DEFINES_BUILDRULEFAMILY, "") != "":\r
-                    if Family != ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
-                        continue\r
-                elif Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+            if Family != "":\r
+                Found = False\r
+                if Tool in ToolDef:\r
+                    FamilyIsNull = False\r
+                    if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[Tool]:\r
+                        if Family == ToolDef[Tool][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                    if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:\r
+                        if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                if TAB_STAR in ToolDef:\r
+                    FamilyIsNull = False\r
+                    if TAB_TOD_DEFINES_BUILDRULEFAMILY in ToolDef[TAB_STAR]:\r
+                        if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_BUILDRULEFAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                    if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:\r
+                        if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:\r
+                            FamilyMatch = True\r
+                            Found = True\r
+                if not Found:\r
                     continue\r
-                FamilyMatch = True\r
+\r
             # expand any wildcard\r
             if Target == TAB_STAR or Target == self.BuildTarget:\r
                 if Tag == TAB_STAR or Tag == self.ToolChain:\r
@@ -1491,10 +1575,19 @@ class PlatformAutoGen(AutoGen):
             Family = Key[0]\r
             Target, Tag, Arch, Tool, Attr = Key[1].split("_")\r
             # if tool chain family doesn't match, skip it\r
-            if Tool not in ToolDef or Family == "":\r
+            if Family == "":\r
                 continue\r
             # option has been added before\r
-            if Family != ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+            Found = False\r
+            if Tool in ToolDef:\r
+                if TAB_TOD_DEFINES_FAMILY in ToolDef[Tool]:\r
+                    if Family == ToolDef[Tool][TAB_TOD_DEFINES_FAMILY]:\r
+                        Found = True\r
+            if TAB_STAR in ToolDef:\r
+                if TAB_TOD_DEFINES_FAMILY in ToolDef[TAB_STAR]:\r
+                    if Family == ToolDef[TAB_STAR][TAB_TOD_DEFINES_FAMILY]:\r
+                        Found = True\r
+            if not Found:\r
                 continue\r
 \r
             # expand any wildcard\r