## @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
\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
# 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
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
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
\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
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
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
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
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
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