## @file
# Run a makefile as part of a PREBUILD or POSTBUILD action.
#
# Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#

'''
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, 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)
