]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/Python/AutoGen/GenMake.py
BaseTools: Fix the bug for CArray PCD override in command line
[mirror_edk2.git] / BaseTools / Source / Python / AutoGen / GenMake.py
index ec24c70fd3f1850b19e987a1bfe03e638b783888..0f3ddd5dd44498258516ec5c6aee79221b3fc98f 100644 (file)
@@ -1,7 +1,7 @@
 ## @file\r
 # Create makefile for MS nmake and GNU make\r
 #\r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2017, Intel Corporation. All rights reserved.<BR>\r
 # This program and the accompanying materials\r
 # are licensed and made available under the terms and conditions of the BSD License\r
 # which accompanies this distribution.  The full text of the license may be found at\r
@@ -233,7 +233,7 @@ PLATFORM_NAME = ${platform_name}
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
+PLATFORM_DIR = ${platform_dir}\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
@@ -386,7 +386,7 @@ ${END}
 #\r
 clean:\r
 \t${BEGIN}${clean_command}\r
-\t${END}\r
+\t${END}\t$(RM) AutoGenTimeStamp\r
 \r
 #\r
 # clean all generated files\r
@@ -395,6 +395,7 @@ cleanall:
 ${BEGIN}\t${cleanall_command}\r
 ${END}\t$(RM) *.pdb *.idb > NUL 2>&1\r
 \t$(RM) $(BIN_DIR)${separator}$(MODULE_NAME).efi\r
+\t$(RM) AutoGenTimeStamp\r
 \r
 #\r
 # clean all dependent libraries built\r
@@ -477,6 +478,22 @@ cleanlib:
             # EdkII modules always use "_ModuleEntryPoint" as entry point\r
             ImageEntryPoint = "_ModuleEntryPoint"\r
 \r
+        for k, v in self._AutoGenObject.Module.Defines.iteritems():\r
+            if k not in self._AutoGenObject.Macros.keys():\r
+                self._AutoGenObject.Macros[k] = v\r
+\r
+        if 'MODULE_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():\r
+            self._AutoGenObject.Macros['MODULE_ENTRY_POINT'] = ModuleEntryPoint\r
+        if 'ARCH_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():\r
+            self._AutoGenObject.Macros['ARCH_ENTRY_POINT'] = ArchEntryPoint\r
+        if 'IMAGE_ENTRY_POINT' not in self._AutoGenObject.Macros.keys():\r
+            self._AutoGenObject.Macros['IMAGE_ENTRY_POINT'] = ImageEntryPoint\r
+\r
+        PCI_COMPRESS_Flag = False\r
+        for k, v in self._AutoGenObject.Module.Defines.iteritems():\r
+            if 'PCI_COMPRESS' == k and 'TRUE' == v:\r
+                PCI_COMPRESS_Flag = True\r
+\r
         # tools definitions\r
         ToolsDef = []\r
         IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]\r
@@ -494,9 +511,43 @@ cleanlib:
                     # Remove duplicated include path, if any\r
                     if Attr == "FLAGS":\r
                         Value = RemoveDupOption(Value, IncPrefix, self._AutoGenObject.IncludePathList)\r
+                        if Tool == "OPTROM" and PCI_COMPRESS_Flag:\r
+                            ValueList = Value.split()\r
+                            if ValueList:\r
+                                for i, v in enumerate(ValueList):\r
+                                    if '-e' == v:\r
+                                        ValueList[i] = '-ec'\r
+                                Value = ' '.join(ValueList)\r
+\r
                     ToolsDef.append("%s_%s = %s" % (Tool, Attr, Value))\r
             ToolsDef.append("")\r
 \r
