xref: /petsc/config/BuildSystem/script.py (revision 7efd6112ee2ef33760f150343450f215bafd87bb)
1179860b2SJed Brownimport sys
2179860b2SJed Brownif not hasattr(sys, 'version_info'):
3179860b2SJed Brown  print '*** Python version 1 is not supported. Please get the latest version from www.python.org ***'
4179860b2SJed Brown  sys.exit(4)
5179860b2SJed Brown
6179860b2SJed Brownimport cPickle
7179860b2SJed Brown
8179860b2SJed Browntry:
9179860b2SJed Brown  import subprocess
10179860b2SJed Brown  USE_SUBPROCESS = 1
11179860b2SJed Brownexcept ImportError:
12179860b2SJed Brown  USE_SUBPROCESS = 0
13179860b2SJed Brown
14179860b2SJed Brown# Some features related to detecting login failures cannot be easily
15179860b2SJed Brown# implemented with the 'subprocess' module. Disable it for now ...
16179860b2SJed BrownUSE_SUBPROCESS = 0
17179860b2SJed Brown# In Python 2.6 and above, the 'popen2' module is deprecated
18179860b2SJed Brownif sys.version_info[:2] >= (2, 6) and not USE_SUBPROCESS:
19179860b2SJed Brown  import warnings
20179860b2SJed Brown  warnings.filterwarnings('ignore', category=DeprecationWarning, module=__name__)
21179860b2SJed Brown
22179860b2SJed Brownimport nargs
23179860b2SJed BrownuseThreads = nargs.Arg.findArgument('useThreads', sys.argv[1:])
24179860b2SJed Brownif useThreads is None:
2592626d4aSBarry Smith  useThreads = 0 # workaround issue with parallel configure
2692626d4aSBarry Smithelif useThreads == 'no' or useThreads == '0':
2792626d4aSBarry Smith  useThreads = 0
2892626d4aSBarry Smithelif useThreads == 'yes' or useThreads == '1':
2992626d4aSBarry Smith  useThreads = 1
30179860b2SJed Brownelse:
3192626d4aSBarry Smith  raise RuntimeError('Unknown option value for --useThreads ',useThreads)
32179860b2SJed Brown
33179860b2SJed BrownuseSelect = nargs.Arg.findArgument('useSelect', sys.argv[1:])
34179860b2SJed Brownif useSelect is None:
35*7efd6112SBarry Smith  useSelect = 1
3692626d4aSBarry Smithelif useSelect == 'no' or useSelect == '0':
3792626d4aSBarry Smith  useSelect = 0
3892626d4aSBarry Smithelif useSelect == 'yes' or useSelect == '1':
39179860b2SJed Brown  useSelect = 1
40179860b2SJed Brownelse:
4192626d4aSBarry Smith  raise RuntimeError('Unknown option value for --useSelect ',useSelect)
42179860b2SJed Brown
43179860b2SJed Brownimport logger
44179860b2SJed Brown
45179860b2SJed Brownclass Script(logger.Logger):
46179860b2SJed Brown  def __init__(self, clArgs = None, argDB = None, log = None):
47179860b2SJed Brown    self.checkPython()
48179860b2SJed Brown    logger.Logger.__init__(self, clArgs, argDB, log)
49179860b2SJed Brown    self.shell = '/bin/sh'
50179860b2SJed Brown    self.showHelp = 1
51179860b2SJed Brown    return
52179860b2SJed Brown
53179860b2SJed Brown  def hasHelpFlag(self):
54179860b2SJed Brown    '''Decide whether to display the help message and exit'''
55179860b2SJed Brown    import nargs
56179860b2SJed Brown
57179860b2SJed Brown    if not self.showHelp:
58179860b2SJed Brown      return 0
59179860b2SJed Brown    if nargs.Arg.findArgument('help', self.clArgs) is None and nargs.Arg.findArgument('h', self.clArgs) is None:
60179860b2SJed Brown      return 0
61179860b2SJed Brown    return 1
62179860b2SJed Brown
6375f179b0SBarry Smith  def hasListFlag(self):
6475f179b0SBarry Smith    '''Decide whether to display the list of download files and exit'''
6575f179b0SBarry Smith    import nargs
6675f179b0SBarry Smith
6775f179b0SBarry Smith    if not self.showHelp:
6875f179b0SBarry Smith      return 0
6975f179b0SBarry Smith    if nargs.Arg.findArgument('with-packages-dir', self.clArgs) is None:
7075f179b0SBarry Smith      return 0
7175f179b0SBarry Smith    return 1
7275f179b0SBarry Smith
73179860b2SJed Brown  def setupArguments(self, argDB):
74179860b2SJed Brown    '''This method now also creates the help and action logs'''
75179860b2SJed Brown    import help
76179860b2SJed Brown
77179860b2SJed Brown    argDB = logger.Logger.setupArguments(self, argDB)
78179860b2SJed Brown
79179860b2SJed Brown    self.help = help.Help(argDB)
80179860b2SJed Brown    self.help.title = 'Script Help'
81179860b2SJed Brown
82179860b2SJed Brown    self.actions = help.Info(argDB)
83179860b2SJed Brown    self.actions.title = 'Script Actions'
84179860b2SJed Brown
85179860b2SJed Brown    self.setupHelp(self.help)
86179860b2SJed Brown    return argDB
87179860b2SJed Brown
88179860b2SJed Brown  def setupHelp(self, help):
89179860b2SJed Brown    '''This method should be overidden to provide help for arguments'''
90179860b2SJed Brown    import nargs
91179860b2SJed Brown
92179860b2SJed Brown    help.addArgument('Script', '-help', nargs.ArgBool(None, 0, 'Print this help message', isTemporary = 1), ignoreDuplicates = 1)
9375f179b0SBarry Smith    help.addArgument('Script', '-with-packages-dir', nargs.ArgDir(None,None, 'Directory to store downloaded external package tarballs', isTemporary = 1), ignoreDuplicates = 1)
94179860b2SJed Brown    help.addArgument('Script', '-h',    nargs.ArgBool(None, 0, 'Print this help message', isTemporary = 1), ignoreDuplicates = 1)
95179860b2SJed Brown    return help
96179860b2SJed Brown
97179860b2SJed Brown  def setup(self):
98179860b2SJed Brown    ''' This method checks to see whether help was requested'''
99179860b2SJed Brown    if hasattr(self, '_setup'):
100179860b2SJed Brown      return
101179860b2SJed Brown    logger.Logger.setup(self)
102179860b2SJed Brown    self._setup = 1
103179860b2SJed Brown    if self.hasHelpFlag():
104e1362b5bSMatthew G. Knepley      self.argDB.readonly = True
105179860b2SJed Brown      if self.argDB.target == ['default']:
106179860b2SJed Brown        sections = None
107179860b2SJed Brown      else:
108179860b2SJed Brown        sections = self.argDB.target
109179860b2SJed Brown      self.help.output(sections = sections)
110179860b2SJed Brown      sys.exit()
11175f179b0SBarry Smith    if self.hasListFlag():
11275f179b0SBarry Smith      self.argDB.readonly = True
11375f179b0SBarry Smith      self.help.outputDownload()
114179860b2SJed Brown    return
115179860b2SJed Brown
116179860b2SJed Brown  def cleanup(self):
117179860b2SJed Brown    '''This method outputs the action log'''
118179860b2SJed Brown    self.actions.output(self.log)
119179860b2SJed Brown    return
120179860b2SJed Brown
121179860b2SJed Brown  def checkPython(self):
122db5c7c58SSatish Balay    if not hasattr(sys, 'version_info') or float(sys.version_info[0]) != 2 or float(sys.version_info[1]) < 6:
123db5c7c58SSatish Balay      raise RuntimeError('BuildSystem requires Python2 version 2.6 or higher. Get Python at http://www.python.org')
124179860b2SJed Brown    return
125179860b2SJed Brown
126179860b2SJed Brown  def getModule(root, name):
127179860b2SJed Brown    '''Retrieve a specific module from the directory root, bypassing the usual paths'''
128179860b2SJed Brown    import imp
129179860b2SJed Brown
130179860b2SJed Brown    (fp, pathname, description) = imp.find_module(name, [root])
131179860b2SJed Brown    try:
132179860b2SJed Brown      return imp.load_module(name, fp, pathname, description)
133179860b2SJed Brown    finally:
134179860b2SJed Brown      if fp: fp.close()
135179860b2SJed Brown    return
136179860b2SJed Brown  getModule = staticmethod(getModule)
137179860b2SJed Brown
138179860b2SJed Brown  def importModule(moduleName):
139179860b2SJed Brown    '''Import the named module, and return the module object
140179860b2SJed Brown       - Works properly for fully qualified names'''
141179860b2SJed Brown    module     = __import__(moduleName)
142179860b2SJed Brown    components = moduleName.split('.')
143179860b2SJed Brown    for comp in components[1:]:
144179860b2SJed Brown      module = getattr(module, comp)
145179860b2SJed Brown    return module
146179860b2SJed Brown  importModule = staticmethod(importModule)
147179860b2SJed Brown
148179860b2SJed Brown  if USE_SUBPROCESS:
149179860b2SJed Brown
150179860b2SJed Brown    def runShellCommand(command, log=None, cwd=None):
151179860b2SJed Brown      Popen = subprocess.Popen
152179860b2SJed Brown      PIPE  = subprocess.PIPE
153179860b2SJed Brown      if log: log.write('Executing: %s\n' % (command,))
154179860b2SJed Brown      pipe = Popen(command, cwd=cwd, stdin=None, stdout=PIPE, stderr=PIPE,
155179860b2SJed Brown                   bufsize=-1, shell=True, universal_newlines=True)
156179860b2SJed Brown      (out, err) = pipe.communicate()
157179860b2SJed Brown      ret = pipe.returncode
158179860b2SJed Brown      return (out, err, ret)
159179860b2SJed Brown
160179860b2SJed Brown  else:
161179860b2SJed Brown
162179860b2SJed Brown    def openPipe(command):
163179860b2SJed Brown      '''We need to use the asynchronous version here since we want to avoid blocking reads'''
164179860b2SJed Brown      import popen2
165179860b2SJed Brown
166179860b2SJed Brown      pipe = None
167179860b2SJed Brown      if hasattr(popen2, 'Popen3'):
168179860b2SJed Brown        pipe   = popen2.Popen3(command, 1)
169179860b2SJed Brown        input  = pipe.tochild
170179860b2SJed Brown        output = pipe.fromchild
171179860b2SJed Brown        err    = pipe.childerr
172179860b2SJed Brown      else:
173179860b2SJed Brown        import os
174179860b2SJed Brown        (input, output, err) = os.popen3(command)
175179860b2SJed Brown      return (input, output, err, pipe)
176179860b2SJed Brown    openPipe = staticmethod(openPipe)
177179860b2SJed Brown
178179860b2SJed Brown    def runShellCommand(command, log = None, cwd = None):
179179860b2SJed Brown      import select, os
180179860b2SJed Brown
181179860b2SJed Brown      ret        = None
182179860b2SJed Brown      out        = ''
183179860b2SJed Brown      err        = ''
184179860b2SJed Brown      loginError = 0
185179860b2SJed Brown      if cwd is not None:
186179860b2SJed Brown        oldpath = os.getcwd()
187179860b2SJed Brown        os.chdir(cwd)
188179860b2SJed Brown      if log: log.write('Executing: %s\n' % (command,))
189179860b2SJed Brown      (input, output, error, pipe) = Script.openPipe(command)
190179860b2SJed Brown      if cwd is not None:
191179860b2SJed Brown        os.chdir(oldpath)
192179860b2SJed Brown      input.close()
193179860b2SJed Brown      if useSelect:
194179860b2SJed Brown        outputClosed = 0
195179860b2SJed Brown        errorClosed  = 0
196179860b2SJed Brown        lst = [output, error]
197179860b2SJed Brown        while 1:
19892987420SSatish Balay          try:
199179860b2SJed Brown            ready = select.select(lst, [], [])
20092987420SSatish Balay          except Exception, e:
20192987420SSatish Balay            if log: log.write('** Error calling select() : '+str(e)+'\n')
20292987420SSatish Balay            continue
203179860b2SJed Brown          if len(ready[0]):
204179860b2SJed Brown            if error in ready[0]:
205179860b2SJed Brown              msg = error.readline()
206179860b2SJed Brown              if msg:
207179860b2SJed Brown                err += msg
208179860b2SJed Brown              else:
209179860b2SJed Brown                errorClosed = 1
210179860b2SJed Brown                lst.remove(error)
211179860b2SJed Brown            if output in ready[0]:
212179860b2SJed Brown              msg = output.readline()
213179860b2SJed Brown              if msg:
214179860b2SJed Brown                out += msg
215179860b2SJed Brown              else:
216179860b2SJed Brown                outputClosed = 1
217179860b2SJed Brown                lst.remove(output)
218acc7487bSSatish Balay            if msg and msg.find('password:') >= 0:
219179860b2SJed Brown              loginError = 1
220179860b2SJed Brown              break
221179860b2SJed Brown          if outputClosed and errorClosed:
222179860b2SJed Brown            break
223179860b2SJed Brown      else:
224179860b2SJed Brown        out = output.read()
225179860b2SJed Brown        err = error.read()
226179860b2SJed Brown      output.close()
227179860b2SJed Brown      error.close()
228179860b2SJed Brown      if pipe:
229179860b2SJed Brown        # We would like the NOHANG argument here
230179860b2SJed Brown        ret = pipe.wait()
231179860b2SJed Brown      if loginError:
232179860b2SJed Brown        raise RuntimeError('Could not login to site')
233179860b2SJed Brown      return (out, err, ret)
234179860b2SJed Brown
235179860b2SJed Brown  runShellCommand = staticmethod(runShellCommand)
236179860b2SJed Brown
237179860b2SJed Brown  def defaultCheckCommand(command, status, output, error):
238179860b2SJed Brown    '''Raise an error if the exit status is nonzero'''
239179860b2SJed Brown    if status: raise RuntimeError('Could not execute "%s":\n%s' % (command,output+error))
240179860b2SJed Brown  defaultCheckCommand = staticmethod(defaultCheckCommand)
241179860b2SJed Brown
242179860b2SJed Brown  def executeShellCommand(command, checkCommand = None, timeout = 600.0, log = None, lineLimit = 0, cwd=None):
243179860b2SJed Brown    '''Execute a shell command returning the output, and optionally provide a custom error checker
244179860b2SJed Brown       - This returns a tuple of the (output, error, statuscode)'''
245179860b2SJed Brown    if not checkCommand:
246179860b2SJed Brown      checkCommand = Script.defaultCheckCommand
247179860b2SJed Brown    if log is None:
248179860b2SJed Brown      log = logger.Logger.defaultLog
249179860b2SJed Brown    def logOutput(log, output):
250179860b2SJed Brown      import re
251179860b2SJed Brown      # get rid of multiple blank lines
2529f0d583aSJed Brown      output = re.sub('\n+','\n', output).strip()
2534854f487SJed Brown      if output:
254179860b2SJed Brown        if lineLimit:
255179860b2SJed Brown          output = '\n'.join(output.split('\n')[:lineLimit])
2564854f487SJed Brown        if '\n' in output:      # multi-line output
2574854f487SJed Brown          log.write('stdout:\n'+output+'\n')
2584854f487SJed Brown        else:
2594854f487SJed Brown          log.write('stdout: '+output+'\n')
260179860b2SJed Brown      return output
261179860b2SJed Brown    def runInShell(command, log, cwd):
262179860b2SJed Brown      if useThreads:
263179860b2SJed Brown        import threading
264179860b2SJed Brown        class InShell(threading.Thread):
265179860b2SJed Brown          def __init__(self):
266179860b2SJed Brown            threading.Thread.__init__(self)
267179860b2SJed Brown            self.name = 'Shell Command'
268179860b2SJed Brown            self.setDaemon(1)
269179860b2SJed Brown          def run(self):
270179860b2SJed Brown            (self.output, self.error, self.status) = ('', '', -1) # So these fields exist even if command fails with no output
271179860b2SJed Brown            (self.output, self.error, self.status) = Script.runShellCommand(command, log, cwd)
272179860b2SJed Brown        thread = InShell()
273179860b2SJed Brown        thread.start()
274179860b2SJed Brown        thread.join(timeout)
275179860b2SJed Brown        if thread.isAlive():
276179860b2SJed Brown          error = 'Runaway process exceeded time limit of '+str(timeout)+'s\n'
277179860b2SJed Brown          log.write(error)
278179860b2SJed Brown          return ('', error, -1)
279179860b2SJed Brown        else:
280179860b2SJed Brown          return (thread.output, thread.error, thread.status)
281179860b2SJed Brown      else:
282179860b2SJed Brown        return Script.runShellCommand(command, log, cwd)
283179860b2SJed Brown
284179860b2SJed Brown    (output, error, status) = runInShell(command, log, cwd)
285179860b2SJed Brown    output = logOutput(log, output)
286179860b2SJed Brown    checkCommand(command, status, output, error)
287179860b2SJed Brown    return (output, error, status)
288179860b2SJed Brown  executeShellCommand = staticmethod(executeShellCommand)
289179860b2SJed Brown
290179860b2SJed Brown  def loadConfigure(self, argDB = None):
291179860b2SJed Brown    if argDB is None:
292179860b2SJed Brown      argDB = self.argDB
293179860b2SJed Brown    if not 'configureCache' in argDB:
294179860b2SJed Brown      self.logPrint('No cached configure in RDict at '+str(argDB.saveFilename))
295179860b2SJed Brown      return None
296179860b2SJed Brown    try:
297179860b2SJed Brown      cache = argDB['configureCache']
298179860b2SJed Brown      framework = cPickle.loads(cache)
299179860b2SJed Brown      framework.framework = framework
300179860b2SJed Brown      framework.argDB = argDB
301179860b2SJed Brown      self.logPrint('Loaded configure to cache: size '+str(len(cache)))
302179860b2SJed Brown    except cPickle.UnpicklingError, e:
303179860b2SJed Brown      framework = None
304179860b2SJed Brown      self.logPrint('Invalid cached configure: '+str(e))
305179860b2SJed Brown    return framework
306179860b2SJed Brown
307179860b2SJed Brownimport args
308179860b2SJed Brown
309179860b2SJed Brownclass LanguageProcessor(args.ArgumentProcessor):
310179860b2SJed Brown  def __init__(self, clArgs = None, argDB = None, framework = None, versionControl = None):
311179860b2SJed Brown    self.languageModule      = {}
312179860b2SJed Brown    self.preprocessorObject  = {}
313179860b2SJed Brown    self.compilerObject      = {}
314179860b2SJed Brown    self.linkerObject        = {}
315179860b2SJed Brown    self.sharedLinkerObject  = {}
316179860b2SJed Brown    self.dynamicLinkerObject = {}
317179860b2SJed Brown    self.framework           = framework
318179860b2SJed Brown    self.versionControl      = versionControl
319179860b2SJed Brown    args.ArgumentProcessor.__init__(self, clArgs, argDB)
320179860b2SJed Brown    self.outputFiles         = {}
321179860b2SJed Brown    self.modulePath          = 'config.compile'
322179860b2SJed Brown    return
323179860b2SJed Brown
324179860b2SJed Brown  def getCompilers(self):
325179860b2SJed Brown    if self.framework is None:
326179860b2SJed Brown      return
327179860b2SJed Brown    return self.framework.require('config.compilers', None)
328179860b2SJed Brown  compilers = property(getCompilers, doc = 'The config.compilers configure object')
329179860b2SJed Brown  def getLibraries(self):
330179860b2SJed Brown    if self.framework is None:
331179860b2SJed Brown      return
332179860b2SJed Brown    return self.framework.require('config.libraries', None)
333179860b2SJed Brown  libraries = property(getLibraries, doc = 'The config.libraries configure object')
334179860b2SJed Brown
335179860b2SJed Brown  def __getstate__(self, d = None):
336179860b2SJed Brown    '''We only want to pickle the language module names and output files. The other objects are set by configure.'''
337179860b2SJed Brown    if d is None:
338179860b2SJed Brown      d = args.ArgumentProcessor.__getstate__(self)
339179860b2SJed Brown    if 'languageModule' in d:
340179860b2SJed Brown      d['languageModule'] = dict([(lang,mod._loadName) for lang,mod in d['languageModule'].items()])
341179860b2SJed Brown    for member in ['preprocessorObject', 'compilerObject', 'linkerObject', 'sharedLinkerObject', 'dynamicLinkerObject', 'framework']:
342179860b2SJed Brown      if member in d:
343179860b2SJed Brown        del d[member]
344179860b2SJed Brown    return d
345179860b2SJed Brown
346179860b2SJed Brown  def __setstate__(self, d):
347179860b2SJed Brown    '''We must create the language modules'''
348179860b2SJed Brown    args.ArgumentProcessor.__setstate__(self, d)
349179860b2SJed Brown    self.__dict__.update(d)
350179860b2SJed Brown    [self.getLanguageModule(language, moduleName) for language,moduleName in self.languageModule.items()]
351179860b2SJed Brown    self.preprocessorObject  = {}
352179860b2SJed Brown    self.compilerObject      = {}
353179860b2SJed Brown    self.linkerObject        = {}
354179860b2SJed Brown    self.sharedLinkerObject  = {}
355179860b2SJed Brown    self.dynamicLinkerObject = {}
356179860b2SJed Brown    return
357179860b2SJed Brown
358179860b2SJed Brown  def setArgDB(self, argDB):
359179860b2SJed Brown    args.ArgumentProcessor.setArgDB(self, argDB)
360179860b2SJed Brown    for obj in self.preprocessorObject.values():
361179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
362179860b2SJed Brown        obj.argDB = argDB
363179860b2SJed Brown    for obj in self.compilerObject.values():
364179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
365179860b2SJed Brown        obj.argDB = argDB
366179860b2SJed Brown    for obj in self.linkerObject.values():
367179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
368179860b2SJed Brown        obj.argDB = argDB
369179860b2SJed Brown    for obj in self.sharedLinkerObject.values():
370179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
371179860b2SJed Brown        obj.argDB = argDB
372179860b2SJed Brown    for obj in self.dynamicLinkerObject.values():
373179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
374179860b2SJed Brown        obj.argDB = argDB
375179860b2SJed Brown    if not self.compilers is None:
376179860b2SJed Brown      self.compilers.argDB = argDB
377179860b2SJed Brown      for obj in self.preprocessorObject.values():
378179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
379179860b2SJed Brown          obj.configCompilers.argDB = argDB
380179860b2SJed Brown      for obj in self.compilerObject.values():
381179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
382179860b2SJed Brown          obj.configCompilers.argDB = argDB
383179860b2SJed Brown      for obj in self.linkerObject.values():
384179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
385179860b2SJed Brown          obj.configCompilers.argDB = argDB
386179860b2SJed Brown      for obj in self.sharedLinkerObject.values():
387179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
388179860b2SJed Brown          obj.configCompilers.argDB = argDB
389179860b2SJed Brown      for obj in self.dynamicLinkerObject.values():
390179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
391179860b2SJed Brown          obj.configCompilers.argDB = argDB
392179860b2SJed Brown    if not self.libraries is None:
393179860b2SJed Brown      self.libraries.argDB = argDB
394179860b2SJed Brown      for obj in self.linkerObject.values():
395179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
396179860b2SJed Brown          obj.configLibraries.argDB = argDB
397179860b2SJed Brown      for obj in self.sharedLinkerObject.values():
398179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
399179860b2SJed Brown          obj.configLibraries.argDB = argDB
400179860b2SJed Brown      for obj in self.dynamicLinkerObject.values():
401179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
402179860b2SJed Brown          obj.configLibraries.argDB = argDB
403179860b2SJed Brown    return
404179860b2SJed Brown  argDB = property(args.ArgumentProcessor.getArgDB, setArgDB, doc = 'The RDict argument database')
405179860b2SJed Brown
406179860b2SJed Brown  def getLanguageModule(self, language, moduleName = None):
407179860b2SJed Brown    '''Return the module associated with operations for a given language
408179860b2SJed Brown       - Giving a moduleName explicitly forces a reimport'''
409179860b2SJed Brown    if not language in self.languageModule or not moduleName is None:
410179860b2SJed Brown      try:
411179860b2SJed Brown        if moduleName is None:
412179860b2SJed Brown          moduleName = self.modulePath+'.'+language
413179860b2SJed Brown        module     = __import__(moduleName)
414179860b2SJed Brown      except ImportError, e:
415179860b2SJed Brown        if not moduleName is None:
416179860b2SJed Brown          self.logPrint('Failure to find language module: '+str(e))
417179860b2SJed Brown        try:
418179860b2SJed Brown          moduleName = self.modulePath+'.'+language
419179860b2SJed Brown          module     = __import__(moduleName)
420179860b2SJed Brown        except ImportError, e:
421179860b2SJed Brown          self.logPrint('Failure to find language module: '+str(e))
422179860b2SJed Brown          moduleName = 'config.compile.'+language
423179860b2SJed Brown          module     = __import__(moduleName)
424179860b2SJed Brown      components = moduleName.split('.')
425179860b2SJed Brown      for component in components[1:]:
426179860b2SJed Brown        module   = getattr(module, component)
427179860b2SJed Brown      module._loadName = moduleName
428179860b2SJed Brown      self.languageModule[language] = module
429179860b2SJed Brown    return self.languageModule[language]
430179860b2SJed Brown
431179860b2SJed Brown  def getPreprocessorObject(self, language):
432179860b2SJed Brown    if not language in self.preprocessorObject:
433179860b2SJed Brown      self.preprocessorObject[language] = self.getLanguageModule(language).Preprocessor(self.argDB)
434179860b2SJed Brown      self.preprocessorObject[language].setup()
435179860b2SJed Brown    if not self.compilers is None:
436179860b2SJed Brown      self.preprocessorObject[language].configCompilers = self.compilers
437179860b2SJed Brown    if not self.versionControl is None:
438179860b2SJed Brown      self.preprocessorObject[language].versionControl  = self.versionControl
439179860b2SJed Brown    return self.preprocessorObject[language]
440179860b2SJed Brown
441179860b2SJed Brown  def setPreprocessorObject(self, language, preprocessor):
442179860b2SJed Brown    self.preprocessorObject[language] = preprocessor
443179860b2SJed Brown    return self.getPreprocessorObject(language)
444179860b2SJed Brown
445179860b2SJed Brown  def getCompilerObject(self, language):
446179860b2SJed Brown    if not language in self.compilerObject:
447179860b2SJed Brown      self.compilerObject[language] = self.getLanguageModule(language).Compiler(self.argDB)
448179860b2SJed Brown      self.compilerObject[language].setup()
449179860b2SJed Brown    if not self.compilers is None:
450179860b2SJed Brown      self.compilerObject[language].configCompilers = self.compilers
451179860b2SJed Brown    if not self.versionControl is None:
452179860b2SJed Brown      self.compilerObject[language].versionControl  = self.versionControl
453179860b2SJed Brown    return self.compilerObject[language]
454179860b2SJed Brown
455179860b2SJed Brown  def setCompilerObject(self, language, compiler):
456179860b2SJed Brown    self.compilerObject[language] = compiler
457179860b2SJed Brown    return self.getCompilerObject(language)
458179860b2SJed Brown
459179860b2SJed Brown  def getLinkerObject(self, language):
460179860b2SJed Brown    if not language in self.linkerObject:
461179860b2SJed Brown      self.linkerObject[language] = self.getLanguageModule(language).Linker(self.argDB)
462179860b2SJed Brown      self.linkerObject[language].setup()
463179860b2SJed Brown    if not self.compilers is None:
464179860b2SJed Brown      self.linkerObject[language].configCompilers = self.compilers
465179860b2SJed Brown    if not self.libraries is None:
466179860b2SJed Brown      self.linkerObject[language].configLibraries = self.libraries
467179860b2SJed Brown    if not self.versionControl is None:
468179860b2SJed Brown      self.linkerObject[language].versionControl  = self.versionControl
469179860b2SJed Brown    return self.linkerObject[language]
470179860b2SJed Brown
471179860b2SJed Brown  def setLinkerObject(self, language, linker):
472179860b2SJed Brown    self.linkerObject[language] = linker
473179860b2SJed Brown    return self.getLinkerObject(language)
474179860b2SJed Brown
475179860b2SJed Brown  def getSharedLinkerObject(self, language):
476179860b2SJed Brown    if not language in self.sharedLinkerObject:
477179860b2SJed Brown      self.sharedLinkerObject[language] = self.getLanguageModule(language).SharedLinker(self.argDB)
478179860b2SJed Brown      self.sharedLinkerObject[language].setup()
479179860b2SJed Brown    if not self.compilers is None:
480179860b2SJed Brown      self.sharedLinkerObject[language].configCompilers = self.compilers
481179860b2SJed Brown    if not self.libraries is None:
482179860b2SJed Brown      self.sharedLinkerObject[language].configLibraries = self.libraries
483179860b2SJed Brown    if not self.versionControl is None:
484179860b2SJed Brown      self.sharedLinkerObject[language].versionControl  = self.versionControl
485179860b2SJed Brown    return self.sharedLinkerObject[language]
486179860b2SJed Brown
487179860b2SJed Brown  def setSharedLinkerObject(self, language, linker):
488179860b2SJed Brown    self.sharedLinkerObject[language] = linker
489179860b2SJed Brown    return self.getSharedLinkerObject(language)
490179860b2SJed Brown
491179860b2SJed Brown  def getDynamicLinkerObject(self, language):
492179860b2SJed Brown    if not language in self.dynamicLinkerObject:
493179860b2SJed Brown      self.dynamicLinkerObject[language] = self.getLanguageModule(language).DynamicLinker(self.argDB)
494179860b2SJed Brown      self.dynamicLinkerObject[language].setup()
495179860b2SJed Brown    if not self.compilers is None:
496179860b2SJed Brown      self.dynamicLinkerObject[language].configCompilers = self.compilers
497179860b2SJed Brown    if not self.libraries is None:
498179860b2SJed Brown      self.dynamicLinkerObject[language].configLibraries = self.libraries
499179860b2SJed Brown    if not self.versionControl is None:
500179860b2SJed Brown      self.dynamicLinkerObject[language].versionControl  = self.versionControl
501179860b2SJed Brown    return self.dynamicLinkerObject[language]
502179860b2SJed Brown
503179860b2SJed Brown  def setDynamicLinkerObject(self, language, linker):
504179860b2SJed Brown    self.dynamicLinkerObject[language] = linker
505179860b2SJed Brown    return self.getDynamicLinkerObject(language)
506