public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH v1 1/1] BaseTools: Rationalise makefile generation
@ 2020-01-13 14:40 PierreGondois
  2020-01-22 17:37 ` PierreGondois
  0 siblings, 1 reply; 3+ messages in thread
From: PierreGondois @ 2020-01-13 14:40 UTC (permalink / raw)
  To: devel; +Cc: Pierre Gondois, bob.c.feng, liming.gao, Sami.Mujawar,
	pierre.gondois

From: Pierre Gondois <pierre.gondois@arm.com>

The GenMake.py script tests the platform environment
to determine the type of makefile that needs to be
generated. If a Windows build host is detected, the
makefile generated is of Nmake type. Otherwise a
GNUmake type is generated.

Furthermore, the <TARGET>_<TAGNAME>_<ARCH>_MAKE_PATH
option in tools_def.template defines the make tool
to use.
E.g.: for VS2017 this is configured to use Nmake, cf.
*_VS2017_*_MAKE_PATH = DEF(VS2017_BIN_HOST)\nmake.exe
while for GCC5 it is setup to use GNU make.
*_GCC5_*_MAKE_PATH = DEF(GCC_HOST_PREFIX)make

This prevents using the GCC compiler toolchain on a
Windows build host.

To address this issue this patch introduces 2 factors
to determine the generated makefile output.
  1. Platform -> to determine shell commands used
                 in makefile.
  2. MakeTool -> to determine the type of makefile
                 that needs to be generated.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---

The changes can be seen at https://github.com/PierreARM/edk2/tree/720_BaseTools_Rationalise_makefile_generation_v1

Notes:
    v1:
      - Rationalise makefile generation [Pierre]

 BaseTools/Source/Python/AutoGen/GenMake.py         | 122 ++++++++++----------
 BaseTools/Source/Python/AutoGen/IncludesAutoGen.py |  34 +++---
 BaseTools/Source/Python/build/build.py             |   7 +-
 3 files changed, 88 insertions(+), 75 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index fe94f9a4c232bb599a59563444c3985700c78ec6..640b562257f74a45b38b8c857dae4750f7c286e0 100755
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -2,6 +2,7 @@
 # Create makefile for MS nmake and GNU make
 #
 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 
@@ -52,13 +53,6 @@ gIncludeMacroConversion = {
   "EFI_PPI_DEPENDENCY"              :   gPpiDefinition,
 }
 
-## default makefile type
-gMakeType = ""
-if sys.platform == "win32":
-    gMakeType = "nmake"
-else:
-    gMakeType = "gmake"
-
 
 ## BuildFile class
 #
@@ -77,6 +71,13 @@ class BuildFile(object):
         "gmake" :   "GNUmakefile"
     }
 
+    # Get Makefile name.
+    def getMakefileName(self):
+        if not self._FileType:
+            return _DEFAULT_FILE_NAME_
+        else:
+            return self._FILE_NAME_[self._FileType]
+
     ## Fixed header string for makefile
     _MAKEFILE_HEADER = '''#
 # DO NOT EDIT
@@ -106,7 +107,7 @@ class BuildFile(object):
     #   $(RD)     remove dir command
     #
     _SHELL_CMD_ = {
-        "nmake" : {
+        "win32" : {
             "CP"    :   "copy /y",
             "MV"    :   "move /y",
             "RM"    :   "del /f /q",
@@ -114,7 +115,7 @@ class BuildFile(object):
             "RD"    :   "rmdir /s /q",
         },
 
-        "gmake" : {
+        "posix" : {
             "CP"    :   "cp -f",
             "MV"    :   "mv -f",
             "RM"    :   "rm -f",
@@ -125,35 +126,35 @@ class BuildFile(object):
 
     ## directory separator
     _SEP_ = {
-        "nmake" :   "\\",
-        "gmake" :   "/"
+        "win32" :   "\\",
+        "posix" :   "/"
     }
 
     ## directory creation template
     _MD_TEMPLATE_ = {
-        "nmake" :   'if not exist %(dir)s $(MD) %(dir)s',
-        "gmake" :   "$(MD) %(dir)s"
+        "win32" :   'if not exist %(dir)s $(MD) %(dir)s',
+        "posix" :   "$(MD) %(dir)s"
     }
 
     ## directory removal template
     _RD_TEMPLATE_ = {
-        "nmake" :   'if exist %(dir)s $(RD) %(dir)s',
-        "gmake" :   "$(RD) %(dir)s"
+        "win32" :   'if exist %(dir)s $(RD) %(dir)s',
+        "posix" :   "$(RD) %(dir)s"
     }
     ## cp if exist
     _CP_TEMPLATE_ = {
-        "nmake" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
-        "gmake" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
+        "win32" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
+        "posix" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
     }
 
     _CD_TEMPLATE_ = {
-        "nmake" :   'if exist %(dir)s cd %(dir)s',
-        "gmake" :   "test -e %(dir)s && cd %(dir)s"
+        "win32" :   'if exist %(dir)s cd %(dir)s',
+        "posix" :   "test -e %(dir)s && cd %(dir)s"
     }
 
     _MAKE_TEMPLATE_ = {
-        "nmake" :   'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
-        "gmake" :   'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
+        "win32" :   'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
+        "posix" :   'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
     }
 
     _INCLUDE_CMD_ = {
@@ -169,22 +170,30 @@ class BuildFile(object):
     #
     def __init__(self, AutoGenObject):
         self._AutoGenObject = AutoGenObject
-        self._FileType = gMakeType
 
-    ## Create build file
+        MakePath = AutoGenObject.BuildOption.get('MAKE', {}).get('PATH')
+        if not MakePath:
+            self._FileType = ""
+        elif "nmake" in MakePath:
+            self._FileType = "nmake"
+        else:
+            self._FileType = "gmake"
+
+        if sys.platform == "win32":
+            self._Platform = "win32"
+        else:
+            self._Platform = "posix"
+
+    ## Create build file.
     #
-    #   @param  FileType    Type of build file. Only nmake and gmake are supported now.
+    #  Only nmake and gmake are supported.
     #
-    #   @retval TRUE        The build file is created or re-created successfully
-    #   @retval FALSE       The build file exists and is the same as the one to be generated
+    #  @retval TRUE        The build file is created or re-created successfully
+    #  @retval FALSE       The build file exists and is the same as the one to be generated
     #
-    def Generate(self, FileType=gMakeType):
-        if FileType not in self._FILE_NAME_:
-            EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,
-                            ExtraData="[%s]" % str(self._AutoGenObject))
-        self._FileType = FileType
+    def Generate(self):
         FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
-        FileName = self._FILE_NAME_[FileType]
+        FileName = self.getMakefileName()
         if not os.path.exists(os.path.join(self._AutoGenObject.MakeFileDir, "deps.txt")):
             with open(os.path.join(self._AutoGenObject.MakeFileDir, "deps.txt"),"w+") as fd:
                 fd.write("")
@@ -200,7 +209,7 @@ class BuildFile(object):
     #   @retval     list        The directory creation command list
     #
     def GetCreateDirectoryCommand(self, DirList):
-        return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
+        return [self._MD_TEMPLATE_[self._Platform] % {'dir':Dir} for Dir in DirList]
 
     ## Return a list of directory removal command string
     #
@@ -209,7 +218,7 @@ class BuildFile(object):
     #   @retval     list        The directory removal command list
     #
     def GetRemoveDirectoryCommand(self, DirList):
-        return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
+        return [self._RD_TEMPLATE_[self._Platform] % {'dir':Dir} for Dir in DirList]
 
     def PlaceMacro(self, Path, MacroDefinitions=None):
         if Path.startswith("$("):
@@ -459,11 +468,8 @@ cleanlib:
     # Compose a dict object containing information used to do replacement in template
     @property
     def _TemplateDict(self):
-        if self._FileType not in self._SEP_:
-            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
-                            ExtraData="[%s]" % str(self._AutoGenObject))
         MyAgo = self._AutoGenObject
-        Separator = self._SEP_[self._FileType]
+        Separator = self._SEP_[self._Platform]
 
         # break build if no source files and binary files are found
         if len(MyAgo.SourceFileList) == 0 and len(MyAgo.BinaryFileList) == 0:
@@ -625,10 +631,10 @@ cleanlib:
 
         BcTargetList = []
 
-        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileName = self.getMakefileName()
         LibraryMakeCommandList = []
         for D in self.LibraryBuildDirectoryList:
-            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}
+            Command = self._MAKE_TEMPLATE_[self._Platform] % {"file":os.path.join(D, MakefileName)}
             LibraryMakeCommandList.append(Command)
 
         package_rel_dir = MyAgo.SourceDir
@@ -680,8 +686,8 @@ cleanlib:
             "separator"                 : Separator,
             "module_tool_definitions"   : ToolsDef,
 
-            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
-            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
+            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
+            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
 
             "module_entry_point"        : ModuleEntryPoint,
             "image_entry_point"         : ImageEntryPoint,
@@ -716,7 +722,7 @@ cleanlib:
                         self.ResultFileList.append(Dst)
                     if '%s :' %(Dst) not in self.BuildTargetList:
                         self.BuildTargetList.append("%s :" %(Dst))
-                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})
+                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._Platform] %{'Src': Src, 'Dst': Dst})
 
             FfsCmdList = Cmd[0]
             for index, Str in enumerate(FfsCmdList):
@@ -1217,7 +1223,7 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
     # Compose a dict object containing information used to do replacement in template
     @property
     def _TemplateDict(self):
-        Separator = self._SEP_[self._FileType]
+        Separator = self._SEP_[self._Platform]
         MyAgo = self._AutoGenObject
         if self._FileType not in MyAgo.CustomMakefile:
             EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType,
@@ -1247,7 +1253,7 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
                     ToolsDef.append("%s_%s = %s" % (Tool, Attr, MyAgo.BuildOption[Tool][Attr]))
             ToolsDef.append("")
 
-        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileName = self.getMakefileName()
         MakefileTemplateDict = {
             "makefile_header"           : self._FILE_HEADER_[self._FileType],
             "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
@@ -1280,8 +1286,8 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
             "separator"                 : Separator,
             "module_tool_definitions"   : ToolsDef,
 
-            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
-            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
+            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
+            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
 
             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
             "custom_makefile_content"   : CustomMakefile
@@ -1408,7 +1414,7 @@ cleanlib:
     # Compose a dict object containing information used to do replacement in template
     @property
     def _TemplateDict(self):
-        Separator = self._SEP_[self._FileType]
+        Separator = self._SEP_[self._Platform]
 
         MyAgo = self._AutoGenObject
         if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:
@@ -1419,13 +1425,13 @@ cleanlib:
         self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
         self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
 
-        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileName = self.getMakefileName()
         LibraryMakefileList = []
         LibraryMakeCommandList = []
         for D in self.LibraryBuildDirectoryList:
             D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})
             Makefile = os.path.join(D, MakefileName)
-            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
+            Command = self._MAKE_TEMPLATE_[self._Platform] % {"file":Makefile}
             LibraryMakefileList.append(Makefile)
             LibraryMakeCommandList.append(Command)
         self.LibraryMakeCommandList = LibraryMakeCommandList
@@ -1435,7 +1441,7 @@ cleanlib:
         for D in self.ModuleBuildDirectoryList:
             D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})
             Makefile = os.path.join(D, MakefileName)
-            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
+            Command = self._MAKE_TEMPLATE_[self._Platform] % {"file":Makefile}
             ModuleMakefileList.append(Makefile)
             ModuleMakeCommandList.append(Command)
 
@@ -1455,8 +1461,8 @@ cleanlib:
 
             "toolchain_tag"             : MyAgo.ToolChain,
             "build_target"              : MyAgo.BuildTarget,
-            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
-            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
+            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
+            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
             "build_architecture_list"   : MyAgo.Arch,
             "architecture"              : MyAgo.Arch,
             "separator"                 : Separator,
@@ -1514,7 +1520,7 @@ class TopLevelMakefile(BuildFile):
     # Compose a dict object containing information used to do replacement in template
     @property
     def _TemplateDict(self):
-        Separator = self._SEP_[self._FileType]
+        Separator = self._SEP_[self._Platform]
 
         # any platform autogen object is ok because we just need common information
         MyAgo = self._AutoGenObject
@@ -1570,10 +1576,10 @@ class TopLevelMakefile(BuildFile):
             else:
                 ExtraOption += " --pcd " + pcdname + '=' + pcd[3]
 
-        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileName = self.getMakefileName()
         SubBuildCommandList = []
         for A in MyAgo.ArchList:
-            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
+            Command = self._MAKE_TEMPLATE_[self._Platform] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
             SubBuildCommandList.append(Command)
 
         MakefileTemplateDict = {
@@ -1588,8 +1594,8 @@ class TopLevelMakefile(BuildFile):
 
             "toolchain_tag"             : MyAgo.ToolChain,
             "build_target"              : MyAgo.BuildTarget,
-            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
-            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
+            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
+            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
             'arch'                      : list(MyAgo.ArchList),
             "build_architecture_list"   : ','.join(MyAgo.ArchList),
             "separator"                 : Separator,
diff --git a/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py b/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
index bb6e883d84ca6decc97514f95a35bd6db8714eed..c41dc33c4bcf33d30cf8bfc829718ed96923ff8f 100644
--- a/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
@@ -2,6 +2,7 @@
 # Build cache intermediate result and state
 #
 # Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent
 #
 from Common.caching import cached_property
@@ -12,20 +13,6 @@ from Common.Misc import SaveFileOnChange, PathClass
 from Common.Misc import TemplateString
 import sys
 gIsFileMap = {}
-if sys.platform == "win32":
-    _INCLUDE_DEPS_TEMPLATE = TemplateString('''
-${BEGIN}
-!IF EXIST(${deps_file})
-!INCLUDE ${deps_file}
-!ENDIF
-${END}
-        ''')
-else:
-    _INCLUDE_DEPS_TEMPLATE = TemplateString('''
-${BEGIN}
--include ${deps_file}
-${END}
-        ''')
 
 DEP_FILE_TAIL = "# Updated \n"
 
@@ -59,6 +46,25 @@ class IncludesAutoGen():
 
     def CreateDepsInclude(self):
         deps_file = {'deps_file':self.deps_files}
+
+        MakePath = self.module_autogen.BuildOption.get('MAKE', {}).get('PATH')
+        if not MakePath:
+            EdkLogger.error("build", PARAMETER_MISSING, Message="No Make path available.")
+        elif "nmake" in MakePath:
+            _INCLUDE_DEPS_TEMPLATE = TemplateString('''
+        ${BEGIN}
+        !IF EXIST(${deps_file})
+        !INCLUDE ${deps_file}
+        !ENDIF
+        ${END}
+               ''')
+        else:
+            _INCLUDE_DEPS_TEMPLATE = TemplateString('''
+        ${BEGIN}
+        -include ${deps_file}
+        ${END}
+               ''')
+
         try:
             deps_include_str = _INCLUDE_DEPS_TEMPLATE.Replace(deps_file)
         except Exception as e:
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index 34acdccbdbd00a3d10f9c6c42004f59a96ff0063..a2a4337b7524163049c77f99874ce1a7aa4c1644 100755
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -4,6 +4,7 @@
 #  Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>
 #  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>
 #  Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR>
+#  Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -1250,7 +1251,7 @@ class Build():
                                 (AutoGenObject.BuildTarget, AutoGenObject.ToolChain, AutoGenObject.Arch),
                             ExtraData=str(AutoGenObject))
 
-        makefile = GenMake.BuildFile(AutoGenObject)._FILE_NAME_[GenMake.gMakeType]
+        makefile = GenMake.BuildFile(AutoGenObject).getMakefileName()
 
         # run
         if Target == 'run':
@@ -2039,10 +2040,10 @@ class Build():
             ModuleBuildDirectoryList = data_pipe.Get("ModuleBuildDirectoryList")
 
             for m_build_dir in LibraryBuildDirectoryList:
-                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile._FILE_NAME_[GenMake.gMakeType])):
+                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile.getMakefileName())):
                     return None
             for m_build_dir in ModuleBuildDirectoryList:
-                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile._FILE_NAME_[GenMake.gMakeType])):
+                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile.getMakefileName())):
                     return None
             Wa = WorkSpaceInfo(
                 workspacedir,active_p,target,toolchain,archlist
-- 
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v1 1/1] BaseTools: Rationalise makefile generation
  2020-01-13 14:40 [PATCH v1 1/1] BaseTools: Rationalise makefile generation PierreGondois
@ 2020-01-22 17:37 ` PierreGondois
  2020-02-03 12:09   ` Liming Gao
  0 siblings, 1 reply; 3+ messages in thread
From: PierreGondois @ 2020-01-22 17:37 UTC (permalink / raw)
  To: Pierre Gondois, devel@edk2.groups.io
  Cc: bob.c.feng@intel.com, liming.gao@intel.com, Sami Mujawar, nd

Hello Bob and Liming,
Just to let you know, I created a Bugzilla here on the same topic: https://bugzilla.tianocore.org/show_bug.cgi?id=2481 

Regards,
Pierre

-----Original Message-----
From: PierreGondois <pierre.gondois@arm.com> 
Sent: 13 January 2020 14:41
To: devel@edk2.groups.io
Cc: Pierre Gondois <Pierre.Gondois@arm.com>; bob.c.feng@intel.com; liming.gao@intel.com; Sami Mujawar <Sami.Mujawar@arm.com>; pierre.gondois@arm.comnd@arm.com
Subject: [PATCH v1 1/1] BaseTools: Rationalise makefile generation

From: Pierre Gondois <pierre.gondois@arm.com>

The GenMake.py script tests the platform environment to determine the type of makefile that needs to be generated. If a Windows build host is detected, the makefile generated is of Nmake type. Otherwise a GNUmake type is generated.

Furthermore, the <TARGET>_<TAGNAME>_<ARCH>_MAKE_PATH
option in tools_def.template defines the make tool to use.
E.g.: for VS2017 this is configured to use Nmake, cf.
*_VS2017_*_MAKE_PATH = DEF(VS2017_BIN_HOST)\nmake.exe while for GCC5 it is setup to use GNU make.
*_GCC5_*_MAKE_PATH = DEF(GCC_HOST_PREFIX)make

This prevents using the GCC compiler toolchain on a Windows build host.

To address this issue this patch introduces 2 factors to determine the generated makefile output.
  1. Platform -> to determine shell commands used
                 in makefile.
  2. MakeTool -> to determine the type of makefile
                 that needs to be generated.

Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
---

The changes can be seen at https://github.com/PierreARM/edk2/tree/720_BaseTools_Rationalise_makefile_generation_v1

Notes:
    v1:
      - Rationalise makefile generation [Pierre]

 BaseTools/Source/Python/AutoGen/GenMake.py         | 122 ++++++++++----------
 BaseTools/Source/Python/AutoGen/IncludesAutoGen.py |  34 +++---
 BaseTools/Source/Python/build/build.py             |   7 +-
 3 files changed, 88 insertions(+), 75 deletions(-)

diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
index fe94f9a4c232bb599a59563444c3985700c78ec6..640b562257f74a45b38b8c857dae4750f7c286e0 100755
--- a/BaseTools/Source/Python/AutoGen/GenMake.py
+++ b/BaseTools/Source/Python/AutoGen/GenMake.py
@@ -2,6 +2,7 @@
 # Create makefile for MS nmake and GNU make  #  # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent  #
 
@@ -52,13 +53,6 @@ gIncludeMacroConversion = {
   "EFI_PPI_DEPENDENCY"              :   gPpiDefinition,
 }
 
-## default makefile type
-gMakeType = ""
-if sys.platform == "win32":
-    gMakeType = "nmake"
-else:
-    gMakeType = "gmake"
-
 
 ## BuildFile class
 #
@@ -77,6 +71,13 @@ class BuildFile(object):
         "gmake" :   "GNUmakefile"
     }
 
+    # Get Makefile name.
+    def getMakefileName(self):
+        if not self._FileType:
+            return _DEFAULT_FILE_NAME_
+        else:
+            return self._FILE_NAME_[self._FileType]
+
     ## Fixed header string for makefile
     _MAKEFILE_HEADER = '''#
 # DO NOT EDIT
@@ -106,7 +107,7 @@ class BuildFile(object):
     #   $(RD)     remove dir command
     #
     _SHELL_CMD_ = {
-        "nmake" : {
+        "win32" : {
             "CP"    :   "copy /y",
             "MV"    :   "move /y",
             "RM"    :   "del /f /q",
@@ -114,7 +115,7 @@ class BuildFile(object):
             "RD"    :   "rmdir /s /q",
         },
 
-        "gmake" : {
+        "posix" : {
             "CP"    :   "cp -f",
             "MV"    :   "mv -f",
             "RM"    :   "rm -f",
@@ -125,35 +126,35 @@ class BuildFile(object):
 
     ## directory separator
     _SEP_ = {
-        "nmake" :   "\\",
-        "gmake" :   "/"
+        "win32" :   "\\",
+        "posix" :   "/"
     }
 
     ## directory creation template
     _MD_TEMPLATE_ = {
-        "nmake" :   'if not exist %(dir)s $(MD) %(dir)s',
-        "gmake" :   "$(MD) %(dir)s"
+        "win32" :   'if not exist %(dir)s $(MD) %(dir)s',
+        "posix" :   "$(MD) %(dir)s"
     }
 
     ## directory removal template
     _RD_TEMPLATE_ = {
-        "nmake" :   'if exist %(dir)s $(RD) %(dir)s',
-        "gmake" :   "$(RD) %(dir)s"
+        "win32" :   'if exist %(dir)s $(RD) %(dir)s',
+        "posix" :   "$(RD) %(dir)s"
     }
     ## cp if exist
     _CP_TEMPLATE_ = {
-        "nmake" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
-        "gmake" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
+        "win32" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
+        "posix" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
     }
 
     _CD_TEMPLATE_ = {
-        "nmake" :   'if exist %(dir)s cd %(dir)s',
-        "gmake" :   "test -e %(dir)s && cd %(dir)s"
+        "win32" :   'if exist %(dir)s cd %(dir)s',
+        "posix" :   "test -e %(dir)s && cd %(dir)s"
     }
 
     _MAKE_TEMPLATE_ = {
-        "nmake" :   'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
-        "gmake" :   'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
+        "win32" :   'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
+        "posix" :   'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
     }
 
     _INCLUDE_CMD_ = {
@@ -169,22 +170,30 @@ class BuildFile(object):
     #
     def __init__(self, AutoGenObject):
         self._AutoGenObject = AutoGenObject
-        self._FileType = gMakeType
 
-    ## Create build file
+        MakePath = AutoGenObject.BuildOption.get('MAKE', {}).get('PATH')
+        if not MakePath:
+            self._FileType = ""
+        elif "nmake" in MakePath:
+            self._FileType = "nmake"
+        else:
+            self._FileType = "gmake"
+
+        if sys.platform == "win32":
+            self._Platform = "win32"
+        else:
+            self._Platform = "posix"
+
+    ## Create build file.
     #
-    #   @param  FileType    Type of build file. Only nmake and gmake are supported now.
+    #  Only nmake and gmake are supported.
     #
-    #   @retval TRUE        The build file is created or re-created successfully
-    #   @retval FALSE       The build file exists and is the same as the one to be generated
+    #  @retval TRUE        The build file is created or re-created successfully
+    #  @retval FALSE       The build file exists and is the same as the one to be generated
     #
-    def Generate(self, FileType=gMakeType):
-        if FileType not in self._FILE_NAME_:
-            EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,
-                            ExtraData="[%s]" % str(self._AutoGenObject))
-        self._FileType = FileType
+    def Generate(self):
         FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
-        FileName = self._FILE_NAME_[FileType]
+        FileName = self.getMakefileName()
         if not os.path.exists(os.path.join(self._AutoGenObject.MakeFileDir, "deps.txt")):
             with open(os.path.join(self._AutoGenObject.MakeFileDir, "deps.txt"),"w+") as fd:
                 fd.write("")
@@ -200,7 +209,7 @@ class BuildFile(object):
     #   @retval     list        The directory creation command list
     #
     def GetCreateDirectoryCommand(self, DirList):
-        return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
+        return [self._MD_TEMPLATE_[self._Platform] % {'dir':Dir} for 
+ Dir in DirList]
 
     ## Return a list of directory removal command string
     #
@@ -209,7 +218,7 @@ class BuildFile(object):
     #   @retval     list        The directory removal command list
     #
     def GetRemoveDirectoryCommand(self, DirList):
-        return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
+        return [self._RD_TEMPLATE_[self._Platform] % {'dir':Dir} for 
+ Dir in DirList]
 
     def PlaceMacro(self, Path, MacroDefinitions=None):
         if Path.startswith("$("):
@@ -459,11 +468,8 @@ cleanlib:
     # Compose a dict object containing information used to do replacement in template
     @property
     def _TemplateDict(self):
-        if self._FileType not in self._SEP_:
-            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
-                            ExtraData="[%s]" % str(self._AutoGenObject))
         MyAgo = self._AutoGenObject
-        Separator = self._SEP_[self._FileType]
+        Separator = self._SEP_[self._Platform]
 
         # break build if no source files and binary files are found
         if len(MyAgo.SourceFileList) == 0 and len(MyAgo.BinaryFileList) == 0:
@@ -625,10 +631,10 @@ cleanlib:
 
         BcTargetList = []
 
-        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileName = self.getMakefileName()
         LibraryMakeCommandList = []
         for D in self.LibraryBuildDirectoryList:
-            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}
+            Command = self._MAKE_TEMPLATE_[self._Platform] % 
+ {"file":os.path.join(D, MakefileName)}
             LibraryMakeCommandList.append(Command)
 
         package_rel_dir = MyAgo.SourceDir @@ -680,8 +686,8 @@ cleanlib:
             "separator"                 : Separator,
             "module_tool_definitions"   : ToolsDef,
 
-            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
-            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
+            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
+            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
 
             "module_entry_point"        : ModuleEntryPoint,
             "image_entry_point"         : ImageEntryPoint,
@@ -716,7 +722,7 @@ cleanlib:
                         self.ResultFileList.append(Dst)
                     if '%s :' %(Dst) not in self.BuildTargetList:
                         self.BuildTargetList.append("%s :" %(Dst))
-                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})
+                        self.BuildTargetList.append('\t' + 
+ self._CP_TEMPLATE_[self._Platform] %{'Src': Src, 'Dst': Dst})
 
             FfsCmdList = Cmd[0]
             for index, Str in enumerate(FfsCmdList):
@@ -1217,7 +1223,7 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
     # Compose a dict object containing information used to do replacement in template
     @property
     def _TemplateDict(self):
-        Separator = self._SEP_[self._FileType]
+        Separator = self._SEP_[self._Platform]
         MyAgo = self._AutoGenObject
         if self._FileType not in MyAgo.CustomMakefile:
             EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType, @@ -1247,7 +1253,7 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
                     ToolsDef.append("%s_%s = %s" % (Tool, Attr, MyAgo.BuildOption[Tool][Attr]))
             ToolsDef.append("")
 
-        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileName = self.getMakefileName()
         MakefileTemplateDict = {
             "makefile_header"           : self._FILE_HEADER_[self._FileType],
             "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
@@ -1280,8 +1286,8 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
             "separator"                 : Separator,
             "module_tool_definitions"   : ToolsDef,
 
-            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
-            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
+            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
+            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
 
             "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
             "custom_makefile_content"   : CustomMakefile
@@ -1408,7 +1414,7 @@ cleanlib:
     # Compose a dict object containing information used to do replacement in template
     @property
     def _TemplateDict(self):
-        Separator = self._SEP_[self._FileType]
+        Separator = self._SEP_[self._Platform]
 
         MyAgo = self._AutoGenObject
         if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:
@@ -1419,13 +1425,13 @@ cleanlib:
         self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
         self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
 
-        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileName = self.getMakefileName()
         LibraryMakefileList = []
         LibraryMakeCommandList = []
         for D in self.LibraryBuildDirectoryList:
             D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})
             Makefile = os.path.join(D, MakefileName)
-            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
+            Command = self._MAKE_TEMPLATE_[self._Platform] % 
+ {"file":Makefile}
             LibraryMakefileList.append(Makefile)
             LibraryMakeCommandList.append(Command)
         self.LibraryMakeCommandList = LibraryMakeCommandList @@ -1435,7 +1441,7 @@ cleanlib:
         for D in self.ModuleBuildDirectoryList:
             D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})
             Makefile = os.path.join(D, MakefileName)
-            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
+            Command = self._MAKE_TEMPLATE_[self._Platform] % 
+ {"file":Makefile}
             ModuleMakefileList.append(Makefile)
             ModuleMakeCommandList.append(Command)
 
@@ -1455,8 +1461,8 @@ cleanlib:
 
             "toolchain_tag"             : MyAgo.ToolChain,
             "build_target"              : MyAgo.BuildTarget,
-            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
-            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
+            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
+            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
             "build_architecture_list"   : MyAgo.Arch,
             "architecture"              : MyAgo.Arch,
             "separator"                 : Separator,
@@ -1514,7 +1520,7 @@ class TopLevelMakefile(BuildFile):
     # Compose a dict object containing information used to do replacement in template
     @property
     def _TemplateDict(self):
-        Separator = self._SEP_[self._FileType]
+        Separator = self._SEP_[self._Platform]
 
         # any platform autogen object is ok because we just need common information
         MyAgo = self._AutoGenObject
@@ -1570,10 +1576,10 @@ class TopLevelMakefile(BuildFile):
             else:
                 ExtraOption += " --pcd " + pcdname + '=' + pcd[3]
 
-        MakefileName = self._FILE_NAME_[self._FileType]
+        MakefileName = self.getMakefileName()
         SubBuildCommandList = []
         for A in MyAgo.ArchList:
-            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
+            Command = self._MAKE_TEMPLATE_[self._Platform] % 
+ {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
             SubBuildCommandList.append(Command)
 
         MakefileTemplateDict = {
@@ -1588,8 +1594,8 @@ class TopLevelMakefile(BuildFile):
 
             "toolchain_tag"             : MyAgo.ToolChain,
             "build_target"              : MyAgo.BuildTarget,
-            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
-            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
+            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
+            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
             'arch'                      : list(MyAgo.ArchList),
             "build_architecture_list"   : ','.join(MyAgo.ArchList),
             "separator"                 : Separator,
diff --git a/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py b/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
index bb6e883d84ca6decc97514f95a35bd6db8714eed..c41dc33c4bcf33d30cf8bfc829718ed96923ff8f 100644
--- a/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
+++ b/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
@@ -2,6 +2,7 @@
 # Build cache intermediate result and state  #  # Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
 # SPDX-License-Identifier: BSD-2-Clause-Patent  #  from Common.caching import cached_property @@ -12,20 +13,6 @@ from Common.Misc import SaveFileOnChange, PathClass  from Common.Misc import TemplateString  import sys  gIsFileMap = {} -if sys.platform == "win32":
-    _INCLUDE_DEPS_TEMPLATE = TemplateString('''
-${BEGIN}
-!IF EXIST(${deps_file})
-!INCLUDE ${deps_file}
-!ENDIF
-${END}
-        ''')
-else:
-    _INCLUDE_DEPS_TEMPLATE = TemplateString('''
-${BEGIN}
--include ${deps_file}
-${END}
-        ''')
 
 DEP_FILE_TAIL = "# Updated \n"
 
@@ -59,6 +46,25 @@ class IncludesAutoGen():
 
     def CreateDepsInclude(self):
         deps_file = {'deps_file':self.deps_files}
+
+        MakePath = self.module_autogen.BuildOption.get('MAKE', {}).get('PATH')
+        if not MakePath:
+            EdkLogger.error("build", PARAMETER_MISSING, Message="No Make path available.")
+        elif "nmake" in MakePath:
+            _INCLUDE_DEPS_TEMPLATE = TemplateString('''
+        ${BEGIN}
+        !IF EXIST(${deps_file})
+        !INCLUDE ${deps_file}
+        !ENDIF
+        ${END}
+               ''')
+        else:
+            _INCLUDE_DEPS_TEMPLATE = TemplateString('''
+        ${BEGIN}
+        -include ${deps_file}
+        ${END}
+               ''')
+
         try:
             deps_include_str = _INCLUDE_DEPS_TEMPLATE.Replace(deps_file)
         except Exception as e:
diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
index 34acdccbdbd00a3d10f9c6c42004f59a96ff0063..a2a4337b7524163049c77f99874ce1a7aa4c1644 100755
--- a/BaseTools/Source/Python/build/build.py
+++ b/BaseTools/Source/Python/build/build.py
@@ -4,6 +4,7 @@
 #  Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>  #  Copyright (c) 2007 - 2019, Intel Corporation. All rights reserved.<BR>  #  Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR>
+#  Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent  # @@ -1250,7 +1251,7 @@ class Build():
                                 (AutoGenObject.BuildTarget, AutoGenObject.ToolChain, AutoGenObject.Arch),
                             ExtraData=str(AutoGenObject))
 
-        makefile = GenMake.BuildFile(AutoGenObject)._FILE_NAME_[GenMake.gMakeType]
+        makefile = GenMake.BuildFile(AutoGenObject).getMakefileName()
 
         # run
         if Target == 'run':
@@ -2039,10 +2040,10 @@ class Build():
             ModuleBuildDirectoryList = data_pipe.Get("ModuleBuildDirectoryList")
 
             for m_build_dir in LibraryBuildDirectoryList:
-                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile._FILE_NAME_[GenMake.gMakeType])):
+                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile.getMakefileName())):
                     return None
             for m_build_dir in ModuleBuildDirectoryList:
-                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile._FILE_NAME_[GenMake.gMakeType])):
+                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile.getMakefileName())):
                     return None
             Wa = WorkSpaceInfo(
                 workspacedir,active_p,target,toolchain,archlist
--
'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'



^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v1 1/1] BaseTools: Rationalise makefile generation
  2020-01-22 17:37 ` PierreGondois
