]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/AutoGen/GenMake.py
BaseTools: Add FMMT Python Tool
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / GenMake.py
index f5d15c40ad3196e5ea56f375bec12c38d313c9ee..e55efff059f94e8c333b15a67e3c8f523e1c2f25 100755 (executable)
@@ -1,8 +1,8 @@
 ## @file\r
 # Create makefile for MS nmake and GNU make\r
 #\r
-# Copyright (c) 2007 - 2020, Intel Corporation. All rights reserved.<BR>\r
-# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2021, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2020 - 2021, Arm Limited. All rights reserved.<BR>\r
 # SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
 \r
@@ -177,11 +177,11 @@ class BuildFile(object):
 \r
         MakePath = AutoGenObject.BuildOption.get('MAKE', {}).get('PATH')\r
         if not MakePath:\r
-            self._FileType = ""\r
-        elif "nmake" in MakePath:\r
+            MakePath = AutoGenObject.ToolDefinition.get('MAKE', {}).get('PATH')\r
+        if "nmake" in MakePath:\r
             self._FileType = NMAKE_FILETYPE\r
         else:\r
-            self._FileType = "gmake"\r
+            self._FileType = GMAKE_FILETYPE\r
 \r
         if sys.platform == "win32":\r
             self._Platform = WIN32_PLATFORM\r
@@ -519,13 +519,15 @@ cleanlib:
         # tools definitions\r
         ToolsDef = []\r
         IncPrefix = self._INC_FLAG_[MyAgo.ToolChainFamily]\r
-        for Tool in MyAgo.BuildOption:\r
-            for Attr in MyAgo.BuildOption[Tool]:\r
+        for Tool in sorted(list(MyAgo.BuildOption)):\r
+            Appended = False\r
+            for Attr in sorted(list(MyAgo.BuildOption[Tool])):\r
                 Value = MyAgo.BuildOption[Tool][Attr]\r
                 if Attr == "FAMILY":\r
                     continue\r
                 elif Attr == "PATH":\r
                     ToolsDef.append("%s = %s" % (Tool, Value))\r
+                    Appended = True\r
                 else:\r
                     # Don't generate MAKE_FLAGS in makefile. It's put in environment variable.\r
                     if Tool == "MAKE":\r
@@ -542,7 +544,9 @@ cleanlib:
                                 Value = ' '.join(ValueList)\r
 \r
                     ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))\r
-            ToolsDef.append("")\r
+                    Appended = True\r
+            if Appended:\r
+                ToolsDef.append("")\r
 \r
         # generate the Response file and Response flag\r
         RespDict = self.CommandExceedLimit()\r
@@ -576,7 +580,7 @@ cleanlib:
             EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",\r
                             ExtraData="[%s]" % str(MyAgo))\r
 \r
-        self.ProcessBuildTargetList()\r
+        self.ProcessBuildTargetList(MyAgo.OutputDir, ToolsDef)\r
         self.ParserGenerateFfsCmd()\r
 \r
         # Generate macros used to represent input files\r
@@ -612,9 +616,10 @@ cleanlib:
                 IncludePath = self._INC_FLAG_['NASM'] + self.PlaceMacro(P, self.Macros)\r
                 if IncludePath.endswith(os.sep):\r
                     IncludePath = IncludePath.rstrip(os.sep)\r
-                # When compiling .nasm files, need to add a literal backslash at each path\r
-                # To specify a literal backslash at the end of the line, precede it with a caret (^)\r
-                if P == MyAgo.IncludePathList[-1] and os.sep == '\\':\r
+                # When compiling .nasm files, need to add a literal backslash at each path.\r
+                # In nmake makfiles, a trailing literal backslash must be escaped with a caret ('^').\r
+                # It is otherwise replaced with a space (' '). This is not necessary for GNU makfefiles.\r
+                if P == MyAgo.IncludePathList[-1] and self._Platform == WIN32_PLATFORM and self._FileType == NMAKE_FILETYPE:\r
                     IncludePath = ''.join([IncludePath, '^', os.sep])\r
                 else:\r
                     IncludePath = os.path.join(IncludePath, '')\r
@@ -785,8 +790,10 @@ cleanlib:
 \r
     def ReplaceMacro(self, str):\r
         for Macro in self.MacroList:\r
-            if self._AutoGenObject.Macros[Macro] and self._AutoGenObject.Macros[Macro] in str:\r
-                str = str.replace(self._AutoGenObject.Macros[Macro], '$(' + Macro + ')')\r
+            if self._AutoGenObject.Macros[Macro] and os.path.normcase(self._AutoGenObject.Macros[Macro]) in os.path.normcase(str):\r
+                replace_dir = str[os.path.normcase(str).index(os.path.normcase(self._AutoGenObject.Macros[Macro])): os.path.normcase(str).index(\r
+                    os.path.normcase(self._AutoGenObject.Macros[Macro])) + len(self._AutoGenObject.Macros[Macro])]\r
+                str = str.replace(replace_dir, '$(' + Macro + ')')\r
         return str\r
 \r
     def CommandExceedLimit(self):\r
@@ -900,7 +907,7 @@ cleanlib:
                                     BuildTargets[Target].Commands[i] = SingleCommand.replace('$(INC)', '').replace(FlagDict[Flag]['Macro'], RespMacro)\r
         return RespDict\r
 \r
-    def ProcessBuildTargetList(self):\r
+    def ProcessBuildTargetList(self, RespFile, ToolsDef):\r
         #\r
         # Search dependency file list for each source file\r
         #\r
@@ -1001,6 +1008,7 @@ cleanlib:
                     self.ObjTargetDict[T.Target.SubDir] = set()\r
                 self.ObjTargetDict[T.Target.SubDir].add(NewFile)\r
         for Type in self._AutoGenObject.Targets:\r
