git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4152 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			281 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			281 lines
		
	
	
		
			9.3 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
## @file BuildEnv.py
 | 
						|
# Initialize Environment for building
 | 
						|
#
 | 
						|
#  Copyright (c) 2007, Intel Corporation
 | 
						|
#
 | 
						|
#  All rights reserved. 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.
 | 
						|
#
 | 
						|
 | 
						|
##
 | 
						|
# Import Modules
 | 
						|
#
 | 
						|
import os
 | 
						|
import os.path
 | 
						|
import pickle
 | 
						|
import shutil
 | 
						|
import sys
 | 
						|
 | 
						|
from optparse import OptionParser
 | 
						|
 | 
						|
# Version and Copyright
 | 
						|
VersionNumber = "0.01"
 | 
						|
__version__ = "%prog Version " + VersionNumber
 | 
						|
__copyright__ = "Copyright (c) 2007, Intel Corporation  All rights reserved."
 | 
						|
 | 
						|
class SetupBuildEnvironmentApp:
 | 
						|
 | 
						|
  def __init__(self):
 | 
						|
    (self.Opt, self.Args) = self.ProcessCommandLine()
 | 
						|
    self.SetupDefaults()
 | 
						|
    self.DetermineEnvironment()
 | 
						|
    self.CopyTemplates()
 | 
						|
    self.WriteEnvironmentConfigurationScript()
 | 
						|
 | 
						|
  def SetupDefaults(self):
 | 
						|
    self.itemsToConfigure = (
 | 
						|
      'compiler',
 | 
						|
      'compiler-prefix',
 | 
						|
      'templates and Conf directory',
 | 
						|
      )
 | 
						|
 | 
						|
    self.defaults = {
 | 
						|
      'compiler': {
 | 
						|
        'options': ('gcc', 'icc'),
 | 
						|
        'default': 'gcc',
 | 
						|
        },
 | 
						|
      'compiler-prefix': {
 | 
						|
        'options': ('/usr/bin', '/usr/bin/x86_64-pc-mingw32-'),
 | 
						|
        'freeform': True,
 | 
						|
        },
 | 
						|
      'templates and Conf directory': {
 | 
						|
        'options': (
 | 
						|
          'copy once (no-overwrite)',
 | 
						|
          'copy with overwrite',
 | 
						|
          'symlink to templates',
 | 
						|
          'do nothing',
 | 
						|
          ),
 | 
						|
        'default': 'copy once (no-overwrite)',
 | 
						|
        },
 | 
						|
      }
 | 
						|
 | 
						|
  def ProcessCommandLine(self):
 | 
						|
    Parser = OptionParser(description=__copyright__,version=__version__,prog="BaseTools/BuildEnv")
 | 
						|
    Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
 | 
						|
    Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
 | 
						|
                                                                               "including library instances selected, final dependency expression, "\
 | 
						|
                                                                               "and warning messages, etc.")
 | 
						|
    Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")
 | 
						|
 | 
						|
    if os.environ.has_key('WORKSPACE'):
 | 
						|
      default = os.environ['WORKSPACE']
 | 
						|
    else:
 | 
						|
      default = os.getcwd()
 | 
						|
    Parser.add_option("--workspace", action="store", type="string", help="Base director of tree to configure", default=default)
 | 
						|
 | 
						|
    (Opt, Args)=Parser.parse_args()
 | 
						|
    Parser.print_version()
 | 
						|
 | 
						|
    return (Opt, Args)
 | 
						|
 | 
						|
  def DetermineEnvironment(self):
 | 
						|
    confFilename = os.path.join(os.path.expanduser('~'), '.edk-build-env.pickle')
 | 
						|
    try:
 | 
						|
      confFile = open(confFilename, 'r')
 | 
						|
      conf = pickle.load(confFile)
 | 
						|
      confFile.close()
 | 
						|
    except Exception:
 | 
						|
      conf = {}
 | 
						|
    self.conf = conf
 | 
						|
 | 
						|
    for item in self.itemsToConfigure:
 | 
						|
      if not conf.has_key(item):
 | 
						|
        self.AskForValueOfOption(item)
 | 
						|
 | 
						|
    while True:
 | 
						|
      self.SummarizeCurrentState()
 | 
						|
 | 
						|
      if not self.Opt.quiet:
 | 
						|
        response = raw_input('Would you like to change anything? (default=no): ')
 | 
						|
        response = response.strip()
 | 
						|
      else:
 | 
						|
        response = ''
 | 
						|
 | 
						|
      if response.lower() in ('', 'n', 'no'):
 | 
						|
        break
 | 
						|
 | 
						|
      for item in self.itemsToConfigure:
 | 
						|
        self.AskForValueOfOption(item)
 | 
						|
 | 
						|
    confFile = open(confFilename, 'w')
 | 
						|
    pickle.dump(conf, confFile)
 | 
						|
    confFile.close()
 | 
						|
 | 
						|
  def AskCompiler(self):
 | 
						|
    self.AskForValueOfOption('compiler')
 | 
						|
 | 
						|
  def AskCompilerPrefix(self):
 | 
						|
    self.AskForValueOfOption('compiler-prefix')
 | 
						|
 | 
						|
  def AskForValueOfOption(self, option):
 | 
						|
    options = self.defaults[option]['options']
 | 
						|
    if self.defaults[option].has_key('default'):
 | 
						|
      default = self.defaults[option]['default']
 | 
						|
    else:
 | 
						|
      default = None
 | 
						|
    if self.defaults[option].has_key('freeform'):
 | 
						|
      freeform = self.defaults[option]['freeform']
 | 
						|
    else:
 | 
						|
      freeform = False
 | 
						|
    self.AskForValue(option, options, default, freeform)
 | 
						|
 | 
						|
  def AskForValue(self, index, options, default=None, freeform=False):
 | 
						|
    conf = self.conf
 | 
						|
    if conf.has_key(index):
 | 
						|
      default = conf[index]
 | 
						|
    options = list(options) # in case options came in as a tuple
 | 
						|
    assert((default == '') or (default is None) or ('' not in options))
 | 
						|
    if (default is not None) and (default not in options):
 | 
						|
      options.append(default)
 | 
						|
    if (freeform and ('' not in options)):
 | 
						|
      options.append('')
 | 
						|
    options.sort()
 | 
						|
    while True:
 | 
						|
      print
 | 
						|
      if len(options) > 0:
 | 
						|
        print 'Options for', index
 | 
						|
        for i in range(len(options)):
 | 
						|
          print '  %d.' % (i + 1),
 | 
						|
          if options[i] != '':
 | 
						|
            print options[i],
 | 
						|
          else:
 | 
						|
            print '(empty string)',
 | 
						|
          if options[i] == default:
 | 
						|
            print '(default)'
 | 
						|
          else:
 | 
						|
            print
 | 
						|
 | 
						|
      if len(options) > 0:
 | 
						|
        prompt = 'Select number or type value: '
 | 
						|
      else:
 | 
						|
        prompt = 'Type value for %s: ' % index
 | 
						|
      response = raw_input(prompt)
 | 
						|
      response = response.strip()
 | 
						|
 | 
						|
      if response.isdigit():
 | 
						|
        response = int(response)
 | 
						|
        if response > len(options):
 | 
						|
          print 'ERROR: Invalid number selection!'
 | 
						|
          continue
 | 
						|
        response = options[response - 1]
 | 
						|
      elif (response == '') and (default is not None):
 | 
						|
        response = default
 | 
						|
 | 
						|
      if (not freeform) and (response not in options):
 | 
						|
        print 'ERROR: Invalid selection! (must be from list)'
 | 
						|
        continue
 | 
						|
 | 
						|
      break
 | 
						|
 | 
						|
    conf[index] = response
 | 
						|
    print 'Using', conf[index], 'for', index
 | 
						|
 | 
						|
  def SummarizeCurrentState(self):
 | 
						|
    print
 | 
						|
    print 'Current configuration:'
 | 
						|
    conf = self.conf
 | 
						|
    for item in self.itemsToConfigure:
 | 
						|
      value = conf[item]
 | 
						|
      if value == '': value = '(empty string)'
 | 
						|
      print ' ', item, '->', value
 | 
						|
 | 
						|
  def CopyTemplates(self):
 | 
						|
    todo = self.conf['templates and Conf directory']
 | 
						|
    workspace = os.path.realpath(self.Opt.workspace)
 | 
						|
    templatesDir = \
 | 
						|
      os.path.join(workspace, 'BaseTools', 'ConfTemplates', sys.platform.title())
 | 
						|
    confDir = \
 | 
						|
      os.path.join(workspace, 'Conf')
 | 
						|
    print
 | 
						|
    print 'Templates & Conf directory'
 | 
						|
    print '  Templates dir:', self.RelativeToWorkspace(templatesDir)
 | 
						|
    for filename in os.listdir(templatesDir):
 | 
						|
      if filename.startswith('.'): continue
 | 
						|
 | 
						|
      srcFilename = os.path.join(templatesDir, filename)
 | 
						|
      destFilename = os.path.join(confDir, filename)
 | 
						|
      print ' ', self.RelativeToWorkspace(destFilename),
 | 
						|
 | 
						|
      if todo == 'copy once (no-overwrite)':
 | 
						|
        if os.path.exists(destFilename):
 | 
						|
          print '[skipped, already exists]'
 | 
						|
        else:
 | 
						|
          shutil.copy(srcFilename, destFilename)
 | 
						|
          print '[copied]'
 | 
						|
      elif todo == 'copy with overwrite':
 | 
						|
        overwrite = ''
 | 
						|
        if os.path.exists(destFilename):
 | 
						|
          os.remove(destFilename)
 | 
						|
          overwrite = ', overwritten'
 | 
						|
        shutil.copy(srcFilename, destFilename)
 | 
						|
        print '[copied' + overwrite + ']'
 | 
						|
      elif todo == 'symlink to templates':
 | 
						|
        if os.path.exists(destFilename):
 | 
						|
          if not os.path.islink(destFilename):
 | 
						|
            raise Exception, '%s is not a symlink! (remove file if you want to start using symlinks)' % \
 | 
						|
                             (self.RelativeToWorkspace(destFilename))
 | 
						|
          os.remove(destFilename)
 | 
						|
        os.symlink(srcFilename, destFilename)
 | 
						|
        print '[symlinked]'
 | 
						|
      elif todo == 'do nothing':
 | 
						|
        print '[skipped by user request]'
 | 
						|
      else:
 | 
						|
        raise Exception, 'Unknown action for templates&conf: %s' % todo
 | 
						|
 | 
						|
  def WriteEnvironmentConfigurationScript(self):
 | 
						|
    workspace = os.path.realpath(self.Opt.workspace)
 | 
						|
    scriptFilename = os.path.join(workspace, 'Conf', 'BuildEnv.sh')
 | 
						|
    print
 | 
						|
    print 'Storing environment configuration into',
 | 
						|
    print   self.RelativeToWorkspace(scriptFilename)
 | 
						|
    script = open(scriptFilename, 'w')
 | 
						|
 | 
						|
    print >> script, 'export WORKSPACE="%s"' % workspace
 | 
						|
    print >> script, 'export TOOLCHAIN="%s"' % self.conf['compiler']
 | 
						|
    print >> script, 'export EDK_CC_PATH_PREFIX="%s"' % self.conf['compiler-prefix']
 | 
						|
 | 
						|
    EDK_TOOLS_PATH = os.path.join(workspace, 'BaseTools')
 | 
						|
    print >> script, 'if [ $EDK_TOOLS_PATH=="" ]'
 | 
						|
    print >> script, 'then'
 | 
						|
    print >> script, '  export EDK_TOOLS_PATH="%s"' % EDK_TOOLS_PATH
 | 
						|
    print >> script, 'fi'
 | 
						|
 | 
						|
    #
 | 
						|
    # Change PATH variable
 | 
						|
    #
 | 
						|
    newPath = os.environ['PATH'].split(os.path.pathsep)
 | 
						|
    binDir = \
 | 
						|
      os.path.join(workspace, 'BaseTools', 'Bin', sys.platform.title())
 | 
						|
    if binDir not in newPath:
 | 
						|
      newPath.append(binDir)
 | 
						|
    newPath = os.path.pathsep.join(newPath)
 | 
						|
    print >> script, 'export PATH=%s' % newPath
 | 
						|
 | 
						|
    script.close()
 | 
						|
 | 
						|
  def RelativeToWorkspace(self, path):
 | 
						|
    workspace = os.path.realpath(self.Opt.workspace)
 | 
						|
    for prefix in (workspace + os.path.sep, workspace):
 | 
						|
      if path.startswith(prefix):
 | 
						|
        return path[len(prefix):]
 | 
						|
    
 | 
						|
 | 
						|
if __name__ == '__main__':
 | 
						|
  SetupBuildEnvironmentApp()
 | 
						|
 |