RunMakefile.py 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. ## @file
  2. # Run a makefile as part of a PREBUILD or POSTBUILD action.
  3. #
  4. # Copyright (c) 2017, Intel Corporation. All rights reserved.<BR>
  5. # SPDX-License-Identifier: BSD-2-Clause-Patent
  6. #
  7. '''
  8. RunMakefile.py
  9. '''
  10. import os
  11. import sys
  12. import argparse
  13. import subprocess
  14. #
  15. # Globals for help information
  16. #
  17. __prog__ = 'RunMakefile'
  18. __version__ = '%s Version %s' % (__prog__, '1.0')
  19. __copyright__ = 'Copyright (c) 2017, Intel Corporation. All rights reserved.'
  20. __description__ = 'Run a makefile as part of a PREBUILD or POSTBUILD action.\n'
  21. #
  22. # Globals
  23. #
  24. gArgs = None
  25. def Log(Message):
  26. if not gArgs.Verbose:
  27. return
  28. sys.stdout.write (__prog__ + ': ' + Message + '\n')
  29. def Error(Message, ExitValue=1):
  30. sys.stderr.write (__prog__ + ': ERROR: ' + Message + '\n')
  31. sys.exit (ExitValue)
  32. def RelativePath(target):
  33. return os.path.relpath (target, gWorkspace)
  34. def NormalizePath(target):
  35. if isinstance(target, tuple):
  36. return os.path.normpath (os.path.join (*target))
  37. else:
  38. return os.path.normpath (target)
  39. if __name__ == '__main__':
  40. #
  41. # Create command line argument parser object
  42. #
  43. parser = argparse.ArgumentParser (
  44. prog = __prog__,
  45. version = __version__,
  46. description = __description__ + __copyright__,
  47. conflict_handler = 'resolve'
  48. )
  49. parser.add_argument (
  50. '-a', '--arch', dest = 'Arch', nargs = '+', action = 'append',
  51. required = True,
  52. help = '''ARCHS is one of list: IA32, X64, IPF, ARM, AARCH64 or EBC,
  53. which overrides target.txt's TARGET_ARCH definition. To
  54. specify more archs, please repeat this option.'''
  55. )
  56. parser.add_argument (
  57. '-t', '--tagname', dest = 'ToolChain', required = True,
  58. help = '''Using the Tool Chain Tagname to build the platform,
  59. overriding target.txt's TOOL_CHAIN_TAG definition.'''
  60. )
  61. parser.add_argument (
  62. '-p', '--platform', dest = 'PlatformFile', required = True,
  63. help = '''Build the platform specified by the DSC file name argument,
  64. overriding target.txt's ACTIVE_PLATFORM definition.'''
  65. )
  66. parser.add_argument (
  67. '-b', '--buildtarget', dest = 'BuildTarget', required = True,
  68. help = '''Using the TARGET to build the platform, overriding
  69. target.txt's TARGET definition.'''
  70. )
  71. parser.add_argument (
  72. '--conf=', dest = 'ConfDirectory', required = True,
  73. help = '''Specify the customized Conf directory.'''
  74. )
  75. parser.add_argument (
  76. '-D', '--define', dest = 'Define', nargs='*', action = 'append',
  77. help = '''Macro: "Name [= Value]".'''
  78. )
  79. parser.add_argument (
  80. '--makefile', dest = 'Makefile', required = True,
  81. help = '''Makefile to run passing in arguments as makefile defines.'''
  82. )
  83. parser.add_argument (
  84. '-v', '--verbose', dest = 'Verbose', action = 'store_true',
  85. help = '''Turn on verbose output with informational messages printed'''
  86. )
  87. #
  88. # Parse command line arguments
  89. #
  90. gArgs, remaining = parser.parse_known_args()
  91. gArgs.BuildType = 'all'
  92. for BuildType in ['all', 'fds', 'genc', 'genmake', 'clean', 'cleanall', 'modules', 'libraries', 'run']:
  93. if BuildType in remaining:
  94. gArgs.BuildType = BuildType
  95. remaining.remove(BuildType)
  96. break
  97. gArgs.Remaining = ' '.join(remaining)
  98. #
  99. # Start
  100. #
  101. Log ('Start')
  102. #
  103. # Find makefile in WORKSPACE or PACKAGES_PATH
  104. #
  105. PathList = ['']
  106. try:
  107. PathList.append(os.environ['WORKSPACE'])
  108. except:
  109. Error ('WORKSPACE environment variable not set')
  110. try:
  111. PathList += os.environ['PACKAGES_PATH'].split(os.pathsep)
  112. except:
  113. pass
  114. for Path in PathList:
  115. Makefile = NormalizePath((Path, gArgs.Makefile))
  116. if os.path.exists (Makefile):
  117. break
  118. if not os.path.exists(Makefile):
  119. Error ('makefile %s not found' % (gArgs.Makefile))
  120. #
  121. # Build command line arguments converting build arguments to makefile defines
  122. #
  123. CommandLine = [Makefile]
  124. CommandLine.append('TARGET_ARCH="%s"' % (' '.join([Item[0] for Item in gArgs.Arch])))
  125. CommandLine.append('TOOL_CHAIN_TAG="%s"' % (gArgs.ToolChain))
  126. CommandLine.append('TARGET="%s"' % (gArgs.BuildTarget))
  127. CommandLine.append('ACTIVE_PLATFORM="%s"' % (gArgs.PlatformFile))
  128. CommandLine.append('CONF_DIRECTORY="%s"' % (gArgs.ConfDirectory))
  129. if gArgs.Define:
  130. for Item in gArgs.Define:
  131. if '=' not in Item[0]:
  132. continue
  133. Item = Item[0].split('=', 1)
  134. CommandLine.append('%s="%s"' % (Item[0], Item[1]))
  135. CommandLine.append('EXTRA_FLAGS="%s"' % (gArgs.Remaining))
  136. CommandLine.append(gArgs.BuildType)
  137. if sys.platform == "win32":
  138. CommandLine = 'nmake /f %s' % (' '.join(CommandLine))
  139. else:
  140. CommandLine = 'make -f %s' % (' '.join(CommandLine))
  141. #
  142. # Run the makefile
  143. #
  144. try:
  145. Process = subprocess.Popen(CommandLine, shell=True)
  146. except:
  147. Error ('make command not available. Please verify PATH')
  148. Process.communicate()
  149. #
  150. # Done
  151. #
  152. Log ('Done')
  153. #
  154. # Return status from running the makefile
  155. #
  156. sys.exit(Process.returncode)