## @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.DeleteEnvironmentConfigurationScript() self.CopyTemplates() self.WriteEnvironmentConfigurationScript() def SetupDefaults(self): self.itemsToConfigure = ( 'compiler', #'compiler-prefix', 'templates', ) self.defaults = { 'compiler': { 'options': ('gcc', 'icc'), 'default': 'gcc', }, 'compiler-prefix': { 'options': ('/usr/bin', '/usr/bin/x86_64-pc-mingw32-'), 'freeform': True, }, 'templates': { 'description': '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 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 if self.defaults[option].has_key('description'): description = self.defaults[option]['description'] else: description = option conf = self.conf if conf.has_key(option): default = conf[option] 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', description 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: ' 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[option] = response print 'Using', conf[option], 'for', description 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'] workspace = os.path.realpath(self.Opt.workspace) templatesDir = \ os.path.join(workspace, 'BaseTools', 'Conf') confDir = \ os.path.join(workspace, 'Conf') print print 'Templates & Conf directory' print ' Templates dir:', self.RelativeToWorkspace(templatesDir) for filename in os.listdir(templatesDir): if not filename.endswith('.template'): continue srcFilename = os.path.join(templatesDir, filename) destFilename = os.path.join(confDir, filename[:-len('template')] + 'txt') 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.islink(destFilename) or 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(os.path.join('..', self.RelativeToWorkspace(srcFilename)), destFilename) print '[symlinked]' elif todo == 'do nothing': print '[skipped by user request]' else: raise Exception, 'Unknown action for templates&conf: %s' % todo def DeleteEnvironmentConfigurationScript(self): workspace = os.path.realpath(self.Opt.workspace) scriptFilename = os.path.join(workspace, 'Conf', 'BuildEnv.sh') if os.path.exists(scriptFilename): os.remove(scriptFilename) 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 COMPILER_SUITE_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()