## @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, 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) |