On 22 March 2016 at 04:25, Gao, Liming <[email protected]> wrote: > Reviewed-by: Liming Gao <[email protected]> >
This patch breaks the AARCH64 build: Processing meta-data .... build.py... : error F000: Not supported macro is found in make command : $(ARCHCC_FLAGS) $(PLATFORM_FLAGS) -g -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -ffunction-sections -fdata-sections -c -include AutoGen.h -fno-common -DSTRING_ARRAY_NAME=DxePcdLibStrings -mcmodel=tiny -g -Os -fshort-wchar -fno-strict-aliasing -Wall -Werror -Wno-array-bounds -c -include AutoGen.h -fno-common -mlittle-endian -fno-short-enums -save-temps -fverbose-asm -fsigned-char -ffunction-sections -fdata-sections -fomit-frame-pointer -fno-builtin -Wno-address -fno-asynchronous-unwind-tables -O0 [/home/ard/build/uefi-next/MdePkg/Library/DxePcdLib/DxePcdLib.inf] Could we *please* start testing BaseTools changes on other toolchains/platforms than X64/VS? >> -----Original Message----- >> From: edk2-devel [mailto:[email protected]] On Behalf Of >> Yonghong Zhu >> Sent: Wednesday, March 16, 2016 11:09 AM >> To: [email protected] >> Subject: [edk2] [Patch] BaseTools: Fix nmake failure due to command-line >> length limitation >> >> NMAKE is limited to command-line length of 4096 characters. Due to the >> large number of /I directives specified on command line (one per include >> directory), the path length of WORKSPACE is multiplied by the number of >> /I directives and can exceed the limit. >> This patch: >> 1. Add new build option -l, --cmd-len to set the maximum command line >> length, default value is 4096. >> 2. Generate the response file only if the command line length exceed its >> maximum characters (default is 4096) when build the module. Cover >> PP_FLAGS, CC_FLAGS, VFRPP_FLAGS, APP_FLAGS, ASLPP_FLAGS, >> ASLCC_FLAGS and >> ASM_FLAGS. >> 3. The content of the response file is combine from the FLAGS option and >> INC option. >> 4. When build failure, it would print out the response file's file >> location and its content. >> >> Contributed-under: TianoCore Contribution Agreement 1.0 >> Signed-off-by: Yonghong Zhu <[email protected]> >> --- >> BaseTools/Source/Python/AutoGen/AutoGen.py | 9 +++ >> BaseTools/Source/Python/AutoGen/GenMake.py | 114 >> ++++++++++++++++++++++++++- >> BaseTools/Source/Python/Common/GlobalData.py | 2 +- >> BaseTools/Source/Python/build/build.py | 12 +++ >> 4 files changed, 135 insertions(+), 2 deletions(-) >> >> diff --git a/BaseTools/Source/Python/AutoGen/AutoGen.py >> b/BaseTools/Source/Python/AutoGen/AutoGen.py >> index c7aa84f..4934c57 100644 >> --- a/BaseTools/Source/Python/AutoGen/AutoGen.py >> +++ b/BaseTools/Source/Python/AutoGen/AutoGen.py >> @@ -2376,10 +2376,11 @@ class ModuleAutoGen(AutoGen): >> self._OutputDir = None >> self._DebugDir = None >> self._MakeFileDir = None >> >> self._IncludePathList = None >> + self._IncludePathLength = 0 >> self._AutoGenFileList = None >> self._UnicodeFileList = None >> self._SourceFileList = None >> self._ObjectFileList = None >> self._BinaryFileList = None >> @@ -3222,10 +3223,17 @@ class ModuleAutoGen(AutoGen): >> for Inc in Package.Includes: >> if Inc not in self._IncludePathList: >> self._IncludePathList.append(str(Inc)) >> return self._IncludePathList >> >> + def _GetIncludePathLength(self): >> + self._IncludePathLength = 0 >> + if self._IncludePathList: >> + for inc in self._IncludePathList: >> + self._IncludePathLength += len(' ' + inc) >> + return self._IncludePathLength >> + >> ## Get HII EX PCDs which maybe used by VFR >> # >> # efivarstore used by VFR may relate with HII EX PCDs >> # Get the variable name and GUID from efivarstore and HII EX PCD >> # List the HII EX PCDs in As Built INF if both name and GUID match. >> @@ -3814,10 +3822,11 @@ class ModuleAutoGen(AutoGen): >> DebugDir = property(_GetDebugDir) >> MakeFileDir = property(_GetMakeFileDir) >> CustomMakefile = property(_GetCustomMakefile) >> >> IncludePathList = property(_GetIncludePathList) >> + IncludePathLength = property(_GetIncludePathLength) >> AutoGenFileList = property(_GetAutoGenFileList) >> UnicodeFileList = property(_GetUnicodeFileList) >> SourceFileList = property(_GetSourceFileList) >> BinaryFileList = property(_GetBinaryFiles) # FileType : [File List] >> Targets = property(_GetTargets) >> diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py >> b/BaseTools/Source/Python/AutoGen/GenMake.py >> index ec24c70..5543aaa 100644 >> --- a/BaseTools/Source/Python/AutoGen/GenMake.py >> +++ b/BaseTools/Source/Python/AutoGen/GenMake.py >> @@ -1,9 +1,9 @@ >> ## @file >> # Create makefile for MS nmake and GNU make >> # >> -# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR> >> +# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR> >> # This program and the accompanying materials >> # are licensed and made available under the terms and conditions of the BSD >> License >> # which accompanies this distribution. The full text of the license may be >> found at >> # http://opensource.org/licenses/bsd-license.php >> # >> @@ -495,10 +495,26 @@ cleanlib: >> if Attr == "FLAGS": >> Value = RemoveDupOption(Value, IncPrefix, >> self._AutoGenObject.IncludePathList) >> ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value)) >> ToolsDef.append("") >> >> + # generate the Response file and Response flag >> + RespDict = self.CommandExceedLimit() >> + RespFileList = os.path.join(self._AutoGenObject.OutputDir, >> 'respfilelist.txt') >> + if RespDict: >> + RespFileListContent = '' >> + for Resp in RespDict.keys(): >> + RespFile = os.path.join(self._AutoGenObject.OutputDir, >> str(Resp).lower() + '.txt') >> + SaveFileOnChange(RespFile, RespDict[Resp], False) >> + ToolsDef.append("%s = %s" % (Resp, '@' + RespFile)) >> + RespFileListContent += '@' + RespFile + os.linesep >> + RespFileListContent += RespDict[Resp] + os.linesep >> + SaveFileOnChange(RespFileList, RespFileListContent, False) >> + else: >> + if os.path.exists(RespFileList): >> + os.remove(RespFileList) >> + >> # convert source files and binary files to build targets >> self.ResultFileList = [str(T.Target) for T in >> self._AutoGenObject.CodaTargetList] >> if len(self.ResultFileList) == 0 and >> len(self._AutoGenObject.SourceFileList) <> 0: >> EdkLogger.error("build", AUTOGEN_ERROR, "Nothing to build", >> ExtraData="[%s]" % str(self._AutoGenObject)) >> @@ -618,10 +634,106 @@ cleanlib: >> "backward_compatible_target": BcTargetList, >> } >> >> return MakefileTemplateDict >> >> + def CommandExceedLimit(self): >> + FlagDict = { >> + 'CC' : { 'Macro' : '$(CC_FLAGS)', 'Value' : >> False}, >> + 'PP' : { 'Macro' : '$(PP_FLAGS)', 'Value' : >> False}, >> + 'APP' : { 'Macro' : '$(APP_FLAGS)', 'Value' : >> False}, >> + 'ASLPP' : { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : >> False}, >> + 'VFRPP' : { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : >> False}, >> + 'ASM' : { 'Macro' : '$(ASM_FLAGS)', 'Value' : >> False}, >> + 'ASLCC' : { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : >> False}, >> + } >> + >> + RespDict = {} >> + FileTypeList = [] >> + IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily] >> + >> + # base on the source files to decide the file type >> + for File in self._AutoGenObject.SourceFileList: >> + for type in self._AutoGenObject.FileTypes: >> + if File in self._AutoGenObject.FileTypes[type]: >> + if type not in FileTypeList: >> + FileTypeList.append(type) >> + >> + # calculate the command-line length >> + if FileTypeList: >> + for type in FileTypeList: >> + BuildTargets = >> self._AutoGenObject.BuildRules[type].BuildTargets >> + for Target in BuildTargets: >> + CommandList = BuildTargets[Target].Commands >> + for SingleCommand in CommandList: >> + Tool = '' >> + SingleCommandLength = len(SingleCommand) >> + SingleCommandList = SingleCommand.split() >> + if len(SingleCommandList) > 0: >> + for Flag in FlagDict.keys(): >> + if '$('+ Flag +')' in SingleCommandList[0]: >> + Tool = Flag >> + break >> + if Tool: >> + SingleCommandLength += >> len(self._AutoGenObject._BuildOption[Tool]['PATH']) >> + for item in SingleCommandList[1:]: >> + if FlagDict[Tool]['Macro'] in item: >> + Str = >> self._AutoGenObject._BuildOption[Tool]['FLAGS'] >> + while(Str.find('$(') != -1): >> + for macro in >> self._AutoGenObject.Macros.keys(): >> + MacroName = '$('+ macro + ')' >> + if (Str.find(MacroName) != -1): >> + Str = Str.replace(MacroName, >> self._AutoGenObject.Macros[macro]) >> + break >> + else: >> + EdkLogger.error("build", >> AUTOGEN_ERROR, "Not >> supported macro is found in make command : %s" % Str, ExtraData="[%s]" % >> str(self._AutoGenObject)) >> + SingleCommandLength += len(Str) >> + elif '$(INC)' in item: >> + SingleCommandLength += >> self._AutoGenObject.IncludePathLength + len(IncPrefix) * >> len(self._AutoGenObject._IncludePathList) >> + elif item.find('$(') != -1: >> + Str = item >> + for Option in >> self._AutoGenObject.BuildOption.keys(): >> + for Attr in >> self._AutoGenObject.BuildOption[Option]: >> + if Str.find(Option + '_' + >> Attr) != -1: >> + Str = Str.replace('$(' + >> Option + '_' + Attr + ')', >> self._AutoGenObject.BuildOption[Option][Attr]) >> + while(Str.find('$(') != -1): >> + for macro in >> self._AutoGenObject.Macros.keys(): >> + MacroName = '$('+ macro + ')' >> + if (Str.find(MacroName) != -1): >> + Str = Str.replace(MacroName, >> self._AutoGenObject.Macros[macro]) >> + break >> + else: >> + EdkLogger.error("build", >> AUTOGEN_ERROR, "Not >> supported macro is found in make command : %s" % Str, ExtraData="[%s]" % >> str(self._AutoGenObject)) >> + >> + SingleCommandLength += len(Str) >> + >> + if SingleCommandLength > >> GlobalData.gCommandMaxLength: >> + FlagDict[Tool]['Value'] = True >> + >> + # generate the response file content by combine the FLAGS >> and >> INC >> + for Flag in FlagDict.keys(): >> + if FlagDict[Flag]['Value']: >> + Key = Flag + '_RESP' >> + RespMacro = >> FlagDict[Flag]['Macro'].replace('FLAGS', 'RESP') >> + Value = >> self._AutoGenObject.BuildOption[Flag]['FLAGS'] >> + for inc in self._AutoGenObject._IncludePathList: >> + Value += ' ' + IncPrefix + inc >> + while (Value.find('$(') != -1): >> + for macro in self._AutoGenObject.Macros.keys(): >> + MacroName = '$('+ macro + ')' >> + if (Value.find(MacroName) != -1): >> + Value = Value.replace(MacroName, >> self._AutoGenObject.Macros[macro]) >> + break >> + else: >> + EdkLogger.error("build", AUTOGEN_ERROR, "Not >> supported macro is found in make command : %s" % Str, ExtraData="[%s]" % >> str(self._AutoGenObject)) >> + 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): >> # >> # Search dependency file list for each source file >> # >> ForceIncludedFile = [] >> diff --git a/BaseTools/Source/Python/Common/GlobalData.py >> b/BaseTools/Source/Python/Common/GlobalData.py >> index 4234bf5..8f544bd 100644 >> --- a/BaseTools/Source/Python/Common/GlobalData.py >> +++ b/BaseTools/Source/Python/Common/GlobalData.py >> @@ -32,11 +32,11 @@ gPlatformPcds = {} >> gPlatformOtherPcds = {} >> gActivePlatform = None >> gCommandLineDefines = {} >> gEdkGlobal = {} >> gOverrideDir = {} >> - >> +gCommandMaxLength = 4096 >> # for debug trace purpose when problem occurs >> gProcessingFile = '' >> gBuildingModule = '' >> >> ## Regular expression for matching macro used in DSC/DEC/INF file inclusion >> diff --git a/BaseTools/Source/Python/build/build.py >> b/BaseTools/Source/Python/build/build.py >> index 5619638..1607928 100644 >> --- a/BaseTools/Source/Python/build/build.py >> +++ b/BaseTools/Source/Python/build/build.py >> @@ -302,10 +302,18 @@ def LaunchCommand(Command, WorkingDir): >> >> # check the return code of the program >> if Proc.returncode != 0: >> if type(Command) != type(""): >> Command = " ".join(Command) >> + # print out the Response file and its content when make failure >> + RespFile = os.path.join(WorkingDir, 'OUTPUT', 'respfilelist.txt') >> + if os.path.isfile(RespFile): >> + f = open(RespFile) >> + RespContent = f.read() >> + f.close() >> + EdkLogger.info(RespContent) >> + >> EdkLogger.error("build", COMMAND_FAILURE, ExtraData="%s [%s]" % >> (Command, WorkingDir)) >> >> ## The smallest unit that can be built in multi-thread build mode >> # >> # This is the base class of build unit. The "Obj" parameter must provide >> @@ -773,10 +781,13 @@ class Build(): >> self.Platform = None >> self.LoadFixAddress = 0 >> self.UniFlag = BuildOptions.Flag >> self.BuildModules = [] >> >> + if BuildOptions.CommandLength: >> + GlobalData.gCommandMaxLength = BuildOptions.CommandLength >> + >> # print dot character during doing some time-consuming work >> self.Progress = Utils.Progressor() >> >> self.InitBuild() >> >> @@ -1929,10 +1940,11 @@ def MyOptionParser(): >> Parser.add_option("-N", "--no-cache", action="store_true", >> dest="DisableCache", default=False, help="Disable build cache mechanism") >> Parser.add_option("--conf", action="store", type="string", >> dest="ConfDirectory", help="Specify the customized Conf directory.") >> Parser.add_option("--check-usage", action="store_true", >> dest="CheckUsage", default=False, help="Check usage content of entries >> listed in INF file.") >> Parser.add_option("--ignore-sources", action="store_true", >> dest="IgnoreSources", default=False, help="Focus to a binary build and >> ignore all source files") >> Parser.add_option("--pcd", action="append", dest="OptionPcd", >> help="Set PCD value by command line. Format: 'PcdName=Value' ") >> + Parser.add_option("-l", "--cmd-len", action="store", type="int", >> dest="CommandLength", help="Specify the maximum line length of build >> command. Default is 4096.") >> >> (Opt, Args) = Parser.parse_args() >> return (Opt, Args) >> >> ## Tool entrance method >> -- >> 2.6.1.windows.1 >> >> _______________________________________________ >> edk2-devel mailing list >> [email protected] >> https://lists.01.org/mailman/listinfo/edk2-devel > _______________________________________________ > edk2-devel mailing list > [email protected] > https://lists.01.org/mailman/listinfo/edk2-devel _______________________________________________ edk2-devel mailing list [email protected] https://lists.01.org/mailman/listinfo/edk2-devel