+        # generate the Response file and Response flag\r
+        RespDict = self.CommandExceedLimit()\r
+        RespFileList = os.path.join(self._AutoGenObject.OutputDir, 'respfilelist.txt')\r
+        if RespDict:\r
+            RespFileListContent = ''\r
+            for Resp in RespDict.keys():\r
+                RespFile = os.path.join(self._AutoGenObject.OutputDir, str(Resp).lower() + '.txt')\r
+                StrList = RespDict[Resp].split(' ')\r
+                UnexpandMacro = []\r
+                NewStr = []\r
+                for Str in StrList:\r
+                    if '$' in Str:\r
+                        UnexpandMacro.append(Str)\r
+                    else:\r
+                        NewStr.append(Str)\r
+                UnexpandMacroStr = ' '.join(UnexpandMacro)\r
+                NewRespStr = ' '.join(NewStr)\r
+                SaveFileOnChange(RespFile, NewRespStr, False)\r
+                ToolsDef.append("%s = %s" % (Resp, UnexpandMacroStr + ' @' + RespFile))\r
+                RespFileListContent += '@' + RespFile + os.linesep\r
+                RespFileListContent += NewRespStr + os.linesep\r
+            SaveFileOnChange(RespFileList, RespFileListContent, False)\r
+        else:\r
+            if os.path.exists(RespFileList):\r
+                os.remove(RespFileList)\r
+\r
         # convert source files and binary files to build targets\r
         self.ResultFileList = [str(T.Target) for T in self._AutoGenObject.CodaTargetList]\r
         if len(self.ResultFileList) == 0 and len(self._AutoGenObject.SourceFileList) <> 0:\r
@@ -560,10 +611,11 @@ cleanlib:
         while not found and os.sep in package_rel_dir:\r
             index = package_rel_dir.index(os.sep)\r
             current_dir = mws.join(current_dir, package_rel_dir[:index])\r
-            for fl in os.listdir(current_dir):\r
-                if fl.endswith('.dec'):\r
-                    found = True\r
-                    break\r
+            if os.path.exists(current_dir):\r
+                for fl in os.listdir(current_dir):\r
+                    if fl.endswith('.dec'):\r
+                        found = True\r
+                        break\r
             package_rel_dir = package_rel_dir[index + 1:]\r
 \r
         MakefileTemplateDict = {\r
@@ -575,6 +627,7 @@ cleanlib:
             "platform_version"          : self.PlatformInfo.Version,\r
             "platform_relative_directory": self.PlatformInfo.SourceDir,\r
             "platform_output_directory" : self.PlatformInfo.OutputDir,\r
+            "platform_dir"              : self._AutoGenObject.Macros["PLATFORM_DIR"],\r
 \r
             "module_name"               : self._AutoGenObject.Name,\r
             "module_guid"               : self._AutoGenObject.Guid,\r
@@ -620,6 +673,113 @@ cleanlib:
 \r
         return MakefileTemplateDict\r
 \r
+    def CommandExceedLimit(self):\r
+        FlagDict = {\r
+                    'CC'    :  { 'Macro' : '$(CC_FLAGS)',    'Value' : False},\r
+                    'PP'    :  { 'Macro' : '$(PP_FLAGS)',    'Value' : False},\r
+                    'APP'   :  { 'Macro' : '$(APP_FLAGS)',   'Value' : False},\r
+                    'ASLPP' :  { 'Macro' : '$(ASLPP_FLAGS)', 'Value' : False},\r
+                    'VFRPP' :  { 'Macro' : '$(VFRPP_FLAGS)', 'Value' : False},\r
+                    'ASM'   :  { 'Macro' : '$(ASM_FLAGS)',   'Value' : False},\r
+                    'ASLCC' :  { 'Macro' : '$(ASLCC_FLAGS)', 'Value' : False},\r
+                   }\r
+\r
+        RespDict = {}\r
+        FileTypeList = []\r
+        IncPrefix = self._INC_FLAG_[self._AutoGenObject.ToolChainFamily]\r
+\r
+        # base on the source files to decide the file type\r
+        for File in self._AutoGenObject.SourceFileList:\r
+            for type in self._AutoGenObject.FileTypes:\r
+                if File in self._AutoGenObject.FileTypes[type]:\r
+                    if type not in FileTypeList:\r
+                        FileTypeList.append(type)\r
+\r
+        # calculate the command-line length\r
+        if FileTypeList:\r
+            for type in FileTypeList:\r
+                BuildTargets = self._AutoGenObject.BuildRules[type].BuildTargets\r
+                for Target in BuildTargets:\r
+                    CommandList = BuildTargets[Target].Commands\r
+                    for SingleCommand in CommandList:\r
+                        Tool = ''\r
+                        SingleCommandLength = len(SingleCommand)\r
+                        SingleCommandList = SingleCommand.split()\r
+                        if len(SingleCommandList) > 0:\r
+                            for Flag in FlagDict.keys():\r
+                                if '$('+ Flag +')' in SingleCommandList[0]:\r
+                                    Tool = Flag\r
+                                    break\r
+                        if Tool:\r
+                            SingleCommandLength += len(self._AutoGenObject._BuildOption[Tool]['PATH'])\r
+                            for item in SingleCommandList[1:]:\r
+                                if FlagDict[Tool]['Macro'] in item:\r
+                                    Str = self._AutoGenObject._BuildOption[Tool]['FLAGS']\r
+                                    for Option in self._AutoGenObject.BuildOption.keys():\r
+                                        for Attr in self._AutoGenObject.BuildOption[Option]:\r
+                                            if Str.find(Option + '_' + Attr) != -1:\r
+                                                Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
+                                    while(Str.find('$(') != -1):\r
+                                        for macro in self._AutoGenObject.Macros.keys():\r
+                                            MacroName = '$('+ macro + ')'\r
+                                            if (Str.find(MacroName) != -1):\r
+                                                Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])\r
+                                                break\r
+                                        else:\r
+                                            break\r
+                                    SingleCommandLength += len(Str)\r
+                                elif '$(INC)' in item:\r
+                                    SingleCommandLength += self._AutoGenObject.IncludePathLength + len(IncPrefix) * len(self._AutoGenObject._IncludePathList)\r
+                                elif item.find('$(') != -1:\r
+                                    Str = item\r
+                                    for Option in self._AutoGenObject.BuildOption.keys():\r
+                                        for Attr in self._AutoGenObject.BuildOption[Option]:\r
+                                            if Str.find(Option + '_' + Attr) != -1:\r
+                                                Str = Str.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
+                                    while(Str.find('$(') != -1):\r
+                                        for macro in self._AutoGenObject.Macros.keys():\r
+                                            MacroName = '$('+ macro + ')'\r
+                                            if (Str.find(MacroName) != -1):\r
+                                                Str = Str.replace(MacroName, self._AutoGenObject.Macros[macro])\r
+                                                break\r
+                                        else:\r
+                                            break\r
+                                    SingleCommandLength += len(Str)\r
+\r
+                            if SingleCommandLength > GlobalData.gCommandMaxLength:\r
+                                FlagDict[Tool]['Value'] = True\r
+\r
+                # generate the response file content by combine the FLAGS and INC\r
+                for Flag in FlagDict.keys():\r
+                    if FlagDict[Flag]['Value']:\r
+                        Key = Flag + '_RESP'\r
+                        RespMacro = FlagDict[Flag]['Macro'].replace('FLAGS', 'RESP')\r
+                        Value = self._AutoGenObject.BuildOption[Flag]['FLAGS']\r
+                        for inc in self._AutoGenObject._IncludePathList:\r
+                            Value += ' ' + IncPrefix + inc\r
+                        for Option in self._AutoGenObject.BuildOption.keys():\r
+                            for Attr in self._AutoGenObject.BuildOption[Option]:\r
+                                if Value.find(Option + '_' + Attr) != -1:\r
+                                    Value = Value.replace('$(' + Option + '_' + Attr + ')', self._AutoGenObject.BuildOption[Option][Attr])\r
+                        while (Value.find('$(') != -1):\r
+                            for macro in self._AutoGenObject.Macros.keys():\r
+                                MacroName = '$('+ macro + ')'\r
+                                if (Value.find(MacroName) != -1):\r
+                                    Value = Value.replace(MacroName, self._AutoGenObject.Macros[macro])\r
+                                    break\r
+                            else:\r
+                                break\r
+\r
+                        if self._AutoGenObject.ToolChainFamily == 'GCC':\r
+                            RespDict[Key] = Value.replace('\\', '/')\r
+                        else:\r
+                            RespDict[Key] = Value\r
+                        for Target in BuildTargets:\r
+                            for i, SingleCommand in enumerate(BuildTargets[Target].Commands):\r
+                                if FlagDict[Flag]['Macro'] in SingleCommand:\r
+                                    BuildTargets[Target].Commands[i] = SingleCommand.replace('$(INC)','').replace(FlagDict[Flag]['Macro'], RespMacro)\r
+        return RespDict\r
+\r
     def ProcessBuildTargetList(self):\r
         #\r
         # Search dependency file list for each source file\r
