[edk2] [RFC Patch 2/3] BaseTools/Scripts: Add python script to run a makefile

Michael D Kinney posted 3 patches 7 years, 4 months ago
[edk2] [RFC Patch 2/3] BaseTools/Scripts: Add python script to run a makefile
Posted by Michael D Kinney 7 years, 4 months ago
Add the python script RunMakefile.py that can be used
in a PREBUILD/POSTBUIILD action to invoke a makefile
passing in context as makefile defines.  The command
line arguments passed into RunMakefile.py are converted
to the following set of defines.

* ACTIVE_PLATFORM
* TARGET_ARCH
* TOOL_CHAIN_TAG
* CONF_DIRECTORY
* TARGET
* EXTRA_FLAGS

In addition, a makefile can access the system environment
variables including WORKSPACE and PACKAGES_PATH.

The makefile target from the following set is also passed
into the makefile.  If no target is passed into build, then
the 'all' target is used.

[all|fds|genc|genmake|clean|cleanall|cleanlib|modules|libraries|run]

A platform DSC file can use a statements in the [Defines]
section of the following form to use this script.  MAKEFILE
is a WORKSPACE or PACKAGES_PATH relative path to the makefile
to run.

[Defines]
  PREBUILD  = python BaseTools/Script/RunMakefile.py --makefile MAKEFILE
  POSTBUILD = python BaseTools/Script/RunMakefile.py --makefile MAKEFILE

Cc: Liming Gao <liming.gao@intel.com>
Cc: Yonghong Zhu <yonghong.zhu@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Michael Kinney <michael.d.kinney@intel.com>
---
 BaseTools/Scripts/RunMakefile.py | 178 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 178 insertions(+)
 create mode 100644 BaseTools/Scripts/RunMakefile.py