+            resp_file_number = 0\r
             for T in self._AutoGenObject.Targets[Type]:\r
                 # Generate related macros if needed\r
                 if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:\r
@@ -1042,7 +1050,10 @@ cleanlib:
                         Deps.append("$(%s)" % T.ListFileMacro)\r
 \r
                 if self._AutoGenObject.BuildRuleFamily == TAB_COMPILER_MSFT and Type == TAB_C_CODE_FILE:\r
-                    T, CmdTarget, CmdTargetDict, CmdCppDict = self.ParserCCodeFile(T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict)\r
+                    T, CmdTarget, CmdTargetDict, CmdCppDict = self.ParserCCodeFile(T, Type, CmdSumDict, CmdTargetDict,\r
+                                                                                   CmdCppDict, DependencyDict, RespFile,\r
+                                                                                   ToolsDef, resp_file_number)\r
+                    resp_file_number += 1\r
                     TargetDict = {"target": self.PlaceMacro(T.Target.Path, self.Macros), "cmd": "\n\t".join(T.Commands),"deps": CCodeDeps}\r
                     CmdLine = self._BUILD_TARGET_TEMPLATE.Replace(TargetDict).rstrip().replace('\t$(OBJLIST', '$(OBJLIST')\r
                     if T.Commands:\r
@@ -1053,7 +1064,15 @@ cleanlib:
                     TargetDict = {"target": self.PlaceMacro(T.Target.Path, self.Macros), "cmd": "\n\t".join(T.Commands),"deps": Deps}\r
                     self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(TargetDict))\r
 \r
-    def ParserCCodeFile(self, T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict):\r
+                    # Add a Makefile rule for targets generating multiple files.\r
+                    # The main output is a prerequisite for the other output files.\r
+                    for i in T.Outputs[1:]:\r
+                        AnnexeTargetDict = {"target": self.PlaceMacro(i.Path, self.Macros), "cmd": "", "deps": self.PlaceMacro(T.Target.Path, self.Macros)}\r
+                        self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(AnnexeTargetDict))\r
+\r
+    def ParserCCodeFile(self, T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict, RespFile, ToolsDef,\r
+                            resp_file_number):\r
+        SaveFilePath = os.path.join(RespFile, "cc_resp_%s.txt" % resp_file_number)\r
         if not CmdSumDict:\r
             for item in self._AutoGenObject.Targets[Type]:\r
                 CmdSumDict[item.Target.SubDir] = item.Target.BaseName\r
@@ -1080,17 +1099,36 @@ cleanlib:
                         if Temp.startswith('/Fo'):\r
                             CmdSign = '%s%s' % (Temp.rsplit(TAB_SLASH, 1)[0], TAB_SLASH)\r
                             break\r
-                    else: continue\r
+                    else:\r
+                        continue\r
                     if CmdSign not in list(CmdTargetDict.keys()):\r
-                        CmdTargetDict[CmdSign] = Item.replace(Temp, CmdSign)\r
+                        cmd = Item.replace(Temp, CmdSign)\r
+                        if SingleCommandList[-1] in cmd:\r
+                            CmdTargetDict[CmdSign] = [cmd.replace(SingleCommandList[-1], "").rstrip(), SingleCommandList[-1]]\r
                     else:\r
-                        CmdTargetDict[CmdSign] = "%s %s" % (CmdTargetDict[CmdSign], SingleCommandList[-1])\r
+                        # CmdTargetDict[CmdSign] = "%s %s" % (CmdTargetDict[CmdSign], SingleCommandList[-1])\r
+                        CmdTargetDict[CmdSign].append(SingleCommandList[-1])\r
                     Index = CommandList.index(Item)\r
                     CommandList.pop(Index)\r
                     if SingleCommandList[-1].endswith("%s%s.c" % (TAB_SLASH, CmdSumDict[CmdSign[3:].rsplit(TAB_SLASH, 1)[0]])):\r
                         Cpplist = CmdCppDict[T.Target.SubDir]\r
                         Cpplist.insert(0, '$(OBJLIST_%d): ' % list(self.ObjTargetDict.keys()).index(T.Target.SubDir))\r
-                        T.Commands[Index] = '%s\n\t%s' % (' \\\n\t'.join(Cpplist), CmdTargetDict[CmdSign])\r
+                        source_files = CmdTargetDict[CmdSign][1:]\r
+                        source_files.insert(0, " ")\r
+                        if len(source_files)>2:\r
+                            SaveFileOnChange(SaveFilePath, " ".join(source_files), False)\r
+                            T.Commands[Index] = '%s\n\t%s $(cc_resp_%s)' % (\r
+                            ' \\\n\t'.join(Cpplist), CmdTargetDict[CmdSign][0], resp_file_number)\r
+                            ToolsDef.append("cc_resp_%s = @%s" % (resp_file_number, SaveFilePath))\r
+\r
+                        elif len(source_files)<=2 and len(" ".join(CmdTargetDict[CmdSign][:2]))>GlobalData.gCommandMaxLength:\r
+                            SaveFileOnChange(SaveFilePath, " ".join(source_files), False)\r
+                            T.Commands[Index] = '%s\n\t%s $(cc_resp_%s)' % (\r
+                                ' \\\n\t'.join(Cpplist), CmdTargetDict[CmdSign][0], resp_file_number)\r
+                            ToolsDef.append("cc_resp_%s = @%s" % (resp_file_number, SaveFilePath))\r
+\r
+                        else:\r
+                            T.Commands[Index] = '%s\n\t%s' % (' \\\n\t'.join(Cpplist), " ".join(CmdTargetDict[CmdSign]))\r
                     else:\r
                         T.Commands.pop(Index)\r
         return T, CmdSumDict, CmdTargetDict, CmdCppDict\r