@@ -642,6 +802,9 @@ cleanlib:
             if not self.FileDependency[File]:\r
                 self.FileDependency[File] = ['$(FORCE_REBUILD)']\r
                 continue\r
+\r
+            self._AutoGenObject.AutoGenDepSet |= set(self.FileDependency[File])\r
+\r
             # skip non-C files\r
             if File.Ext not in [".c", ".C"] or File.Name == "AutoGen.c":\r
                 continue\r
@@ -712,7 +875,8 @@ cleanlib:
     ## For creating makefile targets for dependent libraries\r
     def ProcessDependentLibrary(self):\r
         for LibraryAutoGen in self._AutoGenObject.LibraryAutoGenList:\r
-            self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))\r
+            if not LibraryAutoGen.IsBinaryModule:\r
+                self.LibraryBuildDirectoryList.append(self.PlaceMacro(LibraryAutoGen.BuildDir, self.Macros))\r
 \r
     ## Return a list containing source file's dependencies\r
     #\r
@@ -849,7 +1013,7 @@ PLATFORM_NAME = ${platform_name}
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_RELATIVE_DIR = ${platform_relative_directory}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
+PLATFORM_DIR = ${platform_dir}\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
@@ -979,6 +1143,7 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
             "platform_version"          : self.PlatformInfo.Version,\r
             "platform_relative_directory": self.PlatformInfo.SourceDir,\r
             "platform_output_directory" : self.PlatformInfo.OutputDir,\r
+            "platform_dir"              : self._AutoGenObject.Macros["PLATFORM_DIR"],\r
 \r
             "module_name"               : self._AutoGenObject.Name,\r
             "module_guid"               : self._AutoGenObject.Guid,\r
@@ -1031,7 +1196,7 @@ PLATFORM_NAME = ${platform_name}
 PLATFORM_GUID = ${platform_guid}\r
 PLATFORM_VERSION = ${platform_version}\r
 PLATFORM_FILE = ${platform_file}\r
-PLATFORM_DIR = $(WORKSPACE)${separator}${platform_relative_directory}\r
+PLATFORM_DIR = ${platform_dir}\r
 PLATFORM_OUTPUT_DIR = ${platform_output_directory}\r
 \r
 #\r
@@ -1173,6 +1338,7 @@ cleanlib:
             "platform_relative_directory": PlatformInfo.SourceDir,\r
             "platform_output_directory" : PlatformInfo.OutputDir,\r
             "platform_build_directory"  : PlatformInfo.BuildDir,\r
+            "platform_dir"              : self._AutoGenObject.Macros["PLATFORM_DIR"],\r
 \r
             "toolchain_tag"             : PlatformInfo.ToolChain,\r
             "build_target"              : PlatformInfo.BuildTarget,\r
@@ -1284,6 +1450,19 @@ class TopLevelMakefile(BuildFile):
         if GlobalData.gIgnoreSource:\r
             ExtraOption += " --ignore-sources"\r
 \r
+        if GlobalData.BuildOptionPcd:\r
+            for index, option in enumerate(GlobalData.gCommand):\r
+                if "--pcd" == option and GlobalData.gCommand[index+1]:\r
+                    pcdName, pcdValue = GlobalData.gCommand[index+1].split('=')\r
+                    if pcdValue.startswith('H'):\r
+                        pcdValue = 'H' + '"' + pcdValue[1:] + '"'\r
+                        ExtraOption += " --pcd " + pcdName + '=' + pcdValue\r
+                    elif pcdValue.startswith('L'):\r
+                        pcdValue = 'L' + '"' + pcdValue[1:] + '"'\r
+                        ExtraOption += " --pcd " + pcdName + '=' + pcdValue\r
+                    else:\r
+                        ExtraOption += " --pcd " + GlobalData.gCommand[index+1]\r
+\r
         MakefileName = self._FILE_NAME_[self._FileType]\r
         SubBuildCommandList = []\r
         for A in PlatformInfo.ArchList:\r