diff --git a/BaseTools/Scripts/RunMakefile.py b/BaseTools/Scripts/RunMakefile.py
new file mode 100644
index 0000000000..48bc198c76
--- /dev/null
+++ b/BaseTools/Scripts/RunMakefile.py
@@ -0,0 +1,178 @@
+## @file
+# Run a makefile as part of a PREBUILD or POSTBUILD action.
+#
+# Copyright (c) 2017, 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
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+
+'''
+RunMakefile.py
+'''
+
+import os
+import sys
+import argparse
+import subprocess
+
+#
+# Globals for help information
+#
+__prog__        = 'RunMakefile'
+__version__     = '%s Version %s' % (__prog__, '1.0')
+__copyright__   = 'Copyright (c) 2017, Intel Corporation. All rights reserved.'
+__description__ = 'Run a makefile as part of a PREBUILD or POSTBUILD action.\n'
+
+#
+# Globals
+#
+gArgs = None
+
+def Log(Message):
+  if not gArgs.Verbose:
+    return
+  sys.stdout.write (__prog__ + ': ' + Message + '\n')
+
+def Error(Message, ExitValue=1):
+  sys.stderr.write (__prog__ + ': ERROR: ' + Message + '\n')
+  sys.exit (ExitValue)
+
+def RelativePath(target):
+  return os.path.relpath (target, gWorkspace)
+
+def NormalizePath(target):
+  if isinstance(target, tuple):
+    return os.path.normpath (os.path.join (*target))
+  else:
+    return os.path.normpath (target)
+
+if __name__ == '__main__':
+  #
+  # Create command line argument parser object
+  #
+  parser = argparse.ArgumentParser (
+                      prog = __prog__,
+                      version = __version__,
+                      description = __description__ + __copyright__,
+                      conflict_handler = 'resolve'
+                      )
+  parser.add_argument (
+           '-a', '--arch', dest = 'Arch', nargs = '+', action = 'append',
+           required = True,
+           help = '''ARCHS is one of list: IA32, X64, IPF, ARM, AARCH64 or EBC,
+                     which overrides target.txt's TARGET_ARCH definition. To
+                     specify more archs, please repeat this option.'''
+           )
+  parser.add_argument (
+           '-t', '--tagname', dest = 'ToolChain', required = True,
+           help = '''Using the Tool Chain Tagname to build the platform,
+                     overriding target.txt's TOOL_CHAIN_TAG definition.'''
+           )
+  parser.add_argument (
+           '-p', '--platform', dest = 'PlatformFile', required = True,
+           help = '''Build the platform specified by the DSC file name argument,
+                     overriding target.txt's ACTIVE_PLATFORM definition.'''
+           )
+  parser.add_argument (
+           '-b', '--buildtarget', dest = 'BuildTarget', required = True,
+           help = '''Using the TARGET to build the platform, overriding
+                     target.txt's TARGET definition.'''
+           )
+  parser.add_argument (
+           '--conf=', dest = 'ConfDirectory', required = True,
+           help = '''Specify the customized Conf directory.'''
+           )
+  parser.add_argument (
+           '-D', '--define', dest = 'Define', nargs='*', action = 'append',
+           help = '''Macro: "Name [= Value]".'''
+           )
+  parser.add_argument (
+           '--makefile', dest = 'Makefile', required = True,
+           help = '''Makefile to run passing in arguments as makefile defines.'''
+           )
+  parser.add_argument (
+           '-v', '--verbose', dest = 'Verbose', action = 'store_true',
+           help = '''Turn on verbose output with informational messages printed'''
+           )
+
+  #
+  # Parse command line arguments
+  #
+  gArgs, remaining = parser.parse_known_args()
+  gArgs.BuildType = 'all'
+  for BuildType in ['all', 'fds', 'genc', 'genmake', 'clean', 'cleanall', 'modules', 'libraries', 'run']:
+    if BuildType in remaining:
+      gArgs.BuildType = BuildType
+      remaining.remove(BuildType)
+      break
+  gArgs.Remaining = ' '.join(remaining)
+
+  #
+  # Start
+  #
+  Log ('Start')
+
+  #
+  # Find makefile in WORKSPACE or PACKAGES_PATH
+  #
+  PathList = ['']
+  try:
+    PathList.append(os.environ['WORKSPACE'])
+  except:
+    Error ('WORKSPACE environment variable not set')
+  try:
+    PathList += os.environ['PACKAGES_PATH'].split(os.pathsep)
+  except:
+    pass
+  for Path in PathList:
+    Makefile = NormalizePath((Path, gArgs.Makefile))
+    if os.path.exists (Makefile):
+      break
+  if not os.path.exists(Makefile):
+    Error ('makefile %s not found' % (gArgs.Makefile))
+
+  #
+  # Build command line arguments converting build arguments to makefile defines
+  #
+  CommandLine = [Makefile]
+  CommandLine.append('TARGET_ARCH="%s"' % (' '.join([Item[0] for Item in gArgs.Arch])))
+  CommandLine.append('TOOL_CHAIN_TAG="%s"' % (gArgs.ToolChain))
+  CommandLine.append('TARGET="%s"' % (gArgs.BuildTarget))
+  CommandLine.append('ACTIVE_PLATFORM="%s"' % (gArgs.PlatformFile))
+  CommandLine.append('CONF_DIRECTORY="%s"' % (gArgs.ConfDirectory))
+  if gArgs.Define:
+    for Item in gArgs.Define:
+      if '=' not in Item[0]:
+        continue
+      Item = Item[0].split('=',1)
+      CommandLine.append('%s="%s"' % (Item[0], Item[1]))
+  CommandLine.append('EXTRA_FLAGS="%s"' % (gArgs.Remaining))
+  CommandLine.append(gArgs.BuildType)
+  if sys.platform == "win32":
+    CommandLine = 'nmake /f %s' % (' '.join(CommandLine))
+  else:
+    CommandLine = 'make -f %s' % (' '.join(CommandLine))
+
+  #
+  # Run the makefile
+  #
+  try:
+    Process = subprocess.Popen(CommandLine, shell=True)
+  except:
+    Error ('make command not available.  Please verify PATH')
+  Process.communicate()
+
+  #
+  # Done
+  #
+  Log ('Done')
+
+  #
+  # Return status from running the makefile
+  #
+  sys.exit(Process.returncode)
-- 
2.13.1.windows.2

_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel