xref: /petsc/config/BuildSystem/script.py (revision 179860b23afbef20daed3359c1645679d1efa988)
1*179860b2SJed Brownimport sys
2*179860b2SJed Brownif not hasattr(sys, 'version_info'):
3*179860b2SJed Brown  print '*** Python version 1 is not supported. Please get the latest version from www.python.org ***'
4*179860b2SJed Brown  sys.exit(4)
5*179860b2SJed Brown
6*179860b2SJed Brownimport cPickle
7*179860b2SJed Brown
8*179860b2SJed Browntry:
9*179860b2SJed Brown  import subprocess
10*179860b2SJed Brown  USE_SUBPROCESS = 1
11*179860b2SJed Brownexcept ImportError:
12*179860b2SJed Brown  USE_SUBPROCESS = 0
13*179860b2SJed Brown
14*179860b2SJed Brown# Some features related to detecting login failures cannot be easily
15*179860b2SJed Brown# implemented with the 'subprocess' module. Disable it for now ...
16*179860b2SJed BrownUSE_SUBPROCESS = 0
17*179860b2SJed Brown# In Python 2.6 and above, the 'popen2' module is deprecated
18*179860b2SJed Brownif sys.version_info[:2] >= (2, 6) and not USE_SUBPROCESS:
19*179860b2SJed Brown  import warnings
20*179860b2SJed Brown  warnings.filterwarnings('ignore', category=DeprecationWarning, module=__name__)
21*179860b2SJed Brown
22*179860b2SJed Brownimport nargs
23*179860b2SJed BrownuseThreads = nargs.Arg.findArgument('useThreads', sys.argv[1:])
24*179860b2SJed Brownif useThreads is None:
25*179860b2SJed Brown  useThreads = 1
26*179860b2SJed Brownelse:
27*179860b2SJed Brown  useThreads = int(useThreads)
28*179860b2SJed Brown
29*179860b2SJed BrownuseSelect = nargs.Arg.findArgument('useSelect', sys.argv[1:])
30*179860b2SJed Brownif useSelect is None:
31*179860b2SJed Brown  useSelect = 1
32*179860b2SJed Brownelse:
33*179860b2SJed Brown  useSelect = int(useSelect)
34*179860b2SJed Brown
35*179860b2SJed Brownimport logger
36*179860b2SJed Brown
37*179860b2SJed Brownclass Script(logger.Logger):
38*179860b2SJed Brown  def __init__(self, clArgs = None, argDB = None, log = None):
39*179860b2SJed Brown    self.checkPython()
40*179860b2SJed Brown    logger.Logger.__init__(self, clArgs, argDB, log)
41*179860b2SJed Brown    self.shell = '/bin/sh'
42*179860b2SJed Brown    self.showHelp = 1
43*179860b2SJed Brown    return
44*179860b2SJed Brown
45*179860b2SJed Brown  def hasHelpFlag(self):
46*179860b2SJed Brown    '''Decide whether to display the help message and exit'''
47*179860b2SJed Brown    import nargs
48*179860b2SJed Brown
49*179860b2SJed Brown    if not self.showHelp:
50*179860b2SJed Brown      return 0
51*179860b2SJed Brown    if nargs.Arg.findArgument('help', self.clArgs) is None and nargs.Arg.findArgument('h', self.clArgs) is None:
52*179860b2SJed Brown      return 0
53*179860b2SJed Brown    return 1
54*179860b2SJed Brown
55*179860b2SJed Brown  def setupArguments(self, argDB):
56*179860b2SJed Brown    '''This method now also creates the help and action logs'''
57*179860b2SJed Brown    import help
58*179860b2SJed Brown
59*179860b2SJed Brown    argDB = logger.Logger.setupArguments(self, argDB)
60*179860b2SJed Brown
61*179860b2SJed Brown    self.help = help.Help(argDB)
62*179860b2SJed Brown    self.help.title = 'Script Help'
63*179860b2SJed Brown
64*179860b2SJed Brown    self.actions = help.Info(argDB)
65*179860b2SJed Brown    self.actions.title = 'Script Actions'
66*179860b2SJed Brown
67*179860b2SJed Brown    self.setupHelp(self.help)
68*179860b2SJed Brown    return argDB
69*179860b2SJed Brown
70*179860b2SJed Brown  def setupHelp(self, help):
71*179860b2SJed Brown    '''This method should be overidden to provide help for arguments'''
72*179860b2SJed Brown    import nargs
73*179860b2SJed Brown
74*179860b2SJed Brown    help.addArgument('Script', '-help', nargs.ArgBool(None, 0, 'Print this help message', isTemporary = 1), ignoreDuplicates = 1)
75*179860b2SJed Brown    help.addArgument('Script', '-h',    nargs.ArgBool(None, 0, 'Print this help message', isTemporary = 1), ignoreDuplicates = 1)
76*179860b2SJed Brown    return help
77*179860b2SJed Brown
78*179860b2SJed Brown  def setup(self):
79*179860b2SJed Brown    ''' This method checks to see whether help was requested'''
80*179860b2SJed Brown    if hasattr(self, '_setup'):
81*179860b2SJed Brown      return
82*179860b2SJed Brown    logger.Logger.setup(self)
83*179860b2SJed Brown    self._setup = 1
84*179860b2SJed Brown    if self.hasHelpFlag():
85*179860b2SJed Brown      if self.argDB.target == ['default']:
86*179860b2SJed Brown        sections = None
87*179860b2SJed Brown      else:
88*179860b2SJed Brown        sections = self.argDB.target
89*179860b2SJed Brown      self.help.output(sections = sections)
90*179860b2SJed Brown      sys.exit()
91*179860b2SJed Brown    return
92*179860b2SJed Brown
93*179860b2SJed Brown  def cleanup(self):
94*179860b2SJed Brown    '''This method outputs the action log'''
95*179860b2SJed Brown    self.actions.output(self.log)
96*179860b2SJed Brown    return
97*179860b2SJed Brown
98*179860b2SJed Brown  def checkPython(self):
99*179860b2SJed Brown    if not hasattr(sys, 'version_info') or float(sys.version_info[0]) != 2 or float(sys.version_info[1]) < 3:
100*179860b2SJed Brown      raise RuntimeError('BuildSystem requires Python2 version 2.3 or higher. Get Python at http://www.python.org')
101*179860b2SJed Brown    return
102*179860b2SJed Brown
103*179860b2SJed Brown  def getModule(root, name):
104*179860b2SJed Brown    '''Retrieve a specific module from the directory root, bypassing the usual paths'''
105*179860b2SJed Brown    import imp
106*179860b2SJed Brown
107*179860b2SJed Brown    (fp, pathname, description) = imp.find_module(name, [root])
108*179860b2SJed Brown    try:
109*179860b2SJed Brown      return imp.load_module(name, fp, pathname, description)
110*179860b2SJed Brown    finally:
111*179860b2SJed Brown      if fp: fp.close()
112*179860b2SJed Brown    return
113*179860b2SJed Brown  getModule = staticmethod(getModule)
114*179860b2SJed Brown
115*179860b2SJed Brown  def importModule(moduleName):
116*179860b2SJed Brown    '''Import the named module, and return the module object
117*179860b2SJed Brown       - Works properly for fully qualified names'''
118*179860b2SJed Brown    module     = __import__(moduleName)
119*179860b2SJed Brown    components = moduleName.split('.')
120*179860b2SJed Brown    for comp in components[1:]:
121*179860b2SJed Brown      module = getattr(module, comp)
122*179860b2SJed Brown    return module
123*179860b2SJed Brown  importModule = staticmethod(importModule)
124*179860b2SJed Brown
125*179860b2SJed Brown  if USE_SUBPROCESS:
126*179860b2SJed Brown
127*179860b2SJed Brown    def runShellCommand(command, log=None, cwd=None):
128*179860b2SJed Brown      Popen = subprocess.Popen
129*179860b2SJed Brown      PIPE  = subprocess.PIPE
130*179860b2SJed Brown      if log: log.write('Executing: %s\n' % (command,))
131*179860b2SJed Brown      pipe = Popen(command, cwd=cwd, stdin=None, stdout=PIPE, stderr=PIPE,
132*179860b2SJed Brown                   bufsize=-1, shell=True, universal_newlines=True)
133*179860b2SJed Brown      (out, err) = pipe.communicate()
134*179860b2SJed Brown      ret = pipe.returncode
135*179860b2SJed Brown      return (out, err, ret)
136*179860b2SJed Brown
137*179860b2SJed Brown  else:
138*179860b2SJed Brown
139*179860b2SJed Brown    def openPipe(command):
140*179860b2SJed Brown      '''We need to use the asynchronous version here since we want to avoid blocking reads'''
141*179860b2SJed Brown      import popen2
142*179860b2SJed Brown
143*179860b2SJed Brown      pipe = None
144*179860b2SJed Brown      if hasattr(popen2, 'Popen3'):
145*179860b2SJed Brown        pipe   = popen2.Popen3(command, 1)
146*179860b2SJed Brown        input  = pipe.tochild
147*179860b2SJed Brown        output = pipe.fromchild
148*179860b2SJed Brown        err    = pipe.childerr
149*179860b2SJed Brown      else:
150*179860b2SJed Brown        import os
151*179860b2SJed Brown        (input, output, err) = os.popen3(command)
152*179860b2SJed Brown      return (input, output, err, pipe)
153*179860b2SJed Brown    openPipe = staticmethod(openPipe)
154*179860b2SJed Brown
155*179860b2SJed Brown    def runShellCommand(command, log = None, cwd = None):
156*179860b2SJed Brown      import select, os
157*179860b2SJed Brown
158*179860b2SJed Brown      ret        = None
159*179860b2SJed Brown      out        = ''
160*179860b2SJed Brown      err        = ''
161*179860b2SJed Brown      loginError = 0
162*179860b2SJed Brown      if cwd is not None:
163*179860b2SJed Brown        oldpath = os.getcwd()
164*179860b2SJed Brown        os.chdir(cwd)
165*179860b2SJed Brown      if log: log.write('Executing: %s\n' % (command,))
166*179860b2SJed Brown      (input, output, error, pipe) = Script.openPipe(command)
167*179860b2SJed Brown      if cwd is not None:
168*179860b2SJed Brown        os.chdir(oldpath)
169*179860b2SJed Brown      input.close()
170*179860b2SJed Brown      if useSelect:
171*179860b2SJed Brown        outputClosed = 0
172*179860b2SJed Brown        errorClosed  = 0
173*179860b2SJed Brown        lst = [output, error]
174*179860b2SJed Brown        while 1:
175*179860b2SJed Brown          ready = select.select(lst, [], [])
176*179860b2SJed Brown          if len(ready[0]):
177*179860b2SJed Brown            if error in ready[0]:
178*179860b2SJed Brown              msg = error.readline()
179*179860b2SJed Brown              if msg:
180*179860b2SJed Brown                err += msg
181*179860b2SJed Brown              else:
182*179860b2SJed Brown                errorClosed = 1
183*179860b2SJed Brown                lst.remove(error)
184*179860b2SJed Brown            if output in ready[0]:
185*179860b2SJed Brown              msg = output.readline()
186*179860b2SJed Brown              if msg:
187*179860b2SJed Brown                out += msg
188*179860b2SJed Brown              else:
189*179860b2SJed Brown                outputClosed = 1
190*179860b2SJed Brown                lst.remove(output)
191*179860b2SJed Brown            if out.find('password:') >= 0 or err.find('password:') >= 0:
192*179860b2SJed Brown              loginError = 1
193*179860b2SJed Brown              break
194*179860b2SJed Brown          if outputClosed and errorClosed:
195*179860b2SJed Brown            break
196*179860b2SJed Brown      else:
197*179860b2SJed Brown        out = output.read()
198*179860b2SJed Brown        err = error.read()
199*179860b2SJed Brown      output.close()
200*179860b2SJed Brown      error.close()
201*179860b2SJed Brown      if pipe:
202*179860b2SJed Brown        # We would like the NOHANG argument here
203*179860b2SJed Brown        ret = pipe.wait()
204*179860b2SJed Brown      if loginError:
205*179860b2SJed Brown        raise RuntimeError('Could not login to site')
206*179860b2SJed Brown      return (out, err, ret)
207*179860b2SJed Brown
208*179860b2SJed Brown  runShellCommand = staticmethod(runShellCommand)
209*179860b2SJed Brown
210*179860b2SJed Brown  def defaultCheckCommand(command, status, output, error):
211*179860b2SJed Brown    '''Raise an error if the exit status is nonzero'''
212*179860b2SJed Brown    if status: raise RuntimeError('Could not execute "%s":\n%s' % (command,output+error))
213*179860b2SJed Brown  defaultCheckCommand = staticmethod(defaultCheckCommand)
214*179860b2SJed Brown
215*179860b2SJed Brown  def executeShellCommand(command, checkCommand = None, timeout = 600.0, log = None, lineLimit = 0, cwd=None):
216*179860b2SJed Brown    '''Execute a shell command returning the output, and optionally provide a custom error checker
217*179860b2SJed Brown       - This returns a tuple of the (output, error, statuscode)'''
218*179860b2SJed Brown    if not checkCommand:
219*179860b2SJed Brown      checkCommand = Script.defaultCheckCommand
220*179860b2SJed Brown    if log is None:
221*179860b2SJed Brown      log = logger.Logger.defaultLog
222*179860b2SJed Brown    def logOutput(log, output):
223*179860b2SJed Brown      import re
224*179860b2SJed Brown      # get rid of multiple blank lines
225*179860b2SJed Brown      output = re.sub('\n[\n]*','\n', output)
226*179860b2SJed Brown      if lineLimit:
227*179860b2SJed Brown        output = '\n'.join(output.split('\n')[:lineLimit])
228*179860b2SJed Brown      log.write('sh: '+output+'\n')
229*179860b2SJed Brown      return output
230*179860b2SJed Brown    def runInShell(command, log, cwd):
231*179860b2SJed Brown      if useThreads:
232*179860b2SJed Brown        import threading
233*179860b2SJed Brown        class InShell(threading.Thread):
234*179860b2SJed Brown          def __init__(self):
235*179860b2SJed Brown            threading.Thread.__init__(self)
236*179860b2SJed Brown            self.name = 'Shell Command'
237*179860b2SJed Brown            self.setDaemon(1)
238*179860b2SJed Brown          def run(self):
239*179860b2SJed Brown            (self.output, self.error, self.status) = ('', '', -1) # So these fields exist even if command fails with no output
240*179860b2SJed Brown            (self.output, self.error, self.status) = Script.runShellCommand(command, log, cwd)
241*179860b2SJed Brown        thread = InShell()
242*179860b2SJed Brown        thread.start()
243*179860b2SJed Brown        thread.join(timeout)
244*179860b2SJed Brown        if thread.isAlive():
245*179860b2SJed Brown          error = 'Runaway process exceeded time limit of '+str(timeout)+'s\n'
246*179860b2SJed Brown          log.write(error)
247*179860b2SJed Brown          return ('', error, -1)
248*179860b2SJed Brown        else:
249*179860b2SJed Brown          return (thread.output, thread.error, thread.status)
250*179860b2SJed Brown      else:
251*179860b2SJed Brown        return Script.runShellCommand(command, log, cwd)
252*179860b2SJed Brown
253*179860b2SJed Brown    log.write('sh: %s\n' % (command,))
254*179860b2SJed Brown    (output, error, status) = runInShell(command, log, cwd)
255*179860b2SJed Brown    output = logOutput(log, output)
256*179860b2SJed Brown    checkCommand(command, status, output, error)
257*179860b2SJed Brown    return (output, error, status)
258*179860b2SJed Brown  executeShellCommand = staticmethod(executeShellCommand)
259*179860b2SJed Brown
260*179860b2SJed Brown  def loadConfigure(self, argDB = None):
261*179860b2SJed Brown    if argDB is None:
262*179860b2SJed Brown      argDB = self.argDB
263*179860b2SJed Brown    if not 'configureCache' in argDB:
264*179860b2SJed Brown      self.logPrint('No cached configure in RDict at '+str(argDB.saveFilename))
265*179860b2SJed Brown      return None
266*179860b2SJed Brown    try:
267*179860b2SJed Brown      cache = argDB['configureCache']
268*179860b2SJed Brown      framework = cPickle.loads(cache)
269*179860b2SJed Brown      framework.framework = framework
270*179860b2SJed Brown      framework.argDB = argDB
271*179860b2SJed Brown      self.logPrint('Loaded configure to cache: size '+str(len(cache)))
272*179860b2SJed Brown    except cPickle.UnpicklingError, e:
273*179860b2SJed Brown      framework = None
274*179860b2SJed Brown      self.logPrint('Invalid cached configure: '+str(e))
275*179860b2SJed Brown    return framework
276*179860b2SJed Brown
277*179860b2SJed Brownimport args
278*179860b2SJed Brown
279*179860b2SJed Brownclass LanguageProcessor(args.ArgumentProcessor):
280*179860b2SJed Brown  def __init__(self, clArgs = None, argDB = None, framework = None, versionControl = None):
281*179860b2SJed Brown    self.languageModule      = {}
282*179860b2SJed Brown    self.preprocessorObject  = {}
283*179860b2SJed Brown    self.compilerObject      = {}
284*179860b2SJed Brown    self.linkerObject        = {}
285*179860b2SJed Brown    self.sharedLinkerObject  = {}
286*179860b2SJed Brown    self.dynamicLinkerObject = {}
287*179860b2SJed Brown    self.framework           = framework
288*179860b2SJed Brown    self.versionControl      = versionControl
289*179860b2SJed Brown    args.ArgumentProcessor.__init__(self, clArgs, argDB)
290*179860b2SJed Brown    self.outputFiles         = {}
291*179860b2SJed Brown    self.modulePath          = 'config.compile'
292*179860b2SJed Brown    return
293*179860b2SJed Brown
294*179860b2SJed Brown  def getCompilers(self):
295*179860b2SJed Brown    if self.framework is None:
296*179860b2SJed Brown      return
297*179860b2SJed Brown    return self.framework.require('config.compilers', None)
298*179860b2SJed Brown  compilers = property(getCompilers, doc = 'The config.compilers configure object')
299*179860b2SJed Brown  def getLibraries(self):
300*179860b2SJed Brown    if self.framework is None:
301*179860b2SJed Brown      return
302*179860b2SJed Brown    return self.framework.require('config.libraries', None)
303*179860b2SJed Brown  libraries = property(getLibraries, doc = 'The config.libraries configure object')
304*179860b2SJed Brown
305*179860b2SJed Brown  def __getstate__(self, d = None):
306*179860b2SJed Brown    '''We only want to pickle the language module names and output files. The other objects are set by configure.'''
307*179860b2SJed Brown    if d is None:
308*179860b2SJed Brown      d = args.ArgumentProcessor.__getstate__(self)
309*179860b2SJed Brown    if 'languageModule' in d:
310*179860b2SJed Brown      d['languageModule'] = dict([(lang,mod._loadName) for lang,mod in d['languageModule'].items()])
311*179860b2SJed Brown    for member in ['preprocessorObject', 'compilerObject', 'linkerObject', 'sharedLinkerObject', 'dynamicLinkerObject', 'framework']:
312*179860b2SJed Brown      if member in d:
313*179860b2SJed Brown        del d[member]
314*179860b2SJed Brown    return d
315*179860b2SJed Brown
316*179860b2SJed Brown  def __setstate__(self, d):
317*179860b2SJed Brown    '''We must create the language modules'''
318*179860b2SJed Brown    args.ArgumentProcessor.__setstate__(self, d)
319*179860b2SJed Brown    self.__dict__.update(d)
320*179860b2SJed Brown    [self.getLanguageModule(language, moduleName) for language,moduleName in self.languageModule.items()]
321*179860b2SJed Brown    self.preprocessorObject  = {}
322*179860b2SJed Brown    self.compilerObject      = {}
323*179860b2SJed Brown    self.linkerObject        = {}
324*179860b2SJed Brown    self.sharedLinkerObject  = {}
325*179860b2SJed Brown    self.dynamicLinkerObject = {}
326*179860b2SJed Brown    return
327*179860b2SJed Brown
328*179860b2SJed Brown  def setArgDB(self, argDB):
329*179860b2SJed Brown    args.ArgumentProcessor.setArgDB(self, argDB)
330*179860b2SJed Brown    for obj in self.preprocessorObject.values():
331*179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
332*179860b2SJed Brown        obj.argDB = argDB
333*179860b2SJed Brown    for obj in self.compilerObject.values():
334*179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
335*179860b2SJed Brown        obj.argDB = argDB
336*179860b2SJed Brown    for obj in self.linkerObject.values():
337*179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
338*179860b2SJed Brown        obj.argDB = argDB
339*179860b2SJed Brown    for obj in self.sharedLinkerObject.values():
340*179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
341*179860b2SJed Brown        obj.argDB = argDB
342*179860b2SJed Brown    for obj in self.dynamicLinkerObject.values():
343*179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
344*179860b2SJed Brown        obj.argDB = argDB
345*179860b2SJed Brown    if not self.compilers is None:
346*179860b2SJed Brown      self.compilers.argDB = argDB
347*179860b2SJed Brown      for obj in self.preprocessorObject.values():
348*179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
349*179860b2SJed Brown          obj.configCompilers.argDB = argDB
350*179860b2SJed Brown      for obj in self.compilerObject.values():
351*179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
352*179860b2SJed Brown          obj.configCompilers.argDB = argDB
353*179860b2SJed Brown      for obj in self.linkerObject.values():
354*179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
355*179860b2SJed Brown          obj.configCompilers.argDB = argDB
356*179860b2SJed Brown      for obj in self.sharedLinkerObject.values():
357*179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
358*179860b2SJed Brown          obj.configCompilers.argDB = argDB
359*179860b2SJed Brown      for obj in self.dynamicLinkerObject.values():
360*179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
361*179860b2SJed Brown          obj.configCompilers.argDB = argDB
362*179860b2SJed Brown    if not self.libraries is None:
363*179860b2SJed Brown      self.libraries.argDB = argDB
364*179860b2SJed Brown      for obj in self.linkerObject.values():
365*179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
366*179860b2SJed Brown          obj.configLibraries.argDB = argDB
367*179860b2SJed Brown      for obj in self.sharedLinkerObject.values():
368*179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
369*179860b2SJed Brown          obj.configLibraries.argDB = argDB
370*179860b2SJed Brown      for obj in self.dynamicLinkerObject.values():
371*179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
372*179860b2SJed Brown          obj.configLibraries.argDB = argDB
373*179860b2SJed Brown    return
374*179860b2SJed Brown  argDB = property(args.ArgumentProcessor.getArgDB, setArgDB, doc = 'The RDict argument database')
375*179860b2SJed Brown
376*179860b2SJed Brown  def getLanguageModule(self, language, moduleName = None):
377*179860b2SJed Brown    '''Return the module associated with operations for a given language
378*179860b2SJed Brown       - Giving a moduleName explicitly forces a reimport'''
379*179860b2SJed Brown    if not language in self.languageModule or not moduleName is None:
380*179860b2SJed Brown      try:
381*179860b2SJed Brown        if moduleName is None:
382*179860b2SJed Brown          moduleName = self.modulePath+'.'+language
383*179860b2SJed Brown        module     = __import__(moduleName)
384*179860b2SJed Brown      except ImportError, e:
385*179860b2SJed Brown        if not moduleName is None:
386*179860b2SJed Brown          self.logPrint('Failure to find language module: '+str(e))
387*179860b2SJed Brown        try:
388*179860b2SJed Brown          moduleName = self.modulePath+'.'+language
389*179860b2SJed Brown          module     = __import__(moduleName)
390*179860b2SJed Brown        except ImportError, e:
391*179860b2SJed Brown          self.logPrint('Failure to find language module: '+str(e))
392*179860b2SJed Brown          moduleName = 'config.compile.'+language
393*179860b2SJed Brown          module     = __import__(moduleName)
394*179860b2SJed Brown      components = moduleName.split('.')
395*179860b2SJed Brown      for component in components[1:]:
396*179860b2SJed Brown        module   = getattr(module, component)
397*179860b2SJed Brown      module._loadName = moduleName
398*179860b2SJed Brown      self.languageModule[language] = module
399*179860b2SJed Brown    return self.languageModule[language]
400*179860b2SJed Brown
401*179860b2SJed Brown  def getPreprocessorObject(self, language):
402*179860b2SJed Brown    if not language in self.preprocessorObject:
403*179860b2SJed Brown      self.preprocessorObject[language] = self.getLanguageModule(language).Preprocessor(self.argDB)
404*179860b2SJed Brown      self.preprocessorObject[language].setup()
405*179860b2SJed Brown    if not self.compilers is None:
406*179860b2SJed Brown      self.preprocessorObject[language].configCompilers = self.compilers
407*179860b2SJed Brown    if not self.versionControl is None:
408*179860b2SJed Brown      self.preprocessorObject[language].versionControl  = self.versionControl
409*179860b2SJed Brown    return self.preprocessorObject[language]
410*179860b2SJed Brown
411*179860b2SJed Brown  def setPreprocessorObject(self, language, preprocessor):
412*179860b2SJed Brown    self.preprocessorObject[language] = preprocessor
413*179860b2SJed Brown    return self.getPreprocessorObject(language)
414*179860b2SJed Brown
415*179860b2SJed Brown  def getCompilerObject(self, language):
416*179860b2SJed Brown    if not language in self.compilerObject:
417*179860b2SJed Brown      self.compilerObject[language] = self.getLanguageModule(language).Compiler(self.argDB)
418*179860b2SJed Brown      self.compilerObject[language].setup()
419*179860b2SJed Brown    if not self.compilers is None:
420*179860b2SJed Brown      self.compilerObject[language].configCompilers = self.compilers
421*179860b2SJed Brown    if not self.versionControl is None:
422*179860b2SJed Brown      self.compilerObject[language].versionControl  = self.versionControl
423*179860b2SJed Brown    return self.compilerObject[language]
424*179860b2SJed Brown
425*179860b2SJed Brown  def setCompilerObject(self, language, compiler):
426*179860b2SJed Brown    self.compilerObject[language] = compiler
427*179860b2SJed Brown    return self.getCompilerObject(language)
428*179860b2SJed Brown
429*179860b2SJed Brown  def getLinkerObject(self, language):
430*179860b2SJed Brown    if not language in self.linkerObject:
431*179860b2SJed Brown      self.linkerObject[language] = self.getLanguageModule(language).Linker(self.argDB)
432*179860b2SJed Brown      self.linkerObject[language].setup()
433*179860b2SJed Brown    if not self.compilers is None:
434*179860b2SJed Brown      self.linkerObject[language].configCompilers = self.compilers
435*179860b2SJed Brown    if not self.libraries is None:
436*179860b2SJed Brown      self.linkerObject[language].configLibraries = self.libraries
437*179860b2SJed Brown    if not self.versionControl is None:
438*179860b2SJed Brown      self.linkerObject[language].versionControl  = self.versionControl
439*179860b2SJed Brown    return self.linkerObject[language]
440*179860b2SJed Brown
441*179860b2SJed Brown  def setLinkerObject(self, language, linker):
442*179860b2SJed Brown    self.linkerObject[language] = linker
443*179860b2SJed Brown    return self.getLinkerObject(language)
444*179860b2SJed Brown
445*179860b2SJed Brown  def getSharedLinkerObject(self, language):
446*179860b2SJed Brown    if not language in self.sharedLinkerObject:
447*179860b2SJed Brown      self.sharedLinkerObject[language] = self.getLanguageModule(language).SharedLinker(self.argDB)
448*179860b2SJed Brown      self.sharedLinkerObject[language].setup()
449*179860b2SJed Brown    if not self.compilers is None:
450*179860b2SJed Brown      self.sharedLinkerObject[language].configCompilers = self.compilers
451*179860b2SJed Brown    if not self.libraries is None:
452*179860b2SJed Brown      self.sharedLinkerObject[language].configLibraries = self.libraries
453*179860b2SJed Brown    if not self.versionControl is None:
454*179860b2SJed Brown      self.sharedLinkerObject[language].versionControl  = self.versionControl
455*179860b2SJed Brown    return self.sharedLinkerObject[language]
456*179860b2SJed Brown
457*179860b2SJed Brown  def setSharedLinkerObject(self, language, linker):
458*179860b2SJed Brown    self.sharedLinkerObject[language] = linker
459*179860b2SJed Brown    return self.getSharedLinkerObject(language)
460*179860b2SJed Brown
461*179860b2SJed Brown  def getDynamicLinkerObject(self, language):
462*179860b2SJed Brown    if not language in self.dynamicLinkerObject:
463*179860b2SJed Brown      self.dynamicLinkerObject[language] = self.getLanguageModule(language).DynamicLinker(self.argDB)
464*179860b2SJed Brown      self.dynamicLinkerObject[language].setup()
465*179860b2SJed Brown    if not self.compilers is None:
466*179860b2SJed Brown      self.dynamicLinkerObject[language].configCompilers = self.compilers
467*179860b2SJed Brown    if not self.libraries is None:
468*179860b2SJed Brown      self.dynamicLinkerObject[language].configLibraries = self.libraries
469*179860b2SJed Brown    if not self.versionControl is None:
470*179860b2SJed Brown      self.dynamicLinkerObject[language].versionControl  = self.versionControl
471*179860b2SJed Brown    return self.dynamicLinkerObject[language]
472*179860b2SJed Brown
473*179860b2SJed Brown  def setDynamicLinkerObject(self, language, linker):
474*179860b2SJed Brown    self.dynamicLinkerObject[language] = linker
475*179860b2SJed Brown    return self.getDynamicLinkerObject(language)
476