@ 2020-02-03 12:09   ` Liming Gao
  0 siblings, 0 replies; 3+ messages in thread
From: Liming Gao @ 2020-02-03 12:09 UTC (permalink / raw)
  To: Pierre Gondois, devel@edk2.groups.io; +Cc: Feng, Bob C, Sami Mujawar, nd

Pierre:
  Thanks for your contribution. Do you verify below configurations? And, how do you verify Windows host + GCC make?
1. Windows Host + VS nmake
2. Windows Host + GCC make
3. Linux Host + GCC make.

Thanks
Liming
> -----Original Message-----
> From: Pierre Gondois <Pierre.Gondois@arm.com>
> Sent: Thursday, January 23, 2020 1:37 AM
> To: Pierre Gondois <Pierre.Gondois@arm.com>; devel@edk2.groups.io
> Cc: Feng, Bob C <bob.c.feng@intel.com>; Gao, Liming <liming.gao@intel.com>; Sami Mujawar <Sami.Mujawar@arm.com>; nd
> <nd@arm.com>
> Subject: RE: [PATCH v1 1/1] BaseTools: Rationalise makefile generation
> 
> Hello Bob and Liming,
> Just to let you know, I created a Bugzilla here on the same topic: https://bugzilla.tianocore.org/show_bug.cgi?id=2481
> 
> Regards,
> Pierre
> 
> -----Original Message-----
> From: PierreGondois <pierre.gondois@arm.com>
> Sent: 13 January 2020 14:41
> To: devel@edk2.groups.io
> Cc: Pierre Gondois <Pierre.Gondois@arm.com>; bob.c.feng@intel.com; liming.gao@intel.com; Sami Mujawar
> <Sami.Mujawar@arm.com>; pierre.gondois@arm.comnd@arm.com
> Subject: [PATCH v1 1/1] BaseTools: Rationalise makefile generation
> 
> From: Pierre Gondois <pierre.gondois@arm.com>
> 
> The GenMake.py script tests the platform environment to determine the type of makefile that needs to be generated. If a Windows
> build host is detected, the makefile generated is of Nmake type. Otherwise a GNUmake type is generated.
> 
> Furthermore, the <TARGET>_<TAGNAME>_<ARCH>_MAKE_PATH
> option in tools_def.template defines the make tool to use.
> E.g.: for VS2017 this is configured to use Nmake, cf.
> *_VS2017_*_MAKE_PATH = DEF(VS2017_BIN_HOST)\nmake.exe while for GCC5 it is setup to use GNU make.
> *_GCC5_*_MAKE_PATH = DEF(GCC_HOST_PREFIX)make
> 
> This prevents using the GCC compiler toolchain on a Windows build host.
> 
> To address this issue this patch introduces 2 factors to determine the generated makefile output.
>   1. Platform -> to determine shell commands used
>                  in makefile.
>   2. MakeTool -> to determine the type of makefile
>                  that needs to be generated.
> 
> Signed-off-by: Pierre Gondois <pierre.gondois@arm.com>
> Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
> ---
> 
> The changes can be seen at https://github.com/PierreARM/edk2/tree/720_BaseTools_Rationalise_makefile_generation_v1
> 
> Notes:
>     v1:
>       - Rationalise makefile generation [Pierre]
> 
>  BaseTools/Source/Python/AutoGen/GenMake.py         | 122 ++++++++++----------
>  BaseTools/Source/Python/AutoGen/IncludesAutoGen.py |  34 +++---
>  BaseTools/Source/Python/build/build.py             |   7 +-
>  3 files changed, 88 insertions(+), 75 deletions(-)
> 
> diff --git a/BaseTools/Source/Python/AutoGen/GenMake.py b/BaseTools/Source/Python/AutoGen/GenMake.py
> index fe94f9a4c232bb599a59563444c3985700c78ec6..640b562257f74a45b38b8c857dae4750f7c286e0 100755
> --- a/BaseTools/Source/Python/AutoGen/GenMake.py
> +++ b/BaseTools/Source/Python/AutoGen/GenMake.py
> @@ -2,6 +2,7 @@
>  # Create makefile for MS nmake and GNU make  #  # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
>  # SPDX-License-Identifier: BSD-2-Clause-Patent  #
> 
> @@ -52,13 +53,6 @@ gIncludeMacroConversion = {
>    "EFI_PPI_DEPENDENCY"              :   gPpiDefinition,
>  }
> 
> -## default makefile type
> -gMakeType = ""
> -if sys.platform == "win32":
> -    gMakeType = "nmake"
> -else:
> -    gMakeType = "gmake"
> -
> 
>  ## BuildFile class
>  #
> @@ -77,6 +71,13 @@ class BuildFile(object):
>          "gmake" :   "GNUmakefile"
>      }
> 
> +    # Get Makefile name.
> +    def getMakefileName(self):
> +        if not self._FileType:
> +            return _DEFAULT_FILE_NAME_
> +        else:
> +            return self._FILE_NAME_[self._FileType]
> +
>      ## Fixed header string for makefile
>      _MAKEFILE_HEADER = '''#
>  # DO NOT EDIT
> @@ -106,7 +107,7 @@ class BuildFile(object):
>      #   $(RD)     remove dir command
>      #
>      _SHELL_CMD_ = {
> -        "nmake" : {
> +        "win32" : {
>              "CP"    :   "copy /y",
>              "MV"    :   "move /y",
>              "RM"    :   "del /f /q",
> @@ -114,7 +115,7 @@ class BuildFile(object):
>              "RD"    :   "rmdir /s /q",
>          },
> 
> -        "gmake" : {
> +        "posix" : {
>              "CP"    :   "cp -f",
>              "MV"    :   "mv -f",
>              "RM"    :   "rm -f",
> @@ -125,35 +126,35 @@ class BuildFile(object):
> 
>      ## directory separator
>      _SEP_ = {
> -        "nmake" :   "\\",
> -        "gmake" :   "/"
> +        "win32" :   "\\",
> +        "posix" :   "/"
>      }
> 
>      ## directory creation template
>      _MD_TEMPLATE_ = {
> -        "nmake" :   'if not exist %(dir)s $(MD) %(dir)s',
> -        "gmake" :   "$(MD) %(dir)s"
> +        "win32" :   'if not exist %(dir)s $(MD) %(dir)s',
> +        "posix" :   "$(MD) %(dir)s"
>      }
> 
>      ## directory removal template
>      _RD_TEMPLATE_ = {
> -        "nmake" :   'if exist %(dir)s $(RD) %(dir)s',
> -        "gmake" :   "$(RD) %(dir)s"
> +        "win32" :   'if exist %(dir)s $(RD) %(dir)s',
> +        "posix" :   "$(RD) %(dir)s"
>      }
>      ## cp if exist
>      _CP_TEMPLATE_ = {
> -        "nmake" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
> -        "gmake" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
> +        "win32" :   'if exist %(Src)s $(CP) %(Src)s %(Dst)s',
> +        "posix" :   "test -f %(Src)s && $(CP) %(Src)s %(Dst)s"
>      }
> 
>      _CD_TEMPLATE_ = {
> -        "nmake" :   'if exist %(dir)s cd %(dir)s',
> -        "gmake" :   "test -e %(dir)s && cd %(dir)s"
> +        "win32" :   'if exist %(dir)s cd %(dir)s',
> +        "posix" :   "test -e %(dir)s && cd %(dir)s"
>      }
> 
>      _MAKE_TEMPLATE_ = {
> -        "nmake" :   'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
> -        "gmake" :   'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
> +        "win32" :   'if exist %(file)s "$(MAKE)" $(MAKE_FLAGS) -f %(file)s',
> +        "posix" :   'test -e %(file)s && "$(MAKE)" $(MAKE_FLAGS) -f %(file)s'
>      }
> 
>      _INCLUDE_CMD_ = {
> @@ -169,22 +170,30 @@ class BuildFile(object):
>      #
>      def __init__(self, AutoGenObject):
>          self._AutoGenObject = AutoGenObject
> -        self._FileType = gMakeType
> 
> -    ## Create build file
> +        MakePath = AutoGenObject.BuildOption.get('MAKE', {}).get('PATH')
> +        if not MakePath:
> +            self._FileType = ""
> +        elif "nmake" in MakePath:
> +            self._FileType = "nmake"
> +        else:
> +            self._FileType = "gmake"
> +
> +        if sys.platform == "win32":
> +            self._Platform = "win32"
> +        else:
> +            self._Platform = "posix"
> +
> +    ## Create build file.
>      #
> -    #   @param  FileType    Type of build file. Only nmake and gmake are supported now.
> +    #  Only nmake and gmake are supported.
>      #
> -    #   @retval TRUE        The build file is created or re-created successfully
> -    #   @retval FALSE       The build file exists and is the same as the one to be generated
> +    #  @retval TRUE        The build file is created or re-created successfully
> +    #  @retval FALSE       The build file exists and is the same as the one to be generated
>      #
> -    def Generate(self, FileType=gMakeType):
> -        if FileType not in self._FILE_NAME_:
> -            EdkLogger.error("build", PARAMETER_INVALID, "Invalid build type [%s]" % FileType,
> -                            ExtraData="[%s]" % str(self._AutoGenObject))
> -        self._FileType = FileType
> +    def Generate(self):
>          FileContent = self._TEMPLATE_.Replace(self._TemplateDict)
> -        FileName = self._FILE_NAME_[FileType]
> +        FileName = self.getMakefileName()
>          if not os.path.exists(os.path.join(self._AutoGenObject.MakeFileDir, "deps.txt")):
>              with open(os.path.join(self._AutoGenObject.MakeFileDir, "deps.txt"),"w+") as fd:
>                  fd.write("")
> @@ -200,7 +209,7 @@ class BuildFile(object):
>      #   @retval     list        The directory creation command list
>      #
>      def GetCreateDirectoryCommand(self, DirList):
> -        return [self._MD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
> +        return [self._MD_TEMPLATE_[self._Platform] % {'dir':Dir} for
> + Dir in DirList]
> 
>      ## Return a list of directory removal command string
>      #
> @@ -209,7 +218,7 @@ class BuildFile(object):
>      #   @retval     list        The directory removal command list
>      #
>      def GetRemoveDirectoryCommand(self, DirList):
> -        return [self._RD_TEMPLATE_[self._FileType] % {'dir':Dir} for Dir in DirList]
> +        return [self._RD_TEMPLATE_[self._Platform] % {'dir':Dir} for
> + Dir in DirList]
> 
>      def PlaceMacro(self, Path, MacroDefinitions=None):
>          if Path.startswith("$("):
> @@ -459,11 +468,8 @@ cleanlib:
>      # Compose a dict object containing information used to do replacement in template
>      @property
>      def _TemplateDict(self):
> -        if self._FileType not in self._SEP_:
> -            EdkLogger.error("build", PARAMETER_INVALID, "Invalid Makefile type [%s]" % self._FileType,
> -                            ExtraData="[%s]" % str(self._AutoGenObject))
>          MyAgo = self._AutoGenObject
> -        Separator = self._SEP_[self._FileType]
> +        Separator = self._SEP_[self._Platform]
> 
>          # break build if no source files and binary files are found
>          if len(MyAgo.SourceFileList) == 0 and len(MyAgo.BinaryFileList) == 0:
> @@ -625,10 +631,10 @@ cleanlib:
> 
>          BcTargetList = []
> 
> -        MakefileName = self._FILE_NAME_[self._FileType]
> +        MakefileName = self.getMakefileName()
>          LibraryMakeCommandList = []
>          for D in self.LibraryBuildDirectoryList:
> -            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join(D, MakefileName)}
> +            Command = self._MAKE_TEMPLATE_[self._Platform] %
> + {"file":os.path.join(D, MakefileName)}
>              LibraryMakeCommandList.append(Command)
> 
>          package_rel_dir = MyAgo.SourceDir @@ -680,8 +686,8 @@ cleanlib:
>              "separator"                 : Separator,
>              "module_tool_definitions"   : ToolsDef,
> 
> -            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
> -            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
> +            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
> +            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
> 
>              "module_entry_point"        : ModuleEntryPoint,
>              "image_entry_point"         : ImageEntryPoint,
> @@ -716,7 +722,7 @@ cleanlib:
>                          self.ResultFileList.append(Dst)
>                      if '%s :' %(Dst) not in self.BuildTargetList:
>                          self.BuildTargetList.append("%s :" %(Dst))
> -                        self.BuildTargetList.append('\t' + self._CP_TEMPLATE_[self._FileType] %{'Src': Src, 'Dst': Dst})
> +                        self.BuildTargetList.append('\t' +
> + self._CP_TEMPLATE_[self._Platform] %{'Src': Src, 'Dst': Dst})
> 
>              FfsCmdList = Cmd[0]
>              for index, Str in enumerate(FfsCmdList):
> @@ -1217,7 +1223,7 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
>      # Compose a dict object containing information used to do replacement in template
>      @property
>      def _TemplateDict(self):
> -        Separator = self._SEP_[self._FileType]
> +        Separator = self._SEP_[self._Platform]
>          MyAgo = self._AutoGenObject
>          if self._FileType not in MyAgo.CustomMakefile:
>              EdkLogger.error('build', OPTION_NOT_SUPPORTED, "No custom makefile for %s" % self._FileType, @@ -1247,7 +1253,7 @@
> ${BEGIN}\t-@${create_directory_command}\n${END}\
>                      ToolsDef.append("%s_%s = %s" % (Tool, Attr, MyAgo.BuildOption[Tool][Attr]))
>              ToolsDef.append("")
> 
> -        MakefileName = self._FILE_NAME_[self._FileType]
> +        MakefileName = self.getMakefileName()
>          MakefileTemplateDict = {
>              "makefile_header"           : self._FILE_HEADER_[self._FileType],
>              "makefile_path"             : os.path.join("$(MODULE_BUILD_DIR)", MakefileName),
> @@ -1280,8 +1286,8 @@ ${BEGIN}\t-@${create_directory_command}\n${END}\
>              "separator"                 : Separator,
>              "module_tool_definitions"   : ToolsDef,
> 
> -            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
> -            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
> +            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
> +            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
> 
>              "create_directory_command"  : self.GetCreateDirectoryCommand(self.IntermediateDirectoryList),
>              "custom_makefile_content"   : CustomMakefile
> @@ -1408,7 +1414,7 @@ cleanlib:
>      # Compose a dict object containing information used to do replacement in template
>      @property
>      def _TemplateDict(self):
> -        Separator = self._SEP_[self._FileType]
> +        Separator = self._SEP_[self._Platform]
> 
>          MyAgo = self._AutoGenObject
>          if "MAKE" not in MyAgo.ToolDefinition or "PATH" not in MyAgo.ToolDefinition["MAKE"]:
> @@ -1419,13 +1425,13 @@ cleanlib:
>          self.ModuleBuildDirectoryList = self.GetModuleBuildDirectoryList()
>          self.LibraryBuildDirectoryList = self.GetLibraryBuildDirectoryList()
> 
> -        MakefileName = self._FILE_NAME_[self._FileType]
> +        MakefileName = self.getMakefileName()
>          LibraryMakefileList = []
>          LibraryMakeCommandList = []
>          for D in self.LibraryBuildDirectoryList:
>              D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})
>              Makefile = os.path.join(D, MakefileName)
> -            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
> +            Command = self._MAKE_TEMPLATE_[self._Platform] %
> + {"file":Makefile}
>              LibraryMakefileList.append(Makefile)
>              LibraryMakeCommandList.append(Command)
>          self.LibraryMakeCommandList = LibraryMakeCommandList @@ -1435,7 +1441,7 @@ cleanlib:
>          for D in self.ModuleBuildDirectoryList:
>              D = self.PlaceMacro(D, {"BUILD_DIR":MyAgo.BuildDir})
>              Makefile = os.path.join(D, MakefileName)
> -            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":Makefile}
> +            Command = self._MAKE_TEMPLATE_[self._Platform] %
> + {"file":Makefile}
>              ModuleMakefileList.append(Makefile)
>              ModuleMakeCommandList.append(Command)
> 
> @@ -1455,8 +1461,8 @@ cleanlib:
> 
>              "toolchain_tag"             : MyAgo.ToolChain,
>              "build_target"              : MyAgo.BuildTarget,
> -            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
> -            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
> +            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
> +            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
>              "build_architecture_list"   : MyAgo.Arch,
>              "architecture"              : MyAgo.Arch,
>              "separator"                 : Separator,
> @@ -1514,7 +1520,7 @@ class TopLevelMakefile(BuildFile):
>      # Compose a dict object containing information used to do replacement in template
>      @property
>      def _TemplateDict(self):
> -        Separator = self._SEP_[self._FileType]
> +        Separator = self._SEP_[self._Platform]
> 
>          # any platform autogen object is ok because we just need common information
>          MyAgo = self._AutoGenObject
> @@ -1570,10 +1576,10 @@ class TopLevelMakefile(BuildFile):
>              else:
>                  ExtraOption += " --pcd " + pcdname + '=' + pcd[3]
> 
> -        MakefileName = self._FILE_NAME_[self._FileType]
> +        MakefileName = self.getMakefileName()
>          SubBuildCommandList = []
>          for A in MyAgo.ArchList:
> -            Command = self._MAKE_TEMPLATE_[self._FileType] % {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
> +            Command = self._MAKE_TEMPLATE_[self._Platform] %
> + {"file":os.path.join("$(BUILD_DIR)", A, MakefileName)}
>              SubBuildCommandList.append(Command)
> 
>          MakefileTemplateDict = {
> @@ -1588,8 +1594,8 @@ class TopLevelMakefile(BuildFile):
> 
>              "toolchain_tag"             : MyAgo.ToolChain,
>              "build_target"              : MyAgo.BuildTarget,
> -            "shell_command_code"        : list(self._SHELL_CMD_[self._FileType].keys()),
> -            "shell_command"             : list(self._SHELL_CMD_[self._FileType].values()),
> +            "shell_command_code"        : list(self._SHELL_CMD_[self._Platform].keys()),
> +            "shell_command"             : list(self._SHELL_CMD_[self._Platform].values()),
>              'arch'                      : list(MyAgo.ArchList),
>              "build_architecture_list"   : ','.join(MyAgo.ArchList),
>              "separator"                 : Separator,
> diff --git a/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py b/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
> index bb6e883d84ca6decc97514f95a35bd6db8714eed..c41dc33c4bcf33d30cf8bfc829718ed96923ff8f 100644
> --- a/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
> +++ b/BaseTools/Source/Python/AutoGen/IncludesAutoGen.py
> @@ -2,6 +2,7 @@
>  # Build cache intermediate result and state  #  # Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
> +# Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
>  # SPDX-License-Identifier: BSD-2-Clause-Patent  #  from Common.caching import cached_property @@ -12,20 +13,6 @@ from
> Common.Misc import SaveFileOnChange, PathClass  from Common.Misc import TemplateString  import sys  gIsFileMap = {} -if
> sys.platform == "win32":
> -    _INCLUDE_DEPS_TEMPLATE = TemplateString('''
> -${BEGIN}
> -!IF EXIST(${deps_file})
> -!INCLUDE ${deps_file}
> -!ENDIF
> -${END}
> -        ''')
> -else:
> -    _INCLUDE_DEPS_TEMPLATE = TemplateString('''
> -${BEGIN}
> --include ${deps_file}
> -${END}
> -        ''')
> 
>  DEP_FILE_TAIL = "# Updated \n"
> 
> @@ -59,6 +46,25 @@ class IncludesAutoGen():
> 
>      def CreateDepsInclude(self):
>          deps_file = {'deps_file':self.deps_files}
> +
> +        MakePath = self.module_autogen.BuildOption.get('MAKE', {}).get('PATH')
> +        if not MakePath:
> +            EdkLogger.error("build", PARAMETER_MISSING, Message="No Make path available.")
> +        elif "nmake" in MakePath:
> +            _INCLUDE_DEPS_TEMPLATE = TemplateString('''
> +        ${BEGIN}
> +        !IF EXIST(${deps_file})
> +        !INCLUDE ${deps_file}
> +        !ENDIF
> +        ${END}
> +               ''')
> +        else:
> +            _INCLUDE_DEPS_TEMPLATE = TemplateString('''
> +        ${BEGIN}
> +        -include ${deps_file}
> +        ${END}
> +               ''')
> +
>          try:
>              deps_include_str = _INCLUDE_DEPS_TEMPLATE.Replace(deps_file)
>          except Exception as e:
> diff --git a/BaseTools/Source/Python/build/build.py b/BaseTools/Source/Python/build/build.py
> index 34acdccbdbd00a3d10f9c6c42004f59a96ff0063..a2a4337b7524163049c77f99874ce1a7aa4c1644 100755
> --- a/BaseTools/Source/Python/build/build.py
> +++ b/BaseTools/Source/Python/build/build.py
> @@ -4,6 +4,7 @@
>  #  Copyright (c) 2014, Hewlett-Packard Development Company, L.P.<BR>  #  Copyright (c) 2007 - 2019, Intel Corporation. All rights
> reserved.<BR>  #  Copyright (c) 2018, Hewlett Packard Enterprise Development, L.P.<BR>
> +#  Copyright (c) 2020, ARM Limited. All rights reserved.<BR>
>  #
>  #  SPDX-License-Identifier: BSD-2-Clause-Patent  # @@ -1250,7 +1251,7 @@ class Build():
>                                  (AutoGenObject.BuildTarget, AutoGenObject.ToolChain, AutoGenObject.Arch),
>                              ExtraData=str(AutoGenObject))
> 
> -        makefile = GenMake.BuildFile(AutoGenObject)._FILE_NAME_[GenMake.gMakeType]
> +        makefile = GenMake.BuildFile(AutoGenObject).getMakefileName()
> 
>          # run
>          if Target == 'run':
> @@ -2039,10 +2040,10 @@ class Build():
>              ModuleBuildDirectoryList = data_pipe.Get("ModuleBuildDirectoryList")
> 
>              for m_build_dir in LibraryBuildDirectoryList:
> -                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile._FILE_NAME_[GenMake.gMakeType])):
> +                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile.getMakefileName())):
>                      return None
>              for m_build_dir in ModuleBuildDirectoryList:
> -                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile._FILE_NAME_[GenMake.gMakeType])):
> +                if not os.path.exists(os.path.join(m_build_dir,GenMake.BuildFile.getMakefileName())):
>                      return None
>              Wa = WorkSpaceInfo(
>                  workspacedir,active_p,target,toolchain,archlist
> --
> 'Guid(CE165669-3EF3-493F-B85D-6190EE5B9759)'
> 


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2020-02-03 12:09 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-01-13 14:40 [PATCH v1 1/1] BaseTools: Rationalise makefile generation PierreGondois
2020-01-22 17:37 ` PierreGondois
2020-02-03 12:09   ` Liming Gao

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox