public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: mliang2x <mingyuex.liang@intel.com>
To: devel@edk2.groups.io
Cc: Mingyue Liang <mingyuex.liang@intel.com>,
	Bob Feng <bob.c.feng@intel.com>,
	Liming Gao <gaoliming@byosoft.com.cn>,
	Yuwei Chen <yuwei.chen@intel.com>
Subject: [PATCH] BaseTools: Limit command line length.
Date: Fri, 23 Oct 2020 11:00:43 +0800	[thread overview]
Message-ID: <20201023030043.1047-1-mingyuex.liang@intel.com> (raw)

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2528

Currently, the command line is too long because the CL
command is followed by multiple C files.

Therefore, the number of C files
can be used to determine whether the command line
needs to be written to the file. If the number of
C files is greater than one, the command line is
directly written to the file. On the contrary,
whether to write to the file is determined by whether
the length of the command line exceeds the limited
length Documents.

Signed-off-by: Mingyue Liang <mingyuex.liang@intel.com>
Cc: Bob Feng <bob.c.feng@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Yuwei Chen <yuwei.chen@intel.com>
---
 BaseTools/Source/Python/AutoGen/GenMake.py    | 45 +++++++++++++++----
 .../Source/Python/AutoGen/IncludesAutoGen.py  | 13 +++++-
 2 files changed, 49 insertions(+), 9 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index 0314d0ea34..0cb97dc18d 100755
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -576,7 +576,8 @@ cleanlib:
             EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build",
                             ExtraData="[%s]" % str(MyAgo))
 
-        self.ProcessBuildTargetList()
+        self.ProcessBuildTargetList(MyAgo.OutputDir,ToolsDef)
+
         self.ParserGenerateFfsCmd()
 
         # Generate macros used to represent input files
@@ -866,7 +867,6 @@ cleanlib:
                                         else:
                                             break
                                     SingleCommandLength += len(Str)
-
                             if SingleCommandLength > GlobalData.gCommandMaxLength:
                                 FlagDict[Tool]['Value'] = True
 
@@ -890,18 +890,18 @@ cleanlib:
                                     break
                             else:
                                 break
-
                         if self._AutoGenObject.ToolChainFamily == 'GCC':
                             RespDict[Key] = Value.replace('\\', '/')
                         else:
                             RespDict[Key] = Value
+
                         for Target in BuildTargets:
                             for i, SingleCommand in enumerate(BuildTargets[Target].Commands):
                                 if FlagDict[Flag]['Macro'] in SingleCommand:
                                     BuildTargets[Target].Commands[i] = SingleCommand.replace('$(INC)', '').replace(FlagDict[Flag]['Macro'], RespMacro)
         return RespDict
 
-    def ProcessBuildTargetList(self):
+    def ProcessBuildTargetList(self, RespFile, ToolsDef):
         #
         # Search dependency file list for each source file
         #
@@ -1002,6 +1002,7 @@ cleanlib:
                     self.ObjTargetDict[T.Target.SubDir] = set()
                 self.ObjTargetDict[T.Target.SubDir].add(NewFile)
         for Type in self._AutoGenObject.Targets:
+            resp_file_number = 0
             for T in self._AutoGenObject.Targets[Type]:
                 # Generate related macros if needed
                 if T.GenFileListMacro and T.FileListMacro not in self.FileListMacros:
@@ -1043,7 +1044,8 @@ cleanlib:
                         Deps.append("$(%s)" % T.ListFileMacro)
 
                 if self._AutoGenObject.BuildRuleFamily == TAB_COMPILER_MSFT and Type == TAB_C_CODE_FILE:
-                    T, CmdTarget, CmdTargetDict, CmdCppDict = self.ParserCCodeFile(T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict)
+                    T, CmdTarget, CmdTargetDict, CmdCppDict = self.ParserCCodeFile(T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict, RespFile, ToolsDef, resp_file_number)
+                    resp_file_number += 1
                     TargetDict = {"target": self.PlaceMacro(T.Target.Path, self.Macros), "cmd": "\n\t".join(T.Commands),"deps": CCodeDeps}
                     CmdLine = self._BUILD_TARGET_TEMPLATE.Replace(TargetDict).rstrip().replace('\t$(OBJLIST', '$(OBJLIST')
                     if T.Commands:
@@ -1060,7 +1062,7 @@ cleanlib:
                         AnnexeTargetDict = {"target": self.PlaceMacro(i.Path, self.Macros), "cmd": "", "deps": self.PlaceMacro(T.Target.Path, self.Macros)}
                         self.BuildTargetList.append(self._BUILD_TARGET_TEMPLATE.Replace(AnnexeTargetDict))
 
-    def ParserCCodeFile(self, T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict):
+    def ParserCCodeFile(self, T, Type, CmdSumDict, CmdTargetDict, CmdCppDict, DependencyDict, RespFile, ToolsDef, resp_file_number):
         if not CmdSumDict:
             for item in self._AutoGenObject.Targets[Type]:
                 CmdSumDict[item.Target.SubDir] = item.Target.BaseName
@@ -1080,6 +1082,7 @@ cleanlib:
                                 CmdCppDict[item.Target.SubDir].append(Path)
         if T.Commands:
             CommandList = T.Commands[:]
+            SaveFilePath = os.path.join(RespFile, "cc_resp_%s.txt" % resp_file_number)
             for Item in CommandList[:]:
                 SingleCommandList = Item.split()
                 if len(SingleCommandList) > 0 and self.CheckCCCmd(SingleCommandList):
@@ -1087,19 +1090,45 @@ cleanlib:
                         if Temp.startswith('/Fo'):
                             CmdSign = '%s%s' % (Temp.rsplit(TAB_SLASH, 1)[0], TAB_SLASH)
                             break
-                    else: continue
+                    else:
+                        continue
                     if CmdSign not in list(CmdTargetDict.keys()):
                         CmdTargetDict[CmdSign] = Item.replace(Temp, CmdSign)
                     else:
                         CmdTargetDict[CmdSign] = "%s %s" % (CmdTargetDict[CmdSign], SingleCommandList[-1])
+
                     Index = CommandList.index(Item)
                     CommandList.pop(Index)
                     if SingleCommandList[-1].endswith("%s%s.c" % (TAB_SLASH, CmdSumDict[CmdSign[3:].rsplit(TAB_SLASH, 1)[0]])):
                         Cpplist = CmdCppDict[T.Target.SubDir]
                         Cpplist.insert(0, '$(OBJLIST_%d): ' % list(self.ObjTargetDict.keys()).index(T.Target.SubDir))
-                        T.Commands[Index] = '%s\n\t%s' % (' \\\n\t'.join(Cpplist), CmdTargetDict[CmdSign])
+                        cmdtargetlist = CmdTargetDict[CmdSign].split(" ")
+                        # get Source files and Save resp file.
+                        c_files = []
+                        cmds = []
+                        if cmdtargetlist:
+                            for item in cmdtargetlist:
+                                if item.startswith('$(') or item.startswith('/Fo') or item.startswith('"$('):
+                                    cmds.append(item)
+                                if item.endswith('.c'):
+                                    c_files.append(item)
+                            c_files.insert(0, " ")
+                            if len(c_files) > 2:
+                                SaveFileOnChange(SaveFilePath," ".join(c_files), False)
+                                T.Commands[Index] = '%s\n\t%s $(cc_resp_%s)' % (' \\\n\t'.join(Cpplist), " ".join(cmds), resp_file_number)
+                                ToolsDef.append("cc_resp_%s = @%s" % (resp_file_number, SaveFilePath))
+
+                            elif len(CmdTargetDict[CmdSign]) > GlobalData.gCommandMaxLength and len(c_files) <=2:
+                                SaveFileOnChange(SaveFilePath, " ".join(c_files), False)
+                                T.Commands[Index] = '%s\n\t%s $(cc_resp_%s)' % (' \\\n\t'.join(Cpplist), " ".join(cmds), resp_file_number)
+                                ToolsDef.append("cc_resp_%s = @%s" % (resp_file_number, SaveFilePath))
+
+                            else:
+                                T.Commands[Index] = '%s\n\t%s' % (' \\\n\t'.join(Cpplist), CmdTargetDict[CmdSign])
+
                     else:
                         T.Commands.pop(Index)
+
         return T, CmdSumDict, CmdTargetDict, CmdCppDict
 
     def CheckCCCmd(self, CommandList):
diff --git a/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py b/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
index 720d93395a..9f61d49b3a 100644
--- a/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
@@ -203,7 +203,18 @@ ${END}
                             cc_options = line[len(cc_cmd)+2:].split()
                         else:
                             cc_options = line[len(cc_cmd):].split()
-                        SourceFileAbsPathMap = {os.path.basename(item):item for item in cc_options if not item.startswith("/") and os.path.exists(item)}
+
+                        for item in cc_options:
+                            if not item.startswith("/"):
+                                # if item.startswith("@"):
+                                if item.endswith(".txt") and item.startswith("@"):
+                                    with open(item[1:], "r") as file:
+                                        source_files = file.readlines()[0].split()
+                                        SourceFileAbsPathMap = {os.path.basename(file):file for file in source_files if os.path.exists(file)}
+                                else:
+                                    if os.path.exists(item):
+                                        SourceFileAbsPathMap.update({os.path.basename(item): item.strip()})
+
             if line in SourceFileAbsPathMap:
                 current_source = line
                 if current_source not in ModuleDepDict:
-- 
2.28.0.windows.1


             reply	other threads:[~2020-10-23  3:00 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-23  3:00 mliang2x [this message]
2020-10-27 11:57 ` [edk2-devel] [PATCH] BaseTools: Limit command line length Laszlo Ersek
2020-10-28 14:57   ` Bob Feng
2020-11-02 15:06     ` Laszlo Ersek
2020-11-04  2:30       ` Bob Feng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201023030043.1047-1-mingyuex.liang@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox