xref: /petsc/config/BuildSystem/script.py (revision df3bd252dbc574245cbbb4edf6b407438c525c05)
15b6bfdb9SJed Brownfrom __future__ import print_function
25b6bfdb9SJed Brownfrom __future__ import absolute_import
3179860b2SJed Brownimport sys
4179860b2SJed Brownif not hasattr(sys, 'version_info'):
55b6bfdb9SJed Brown  print('*** Python version 1 is not supported. Please get the latest version from www.python.org ***')
6179860b2SJed Brown  sys.exit(4)
7179860b2SJed Brown
8492432c8SJed Brownimport pickle
9179860b2SJed Brown
10179860b2SJed Brownimport subprocess
11179860b2SJed Brown
12179860b2SJed Brownimport nargs
130542e31aSBarry Smith
140542e31aSBarry Smith# Uses threads to monitor running programs and time them out if they take too long
15179860b2SJed BrownuseThreads = nargs.Arg.findArgument('useThreads', sys.argv[1:])
160542e31aSBarry Smithif useThreads == 'no' or useThreads == '0':
1792626d4aSBarry Smith  useThreads = 0
180542e31aSBarry Smithelif useThreads == None or useThreads == 'yes' or useThreads == '1':
1992626d4aSBarry Smith  useThreads = 1
20179860b2SJed Brownelse:
2192626d4aSBarry Smith  raise RuntimeError('Unknown option value for --useThreads ',useThreads)
22179860b2SJed Brown
23179860b2SJed BrownuseSelect = nargs.Arg.findArgument('useSelect', sys.argv[1:])
240542e31aSBarry Smithif useSelect == 'no' or useSelect == '0':
2592626d4aSBarry Smith  useSelect = 0
260542e31aSBarry Smithelif  useSelect is None or useSelect == 'yes' or useSelect == '1':
27179860b2SJed Brown  useSelect = 1
28179860b2SJed Brownelse:
2992626d4aSBarry Smith  raise RuntimeError('Unknown option value for --useSelect ',useSelect)
30179860b2SJed Brown
310542e31aSBarry Smith#  Run parts of configure in parallel, does not currently work;
320542e31aSBarry Smith#  see config/BuildSystem/config/framework.parallelQueueEvaluation()
330542e31aSBarry SmithuseParallel = nargs.Arg.findArgument('useParallel', sys.argv[1:])
340542e31aSBarry Smithif useParallel == 'no' or useParallel == '0':
350542e31aSBarry Smith  useParallel = 0
360542e31aSBarry Smithelif  useParallel is None or useParallel == 'yes':
370542e31aSBarry Smith  useParallel = 5
380542e31aSBarry Smithelse:
390542e31aSBarry Smith  if useParallel == '1':
400542e31aSBarry Smith    # handle case with --useParallel was used
410542e31aSBarry Smith    found = 0
420542e31aSBarry Smith    for i in sys.argv[1:]:
430542e31aSBarry Smith      if i.startswith('--useParallel='):
440542e31aSBarry Smith        found = 1
450542e31aSBarry Smith        break
460542e31aSBarry Smith    if found: useParallel = int(useParallel)
470542e31aSBarry Smith    else: useParallel = 5
480542e31aSBarry SmithuseParallel = 0
490542e31aSBarry Smith
50179860b2SJed Brownimport logger
51179860b2SJed Brown
52179860b2SJed Brownclass Script(logger.Logger):
53179860b2SJed Brown  def __init__(self, clArgs = None, argDB = None, log = None):
54179860b2SJed Brown    self.checkPython()
55179860b2SJed Brown    logger.Logger.__init__(self, clArgs, argDB, log)
56179860b2SJed Brown    self.shell = '/bin/sh'
57179860b2SJed Brown    self.showHelp = 1
58179860b2SJed Brown    return
59179860b2SJed Brown
60179860b2SJed Brown  def hasHelpFlag(self):
61179860b2SJed Brown    '''Decide whether to display the help message and exit'''
62179860b2SJed Brown    import nargs
63179860b2SJed Brown
64179860b2SJed Brown    if not self.showHelp:
65179860b2SJed Brown      return 0
66179860b2SJed Brown    if nargs.Arg.findArgument('help', self.clArgs) is None and nargs.Arg.findArgument('h', self.clArgs) is None:
67179860b2SJed Brown      return 0
68179860b2SJed Brown    return 1
69179860b2SJed Brown
7075f179b0SBarry Smith  def hasListFlag(self):
7175f179b0SBarry Smith    '''Decide whether to display the list of download files and exit'''
7275f179b0SBarry Smith    import nargs
7375f179b0SBarry Smith
7475f179b0SBarry Smith    if not self.showHelp:
7575f179b0SBarry Smith      return 0
760aa1f76dSSatish Balay    if nargs.Arg.findArgument('with-packages-download-dir', self.clArgs) is None:
7775f179b0SBarry Smith      return 0
7875f179b0SBarry Smith    return 1
7975f179b0SBarry Smith
80179860b2SJed Brown  def setupArguments(self, argDB):
81179860b2SJed Brown    '''This method now also creates the help and action logs'''
82179860b2SJed Brown    import help
83179860b2SJed Brown
84179860b2SJed Brown    argDB = logger.Logger.setupArguments(self, argDB)
85179860b2SJed Brown
86179860b2SJed Brown    self.help = help.Help(argDB)
87179860b2SJed Brown    self.help.title = 'Script Help'
88179860b2SJed Brown
89179860b2SJed Brown    self.actions = help.Info(argDB)
90179860b2SJed Brown    self.actions.title = 'Script Actions'
91179860b2SJed Brown
92179860b2SJed Brown    self.setupHelp(self.help)
93179860b2SJed Brown    return argDB
94179860b2SJed Brown
95179860b2SJed Brown  def setupHelp(self, help):
96179860b2SJed Brown    '''This method should be overidden to provide help for arguments'''
97179860b2SJed Brown    import nargs
98179860b2SJed Brown
99179860b2SJed Brown    help.addArgument('Script', '-h',    nargs.ArgBool(None, 0, 'Print this help message', isTemporary = 1), ignoreDuplicates = 1)
1000aa1f76dSSatish Balay    help.addArgument('Script', '-help', nargs.ArgBool(None, 0, 'Print this help message', isTemporary = 1), ignoreDuplicates = 1)
1010aa1f76dSSatish Balay    help.addArgument('Script', '-with-packages-download-dir=<dir>', nargs.ArgDir(None,None, 'Skip network download of package tarballs and locate them in specified dir. If not found in dir, print package URL - so it can be obtained manually.', isTemporary = 1), ignoreDuplicates = 1)
102179860b2SJed Brown    return help
103179860b2SJed Brown
104179860b2SJed Brown  def setup(self):
105179860b2SJed Brown    ''' This method checks to see whether help was requested'''
106179860b2SJed Brown    if hasattr(self, '_setup'):
107179860b2SJed Brown      return
108179860b2SJed Brown    logger.Logger.setup(self)
109179860b2SJed Brown    self._setup = 1
110179860b2SJed Brown    if self.hasHelpFlag():
111e1362b5bSMatthew G. Knepley      self.argDB.readonly = True
112179860b2SJed Brown      if self.argDB.target == ['default']:
113179860b2SJed Brown        sections = None
114179860b2SJed Brown      else:
115179860b2SJed Brown        sections = self.argDB.target
116179860b2SJed Brown      self.help.output(sections = sections)
117179860b2SJed Brown      sys.exit()
11875f179b0SBarry Smith    if self.hasListFlag():
11975f179b0SBarry Smith      self.help.outputDownload()
120179860b2SJed Brown    return
121179860b2SJed Brown
122179860b2SJed Brown  def cleanup(self):
123179860b2SJed Brown    '''This method outputs the action log'''
124179860b2SJed Brown    self.actions.output(self.log)
125179860b2SJed Brown    return
126179860b2SJed Brown
127179860b2SJed Brown  def checkPython(self):
128*df3bd252SSatish Balay    if not hasattr(sys, 'version_info') or sys.version_info < (3,4):
129*df3bd252SSatish Balay      raise RuntimeError('BuildSystem requires Python version 3.4 or higher. Get Python at https://www.python.org/')
130179860b2SJed Brown    return
131179860b2SJed Brown
1320d623e36SVaclav Hapla  @staticmethod
133179860b2SJed Brown  def getModule(root, name):
134179860b2SJed Brown    '''Retrieve a specific module from the directory root, bypassing the usual paths'''
135179860b2SJed Brown    import imp
136179860b2SJed Brown
137179860b2SJed Brown    (fp, pathname, description) = imp.find_module(name, [root])
138179860b2SJed Brown    try:
139179860b2SJed Brown      return imp.load_module(name, fp, pathname, description)
140179860b2SJed Brown    finally:
141179860b2SJed Brown      if fp: fp.close()
142179860b2SJed Brown
1430d623e36SVaclav Hapla  @staticmethod
144179860b2SJed Brown  def importModule(moduleName):
145179860b2SJed Brown    '''Import the named module, and return the module object
146179860b2SJed Brown       - Works properly for fully qualified names'''
147179860b2SJed Brown    module     = __import__(moduleName)
148179860b2SJed Brown    components = moduleName.split('.')
149179860b2SJed Brown    for comp in components[1:]:
150179860b2SJed Brown      module = getattr(module, comp)
151179860b2SJed Brown    return module
152179860b2SJed Brown
15350f8d48fSJed Brown  @staticmethod
15497565ffdSJunchao Zhang  def runShellCommand(command, log=None, cwd=None, env=None):
15597565ffdSJunchao Zhang    return Script.runShellCommandSeq([command], log=log, cwd=cwd, env=env)
15650f8d48fSJed Brown
15750f8d48fSJed Brown  @staticmethod
15897565ffdSJunchao Zhang  def runShellCommandSeq(commandseq, log=None, cwd=None, env=None):
159179860b2SJed Brown    Popen = subprocess.Popen
160179860b2SJed Brown    PIPE  = subprocess.PIPE
16150f8d48fSJed Brown    output = ''
16250f8d48fSJed Brown    error = ''
1630d623e36SVaclav Hapla    ret = 0
16450f8d48fSJed Brown    for command in commandseq:
16550f8d48fSJed Brown      useShell = isinstance(command, str) or isinstance(command, bytes)
166179860b2SJed Brown      if log: log.write('Executing: %s\n' % (command,))
16750f8d48fSJed Brown      try:
16897565ffdSJunchao Zhang        pipe = Popen(command, cwd=cwd, env=env, stdin=None, stdout=PIPE, stderr=PIPE,
1699467260aSSatish Balay                     shell=useShell)
170179860b2SJed Brown        (out, err) = pipe.communicate()
1719467260aSSatish Balay        out = out.decode(encoding='UTF-8',errors='replace')
1729467260aSSatish Balay        err = err.decode(encoding='UTF-8',errors='replace')
173179860b2SJed Brown        ret = pipe.returncode
174a952ef13SBarry Smith      except Exception as e:
1751a7b8b2eSBarry Smith        if hasattr(e,'message') and hasattr(e,'errno'):
17650f8d48fSJed Brown          return ('', e.message, e.errno)
1771a7b8b2eSBarry Smith        else:
1781a7b8b2eSBarry Smith          return ('', str(e),1)
17950f8d48fSJed Brown      output += out
18050f8d48fSJed Brown      error += err
18150f8d48fSJed Brown      if ret:
18250f8d48fSJed Brown        break
18350f8d48fSJed Brown    return (output, error, ret)
184179860b2SJed Brown
1850d623e36SVaclav Hapla  @staticmethod
186179860b2SJed Brown  def defaultCheckCommand(command, status, output, error):
187179860b2SJed Brown    '''Raise an error if the exit status is nonzero'''
188179860b2SJed Brown    if status: raise RuntimeError('Could not execute "%s":\n%s' % (command,output+error))
189179860b2SJed Brown
1900d623e36SVaclav Hapla  @staticmethod
19105f86fb1SBarry Smith  def passCheckCommand(command, status, output, error):
19205f86fb1SBarry Smith    '''Does not check the command results'''
19305f86fb1SBarry Smith
19450f8d48fSJed Brown  @staticmethod
19597565ffdSJunchao Zhang  def executeShellCommand(command, checkCommand = None, timeout = 600.0, log = None, lineLimit = 0, cwd=None, env=None, logOutputflg = True, threads = 0):
196179860b2SJed Brown    '''Execute a shell command returning the output, and optionally provide a custom error checker
197179860b2SJed Brown       - This returns a tuple of the (output, error, statuscode)'''
1981a87e097SBarry Smith    '''The timeout is ignored unless the threads values is nonzero'''
19997565ffdSJunchao Zhang    return Script.executeShellCommandSeq([command], checkCommand=checkCommand, timeout=timeout, log=log, lineLimit=lineLimit, cwd=cwd, env=env, logOutputflg = logOutputflg, threads = threads)
20050f8d48fSJed Brown
20150f8d48fSJed Brown  @staticmethod
20297565ffdSJunchao Zhang  def executeShellCommandSeq(commandseq, checkCommand = None, timeout = 600.0, log = None, lineLimit = 0, cwd=None, env=None, logOutputflg = True, threads = 0):
20350f8d48fSJed Brown    '''Execute a sequence of shell commands (an && chain) returning the output, and optionally provide a custom error checker
20450f8d48fSJed Brown       - This returns a tuple of the (output, error, statuscode)'''
205179860b2SJed Brown    if not checkCommand:
206179860b2SJed Brown      checkCommand = Script.defaultCheckCommand
207179860b2SJed Brown    if log is None:
208179860b2SJed Brown      log = logger.Logger.defaultLog
209c3ec109aSBarry Smith    def logOutput(log, output, logOutputflg):
210179860b2SJed Brown      import re
211c3ec109aSBarry Smith      if not logOutputflg: return output
212179860b2SJed Brown      # get rid of multiple blank lines
2139f0d583aSJed Brown      output = re.sub('\n+','\n', output).strip()
2144854f487SJed Brown      if output:
215179860b2SJed Brown        if lineLimit:
216179860b2SJed Brown          output = '\n'.join(output.split('\n')[:lineLimit])
2174854f487SJed Brown        if '\n' in output:      # multi-line output
2184854f487SJed Brown          log.write('stdout:\n'+output+'\n')
2194854f487SJed Brown        else:
2204854f487SJed Brown          log.write('stdout: '+output+'\n')
221179860b2SJed Brown      return output
22297565ffdSJunchao Zhang    def runInShell(commandseq, log, cwd, env):
2230542e31aSBarry Smith      if useThreads and threads:
224179860b2SJed Brown        import threading
2251a87e097SBarry Smith        log.write('Running Executable with threads to time it out at '+str(timeout)+'\n')
226179860b2SJed Brown        class InShell(threading.Thread):
227179860b2SJed Brown          def __init__(self):
228179860b2SJed Brown            threading.Thread.__init__(self)
229179860b2SJed Brown            self.name = 'Shell Command'
230179860b2SJed Brown            self.setDaemon(1)
231179860b2SJed Brown          def run(self):
232179860b2SJed Brown            (self.output, self.error, self.status) = ('', '', -1) # So these fields exist even if command fails with no output
23397565ffdSJunchao Zhang            (self.output, self.error, self.status) = Script.runShellCommandSeq(commandseq, log, cwd, env)
234179860b2SJed Brown        thread = InShell()
235179860b2SJed Brown        thread.start()
236179860b2SJed Brown        thread.join(timeout)
237ca038c9dSSatish Balay        if thread.is_alive():
2381a87e097SBarry Smith          error = 'Runaway process exceeded time limit of '+str(timeout)+'\n'
239179860b2SJed Brown          log.write(error)
240179860b2SJed Brown          return ('', error, -1)
241179860b2SJed Brown        else:
242179860b2SJed Brown          return (thread.output, thread.error, thread.status)
243179860b2SJed Brown      else:
24497565ffdSJunchao Zhang        return Script.runShellCommandSeq(commandseq, log, cwd, env)
245179860b2SJed Brown
24697565ffdSJunchao Zhang    (output, error, status) = runInShell(commandseq, log, cwd, env)
247c3ec109aSBarry Smith    output = logOutput(log, output,logOutputflg)
24850f8d48fSJed Brown    checkCommand(commandseq, status, output, error)
249179860b2SJed Brown    return (output, error, status)
250179860b2SJed Brown
251179860b2SJed Brown  def loadConfigure(self, argDB = None):
252179860b2SJed Brown    if argDB is None:
253179860b2SJed Brown      argDB = self.argDB
254179860b2SJed Brown    if not 'configureCache' in argDB:
255179860b2SJed Brown      self.logPrint('No cached configure in RDict at '+str(argDB.saveFilename))
256179860b2SJed Brown      return None
257179860b2SJed Brown    try:
258179860b2SJed Brown      cache = argDB['configureCache']
259492432c8SJed Brown      framework = pickle.loads(cache)
260179860b2SJed Brown      framework.framework = framework
261179860b2SJed Brown      framework.argDB = argDB
262179860b2SJed Brown      self.logPrint('Loaded configure to cache: size '+str(len(cache)))
263492432c8SJed Brown    except pickle.UnpicklingError as e:
264179860b2SJed Brown      framework = None
265179860b2SJed Brown      self.logPrint('Invalid cached configure: '+str(e))
266179860b2SJed Brown    return framework
267179860b2SJed Brown
268179860b2SJed Brownimport args
269179860b2SJed Brown
270179860b2SJed Brownclass LanguageProcessor(args.ArgumentProcessor):
271179860b2SJed Brown  def __init__(self, clArgs = None, argDB = None, framework = None, versionControl = None):
272179860b2SJed Brown    self.languageModule      = {}
273179860b2SJed Brown    self.preprocessorObject  = {}
274179860b2SJed Brown    self.compilerObject      = {}
275179860b2SJed Brown    self.linkerObject        = {}
276179860b2SJed Brown    self.sharedLinkerObject  = {}
277179860b2SJed Brown    self.dynamicLinkerObject = {}
278179860b2SJed Brown    self.framework           = framework
279179860b2SJed Brown    self.versionControl      = versionControl
280179860b2SJed Brown    args.ArgumentProcessor.__init__(self, clArgs, argDB)
281179860b2SJed Brown    self.outputFiles         = {}
282179860b2SJed Brown    self.modulePath          = 'config.compile'
283179860b2SJed Brown    return
284179860b2SJed Brown
285179860b2SJed Brown  def getCompilers(self):
286179860b2SJed Brown    if self.framework is None:
287179860b2SJed Brown      return
288179860b2SJed Brown    return self.framework.require('config.compilers', None)
289179860b2SJed Brown  compilers = property(getCompilers, doc = 'The config.compilers configure object')
290179860b2SJed Brown  def getLibraries(self):
291179860b2SJed Brown    if self.framework is None:
292179860b2SJed Brown      return
293179860b2SJed Brown    return self.framework.require('config.libraries', None)
294179860b2SJed Brown  libraries = property(getLibraries, doc = 'The config.libraries configure object')
295179860b2SJed Brown
296179860b2SJed Brown  def __getstate__(self, d = None):
297179860b2SJed Brown    '''We only want to pickle the language module names and output files. The other objects are set by configure.'''
298179860b2SJed Brown    if d is None:
299179860b2SJed Brown      d = args.ArgumentProcessor.__getstate__(self)
300179860b2SJed Brown    if 'languageModule' in d:
301179860b2SJed Brown      d['languageModule'] = dict([(lang,mod._loadName) for lang,mod in d['languageModule'].items()])
302179860b2SJed Brown    for member in ['preprocessorObject', 'compilerObject', 'linkerObject', 'sharedLinkerObject', 'dynamicLinkerObject', 'framework']:
303179860b2SJed Brown      if member in d:
304179860b2SJed Brown        del d[member]
305179860b2SJed Brown    return d
306179860b2SJed Brown
307179860b2SJed Brown  def __setstate__(self, d):
308179860b2SJed Brown    '''We must create the language modules'''
309179860b2SJed Brown    args.ArgumentProcessor.__setstate__(self, d)
310179860b2SJed Brown    self.__dict__.update(d)
311179860b2SJed Brown    [self.getLanguageModule(language, moduleName) for language,moduleName in self.languageModule.items()]
312179860b2SJed Brown    self.preprocessorObject  = {}
313179860b2SJed Brown    self.compilerObject      = {}
314179860b2SJed Brown    self.linkerObject        = {}
315179860b2SJed Brown    self.sharedLinkerObject  = {}
316179860b2SJed Brown    self.dynamicLinkerObject = {}
317179860b2SJed Brown    return
318179860b2SJed Brown
319179860b2SJed Brown  def setArgDB(self, argDB):
320179860b2SJed Brown    args.ArgumentProcessor.setArgDB(self, argDB)
321179860b2SJed Brown    for obj in self.preprocessorObject.values():
322179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
323179860b2SJed Brown        obj.argDB = argDB
324179860b2SJed Brown    for obj in self.compilerObject.values():
325179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
326179860b2SJed Brown        obj.argDB = argDB
327179860b2SJed Brown    for obj in self.linkerObject.values():
328179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
329179860b2SJed Brown        obj.argDB = argDB
330179860b2SJed Brown    for obj in self.sharedLinkerObject.values():
331179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
332179860b2SJed Brown        obj.argDB = argDB
333179860b2SJed Brown    for obj in self.dynamicLinkerObject.values():
334179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
335179860b2SJed Brown        obj.argDB = argDB
336179860b2SJed Brown    if not self.compilers is None:
337179860b2SJed Brown      self.compilers.argDB = argDB
338179860b2SJed Brown      for obj in self.preprocessorObject.values():
339179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
340179860b2SJed Brown          obj.configCompilers.argDB = argDB
341179860b2SJed Brown      for obj in self.compilerObject.values():
342179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
343179860b2SJed Brown          obj.configCompilers.argDB = argDB
344179860b2SJed Brown      for obj in self.linkerObject.values():
345179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
346179860b2SJed Brown          obj.configCompilers.argDB = argDB
347179860b2SJed Brown      for obj in self.sharedLinkerObject.values():
348179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
349179860b2SJed Brown          obj.configCompilers.argDB = argDB
350179860b2SJed Brown      for obj in self.dynamicLinkerObject.values():
351179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
352179860b2SJed Brown          obj.configCompilers.argDB = argDB
353179860b2SJed Brown    if not self.libraries is None:
354179860b2SJed Brown      self.libraries.argDB = argDB
355179860b2SJed Brown      for obj in self.linkerObject.values():
356179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
357179860b2SJed Brown          obj.configLibraries.argDB = argDB
358179860b2SJed Brown      for obj in self.sharedLinkerObject.values():
359179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
360179860b2SJed Brown          obj.configLibraries.argDB = argDB
361179860b2SJed Brown      for obj in self.dynamicLinkerObject.values():
362179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
363179860b2SJed Brown          obj.configLibraries.argDB = argDB
364179860b2SJed Brown    return
365179860b2SJed Brown  argDB = property(args.ArgumentProcessor.getArgDB, setArgDB, doc = 'The RDict argument database')
366179860b2SJed Brown
367179860b2SJed Brown  def getLanguageModule(self, language, moduleName = None):
368179860b2SJed Brown    '''Return the module associated with operations for a given language
369179860b2SJed Brown       - Giving a moduleName explicitly forces a reimport'''
370179860b2SJed Brown    if not language in self.languageModule or not moduleName is None:
371179860b2SJed Brown      try:
372179860b2SJed Brown        if moduleName is None:
373179860b2SJed Brown          moduleName = self.modulePath+'.'+language
374179860b2SJed Brown        module     = __import__(moduleName)
3755b6bfdb9SJed Brown      except ImportError as e:
376179860b2SJed Brown        if not moduleName is None:
377179860b2SJed Brown          self.logPrint('Failure to find language module: '+str(e))
378179860b2SJed Brown        try:
379179860b2SJed Brown          moduleName = self.modulePath+'.'+language
380179860b2SJed Brown          module     = __import__(moduleName)
3815b6bfdb9SJed Brown        except ImportError as e:
382179860b2SJed Brown          self.logPrint('Failure to find language module: '+str(e))
383179860b2SJed Brown          moduleName = 'config.compile.'+language
384179860b2SJed Brown          module     = __import__(moduleName)
385179860b2SJed Brown      components = moduleName.split('.')
386179860b2SJed Brown      for component in components[1:]:
387179860b2SJed Brown        module   = getattr(module, component)
388179860b2SJed Brown      module._loadName = moduleName
389179860b2SJed Brown      self.languageModule[language] = module
390179860b2SJed Brown    return self.languageModule[language]
391179860b2SJed Brown
392179860b2SJed Brown  def getPreprocessorObject(self, language):
393179860b2SJed Brown    if not language in self.preprocessorObject:
394179860b2SJed Brown      self.preprocessorObject[language] = self.getLanguageModule(language).Preprocessor(self.argDB)
395179860b2SJed Brown      self.preprocessorObject[language].setup()
396179860b2SJed Brown    if not self.compilers is None:
397179860b2SJed Brown      self.preprocessorObject[language].configCompilers = self.compilers
398179860b2SJed Brown    if not self.versionControl is None:
399179860b2SJed Brown      self.preprocessorObject[language].versionControl  = self.versionControl
400179860b2SJed Brown    return self.preprocessorObject[language]
401179860b2SJed Brown
402179860b2SJed Brown  def setPreprocessorObject(self, language, preprocessor):
403179860b2SJed Brown    self.preprocessorObject[language] = preprocessor
404179860b2SJed Brown    return self.getPreprocessorObject(language)
405179860b2SJed Brown
406179860b2SJed Brown  def getCompilerObject(self, language):
407179860b2SJed Brown    if not language in self.compilerObject:
408179860b2SJed Brown      self.compilerObject[language] = self.getLanguageModule(language).Compiler(self.argDB)
409179860b2SJed Brown      self.compilerObject[language].setup()
410179860b2SJed Brown    if not self.compilers is None:
411179860b2SJed Brown      self.compilerObject[language].configCompilers = self.compilers
412179860b2SJed Brown    if not self.versionControl is None:
413179860b2SJed Brown      self.compilerObject[language].versionControl  = self.versionControl
414179860b2SJed Brown    return self.compilerObject[language]
415179860b2SJed Brown
416179860b2SJed Brown  def setCompilerObject(self, language, compiler):
417179860b2SJed Brown    self.compilerObject[language] = compiler
418179860b2SJed Brown    return self.getCompilerObject(language)
419179860b2SJed Brown
420179860b2SJed Brown  def getLinkerObject(self, language):
421179860b2SJed Brown    if not language in self.linkerObject:
422179860b2SJed Brown      self.linkerObject[language] = self.getLanguageModule(language).Linker(self.argDB)
423179860b2SJed Brown      self.linkerObject[language].setup()
424179860b2SJed Brown    if not self.compilers is None:
425179860b2SJed Brown      self.linkerObject[language].configCompilers = self.compilers
426179860b2SJed Brown    if not self.libraries is None:
427179860b2SJed Brown      self.linkerObject[language].configLibraries = self.libraries
428179860b2SJed Brown    if not self.versionControl is None:
429179860b2SJed Brown      self.linkerObject[language].versionControl  = self.versionControl
430179860b2SJed Brown    return self.linkerObject[language]
431179860b2SJed Brown
432179860b2SJed Brown  def setLinkerObject(self, language, linker):
433179860b2SJed Brown    self.linkerObject[language] = linker
434179860b2SJed Brown    return self.getLinkerObject(language)
435179860b2SJed Brown
436179860b2SJed Brown  def getSharedLinkerObject(self, language):
437179860b2SJed Brown    if not language in self.sharedLinkerObject:
438179860b2SJed Brown      self.sharedLinkerObject[language] = self.getLanguageModule(language).SharedLinker(self.argDB)
439179860b2SJed Brown      self.sharedLinkerObject[language].setup()
440179860b2SJed Brown    if not self.compilers is None:
441179860b2SJed Brown      self.sharedLinkerObject[language].configCompilers = self.compilers
442179860b2SJed Brown    if not self.libraries is None:
443179860b2SJed Brown      self.sharedLinkerObject[language].configLibraries = self.libraries
444179860b2SJed Brown    if not self.versionControl is None:
445179860b2SJed Brown      self.sharedLinkerObject[language].versionControl  = self.versionControl
446179860b2SJed Brown    return self.sharedLinkerObject[language]
447179860b2SJed Brown
448179860b2SJed Brown  def setSharedLinkerObject(self, language, linker):
449179860b2SJed Brown    self.sharedLinkerObject[language] = linker
450179860b2SJed Brown    return self.getSharedLinkerObject(language)
451179860b2SJed Brown
452179860b2SJed Brown  def getDynamicLinkerObject(self, language):
453179860b2SJed Brown    if not language in self.dynamicLinkerObject:
454179860b2SJed Brown      self.dynamicLinkerObject[language] = self.getLanguageModule(language).DynamicLinker(self.argDB)
455179860b2SJed Brown      self.dynamicLinkerObject[language].setup()
456179860b2SJed Brown    if not self.compilers is None:
457179860b2SJed Brown      self.dynamicLinkerObject[language].configCompilers = self.compilers
458179860b2SJed Brown    if not self.libraries is None:
459179860b2SJed Brown      self.dynamicLinkerObject[language].configLibraries = self.libraries
460179860b2SJed Brown    if not self.versionControl is None:
461179860b2SJed Brown      self.dynamicLinkerObject[language].versionControl  = self.versionControl
462179860b2SJed Brown    return self.dynamicLinkerObject[language]
463179860b2SJed Brown
464179860b2SJed Brown  def setDynamicLinkerObject(self, language, linker):
465179860b2SJed Brown    self.dynamicLinkerObject[language] = linker
466179860b2SJed Brown    return self.getDynamicLinkerObject(language)
467