xref: /petsc/config/BuildSystem/script.py (revision b7d94e18c520d85223e25bcd98feacc3fb35a1f4)
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):
966aad120cSJose E. Roman    '''This method should be overridden 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):
128df3bd252SSatish Balay    if not hasattr(sys, 'version_info') or sys.version_info < (3,4):
129df3bd252SSatish 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):
18773f05c50SBarry Smith    '''Raise an error if the exit status is nonzero
18873f05c50SBarry Smith       Since output and error may be huge and the exception error message may be printed to the
18973f05c50SBarry Smith       screen we cannot print the entire output'''
19073f05c50SBarry Smith    if status:
19173f05c50SBarry Smith      mlen = 512//2
19273f05c50SBarry Smith      if len(output) > 2*mlen:
19373f05c50SBarry Smith        output = output[0:mlen]+'\n .... more output .....\n'+output[len(output)- mlen:]
19473f05c50SBarry Smith      if len(error) > 2*mlen:
19573f05c50SBarry Smith        error = error[0:mlen]+'\n .... more error .....\n'+error[len(error)- mlen:]
19673f05c50SBarry Smith      raise RuntimeError('Could not execute "%s":\n%s' % (command,output+error))
197179860b2SJed Brown
1980d623e36SVaclav Hapla  @staticmethod
19905f86fb1SBarry Smith  def passCheckCommand(command, status, output, error):
20005f86fb1SBarry Smith    '''Does not check the command results'''
20105f86fb1SBarry Smith
20250f8d48fSJed Brown  @staticmethod
20397565ffdSJunchao Zhang  def executeShellCommand(command, checkCommand = None, timeout = 600.0, log = None, lineLimit = 0, cwd=None, env=None, logOutputflg = True, threads = 0):
204179860b2SJed Brown    '''Execute a shell command returning the output, and optionally provide a custom error checker
205179860b2SJed Brown       - This returns a tuple of the (output, error, statuscode)'''
2061a87e097SBarry Smith    '''The timeout is ignored unless the threads values is nonzero'''
20797565ffdSJunchao Zhang    return Script.executeShellCommandSeq([command], checkCommand=checkCommand, timeout=timeout, log=log, lineLimit=lineLimit, cwd=cwd, env=env, logOutputflg = logOutputflg, threads = threads)
20850f8d48fSJed Brown
20950f8d48fSJed Brown  @staticmethod
21097565ffdSJunchao Zhang  def executeShellCommandSeq(commandseq, checkCommand = None, timeout = 600.0, log = None, lineLimit = 0, cwd=None, env=None, logOutputflg = True, threads = 0):
21150f8d48fSJed Brown    '''Execute a sequence of shell commands (an && chain) returning the output, and optionally provide a custom error checker
21250f8d48fSJed Brown       - This returns a tuple of the (output, error, statuscode)'''
213179860b2SJed Brown    if not checkCommand:
214179860b2SJed Brown      checkCommand = Script.defaultCheckCommand
215179860b2SJed Brown    if log is None:
216179860b2SJed Brown      log = logger.Logger.defaultLog
217c3ec109aSBarry Smith    def logOutput(log, output, logOutputflg):
218179860b2SJed Brown      import re
219c3ec109aSBarry Smith      if not logOutputflg: return output
220179860b2SJed Brown      # get rid of multiple blank lines
2219f0d583aSJed Brown      output = re.sub('\n+','\n', output).strip()
2224854f487SJed Brown      if output:
223179860b2SJed Brown        if lineLimit:
224179860b2SJed Brown          output = '\n'.join(output.split('\n')[:lineLimit])
2254854f487SJed Brown        if '\n' in output:      # multi-line output
2264854f487SJed Brown          log.write('stdout:\n'+output+'\n')
2274854f487SJed Brown        else:
2284854f487SJed Brown          log.write('stdout: '+output+'\n')
229179860b2SJed Brown      return output
23097565ffdSJunchao Zhang    def runInShell(commandseq, log, cwd, env):
2310542e31aSBarry Smith      if useThreads and threads:
232179860b2SJed Brown        import threading
2331a87e097SBarry Smith        log.write('Running Executable with threads to time it out at '+str(timeout)+'\n')
234179860b2SJed Brown        class InShell(threading.Thread):
235179860b2SJed Brown          def __init__(self):
236179860b2SJed Brown            threading.Thread.__init__(self)
237179860b2SJed Brown            self.name = 'Shell Command'
238179860b2SJed Brown            self.setDaemon(1)
239179860b2SJed Brown          def run(self):
240179860b2SJed Brown            (self.output, self.error, self.status) = ('', '', -1) # So these fields exist even if command fails with no output
24197565ffdSJunchao Zhang            (self.output, self.error, self.status) = Script.runShellCommandSeq(commandseq, log, cwd, env)
242179860b2SJed Brown        thread = InShell()
243179860b2SJed Brown        thread.start()
244179860b2SJed Brown        thread.join(timeout)
245ca038c9dSSatish Balay        if thread.is_alive():
2461a87e097SBarry Smith          error = 'Runaway process exceeded time limit of '+str(timeout)+'\n'
247179860b2SJed Brown          log.write(error)
248179860b2SJed Brown          return ('', error, -1)
249179860b2SJed Brown        else:
250179860b2SJed Brown          return (thread.output, thread.error, thread.status)
251179860b2SJed Brown      else:
25297565ffdSJunchao Zhang        return Script.runShellCommandSeq(commandseq, log, cwd, env)
253179860b2SJed Brown
25497565ffdSJunchao Zhang    (output, error, status) = runInShell(commandseq, log, cwd, env)
255c3ec109aSBarry Smith    output = logOutput(log, output,logOutputflg)
256*b7d94e18SBarry Smith    logOutput(log, error,logOutputflg)
25750f8d48fSJed Brown    checkCommand(commandseq, status, output, error)
258179860b2SJed Brown    return (output, error, status)
259179860b2SJed Brown
260179860b2SJed Brown  def loadConfigure(self, argDB = None):
261179860b2SJed Brown    if argDB is None:
262179860b2SJed Brown      argDB = self.argDB
263179860b2SJed Brown    if not 'configureCache' in argDB:
264179860b2SJed Brown      self.logPrint('No cached configure in RDict at '+str(argDB.saveFilename))
265179860b2SJed Brown      return None
266179860b2SJed Brown    try:
267179860b2SJed Brown      cache = argDB['configureCache']
268492432c8SJed Brown      framework = pickle.loads(cache)
269179860b2SJed Brown      framework.framework = framework
270179860b2SJed Brown      framework.argDB = argDB
271179860b2SJed Brown      self.logPrint('Loaded configure to cache: size '+str(len(cache)))
272492432c8SJed Brown    except pickle.UnpicklingError as e:
273179860b2SJed Brown      framework = None
274179860b2SJed Brown      self.logPrint('Invalid cached configure: '+str(e))
275179860b2SJed Brown    return framework
276179860b2SJed Brown
277179860b2SJed Brownimport args
278179860b2SJed Brown
279179860b2SJed Brownclass LanguageProcessor(args.ArgumentProcessor):
280179860b2SJed Brown  def __init__(self, clArgs = None, argDB = None, framework = None, versionControl = None):
281179860b2SJed Brown    self.languageModule      = {}
282179860b2SJed Brown    self.preprocessorObject  = {}
283179860b2SJed Brown    self.compilerObject      = {}
284179860b2SJed Brown    self.linkerObject        = {}
285179860b2SJed Brown    self.sharedLinkerObject  = {}
286179860b2SJed Brown    self.dynamicLinkerObject = {}
287179860b2SJed Brown    self.framework           = framework
288179860b2SJed Brown    self.versionControl      = versionControl
289179860b2SJed Brown    args.ArgumentProcessor.__init__(self, clArgs, argDB)
290179860b2SJed Brown    self.outputFiles         = {}
291179860b2SJed Brown    self.modulePath          = 'config.compile'
292179860b2SJed Brown    return
293179860b2SJed Brown
294179860b2SJed Brown  def getCompilers(self):
295179860b2SJed Brown    if self.framework is None:
296179860b2SJed Brown      return
297179860b2SJed Brown    return self.framework.require('config.compilers', None)
298179860b2SJed Brown  compilers = property(getCompilers, doc = 'The config.compilers configure object')
299179860b2SJed Brown  def getLibraries(self):
300179860b2SJed Brown    if self.framework is None:
301179860b2SJed Brown      return
302179860b2SJed Brown    return self.framework.require('config.libraries', None)
303179860b2SJed Brown  libraries = property(getLibraries, doc = 'The config.libraries configure object')
304179860b2SJed Brown
305179860b2SJed Brown  def __getstate__(self, d = None):
306179860b2SJed Brown    '''We only want to pickle the language module names and output files. The other objects are set by configure.'''
307179860b2SJed Brown    if d is None:
308179860b2SJed Brown      d = args.ArgumentProcessor.__getstate__(self)
309179860b2SJed Brown    if 'languageModule' in d:
310179860b2SJed Brown      d['languageModule'] = dict([(lang,mod._loadName) for lang,mod in d['languageModule'].items()])
311179860b2SJed Brown    for member in ['preprocessorObject', 'compilerObject', 'linkerObject', 'sharedLinkerObject', 'dynamicLinkerObject', 'framework']:
312179860b2SJed Brown      if member in d:
313179860b2SJed Brown        del d[member]
314179860b2SJed Brown    return d
315179860b2SJed Brown
316179860b2SJed Brown  def __setstate__(self, d):
317179860b2SJed Brown    '''We must create the language modules'''
318179860b2SJed Brown    args.ArgumentProcessor.__setstate__(self, d)
319179860b2SJed Brown    self.__dict__.update(d)
320179860b2SJed Brown    [self.getLanguageModule(language, moduleName) for language,moduleName in self.languageModule.items()]
321179860b2SJed Brown    self.preprocessorObject  = {}
322179860b2SJed Brown    self.compilerObject      = {}
323179860b2SJed Brown    self.linkerObject        = {}
324179860b2SJed Brown    self.sharedLinkerObject  = {}
325179860b2SJed Brown    self.dynamicLinkerObject = {}
326179860b2SJed Brown    return
327179860b2SJed Brown
328179860b2SJed Brown  def setArgDB(self, argDB):
329179860b2SJed Brown    args.ArgumentProcessor.setArgDB(self, argDB)
330179860b2SJed Brown    for obj in self.preprocessorObject.values():
331179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
332179860b2SJed Brown        obj.argDB = argDB
333179860b2SJed Brown    for obj in self.compilerObject.values():
334179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
335179860b2SJed Brown        obj.argDB = argDB
336179860b2SJed Brown    for obj in self.linkerObject.values():
337179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
338179860b2SJed Brown        obj.argDB = argDB
339179860b2SJed Brown    for obj in self.sharedLinkerObject.values():
340179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
341179860b2SJed Brown        obj.argDB = argDB
342179860b2SJed Brown    for obj in self.dynamicLinkerObject.values():
343179860b2SJed Brown      if not hasattr(obj, 'argDB') or not obj.argDB == argDB:
344179860b2SJed Brown        obj.argDB = argDB
345179860b2SJed Brown    if not self.compilers is None:
346179860b2SJed Brown      self.compilers.argDB = argDB
347179860b2SJed Brown      for obj in self.preprocessorObject.values():
348179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
349179860b2SJed Brown          obj.configCompilers.argDB = argDB
350179860b2SJed Brown      for obj in self.compilerObject.values():
351179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
352179860b2SJed Brown          obj.configCompilers.argDB = argDB
353179860b2SJed Brown      for obj in self.linkerObject.values():
354179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
355179860b2SJed Brown          obj.configCompilers.argDB = argDB
356179860b2SJed Brown      for obj in self.sharedLinkerObject.values():
357179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
358179860b2SJed Brown          obj.configCompilers.argDB = argDB
359179860b2SJed Brown      for obj in self.dynamicLinkerObject.values():
360179860b2SJed Brown        if hasattr(obj, 'configCompilers'):
361179860b2SJed Brown          obj.configCompilers.argDB = argDB
362179860b2SJed Brown    if not self.libraries is None:
363179860b2SJed Brown      self.libraries.argDB = argDB
364179860b2SJed Brown      for obj in self.linkerObject.values():
365179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
366179860b2SJed Brown          obj.configLibraries.argDB = argDB
367179860b2SJed Brown      for obj in self.sharedLinkerObject.values():
368179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
369179860b2SJed Brown          obj.configLibraries.argDB = argDB
370179860b2SJed Brown      for obj in self.dynamicLinkerObject.values():
371179860b2SJed Brown        if hasattr(obj, 'configLibraries'):
372179860b2SJed Brown          obj.configLibraries.argDB = argDB
373179860b2SJed Brown    return
374179860b2SJed Brown  argDB = property(args.ArgumentProcessor.getArgDB, setArgDB, doc = 'The RDict argument database')
375179860b2SJed Brown
376179860b2SJed Brown  def getLanguageModule(self, language, moduleName = None):
377179860b2SJed Brown    '''Return the module associated with operations for a given language
378179860b2SJed Brown       - Giving a moduleName explicitly forces a reimport'''
379179860b2SJed Brown    if not language in self.languageModule or not moduleName is None:
380179860b2SJed Brown      try:
381179860b2SJed Brown        if moduleName is None:
382179860b2SJed Brown          moduleName = self.modulePath+'.'+language
383179860b2SJed Brown        module     = __import__(moduleName)
3845b6bfdb9SJed Brown      except ImportError as e:
385179860b2SJed Brown        if not moduleName is None:
386179860b2SJed Brown          self.logPrint('Failure to find language module: '+str(e))
387179860b2SJed Brown        try:
388179860b2SJed Brown          moduleName = self.modulePath+'.'+language
389179860b2SJed Brown          module     = __import__(moduleName)
3905b6bfdb9SJed Brown        except ImportError as e:
391179860b2SJed Brown          self.logPrint('Failure to find language module: '+str(e))
392179860b2SJed Brown          moduleName = 'config.compile.'+language
393179860b2SJed Brown          module     = __import__(moduleName)
394179860b2SJed Brown      components = moduleName.split('.')
395179860b2SJed Brown      for component in components[1:]:
396179860b2SJed Brown        module   = getattr(module, component)
397179860b2SJed Brown      module._loadName = moduleName
398179860b2SJed Brown      self.languageModule[language] = module
399179860b2SJed Brown    return self.languageModule[language]
400179860b2SJed Brown
401179860b2SJed Brown  def getPreprocessorObject(self, language):
402179860b2SJed Brown    if not language in self.preprocessorObject:
403179860b2SJed Brown      self.preprocessorObject[language] = self.getLanguageModule(language).Preprocessor(self.argDB)
404179860b2SJed Brown      self.preprocessorObject[language].setup()
405179860b2SJed Brown    if not self.compilers is None:
406179860b2SJed Brown      self.preprocessorObject[language].configCompilers = self.compilers
407179860b2SJed Brown    if not self.versionControl is None:
408179860b2SJed Brown      self.preprocessorObject[language].versionControl  = self.versionControl
409179860b2SJed Brown    return self.preprocessorObject[language]
410179860b2SJed Brown
411179860b2SJed Brown  def setPreprocessorObject(self, language, preprocessor):
412179860b2SJed Brown    self.preprocessorObject[language] = preprocessor
413179860b2SJed Brown    return self.getPreprocessorObject(language)
414179860b2SJed Brown
415179860b2SJed Brown  def getCompilerObject(self, language):
416179860b2SJed Brown    if not language in self.compilerObject:
417179860b2SJed Brown      self.compilerObject[language] = self.getLanguageModule(language).Compiler(self.argDB)
418179860b2SJed Brown      self.compilerObject[language].setup()
419179860b2SJed Brown    if not self.compilers is None:
420179860b2SJed Brown      self.compilerObject[language].configCompilers = self.compilers
421179860b2SJed Brown    if not self.versionControl is None:
422179860b2SJed Brown      self.compilerObject[language].versionControl  = self.versionControl
423179860b2SJed Brown    return self.compilerObject[language]
424179860b2SJed Brown
425179860b2SJed Brown  def setCompilerObject(self, language, compiler):
426179860b2SJed Brown    self.compilerObject[language] = compiler
427179860b2SJed Brown    return self.getCompilerObject(language)
428179860b2SJed Brown
429179860b2SJed Brown  def getLinkerObject(self, language):
430179860b2SJed Brown    if not language in self.linkerObject:
431179860b2SJed Brown      self.linkerObject[language] = self.getLanguageModule(language).Linker(self.argDB)
432179860b2SJed Brown      self.linkerObject[language].setup()
433179860b2SJed Brown    if not self.compilers is None:
434179860b2SJed Brown      self.linkerObject[language].configCompilers = self.compilers
435179860b2SJed Brown    if not self.libraries is None:
436179860b2SJed Brown      self.linkerObject[language].configLibraries = self.libraries
437179860b2SJed Brown    if not self.versionControl is None:
438179860b2SJed Brown      self.linkerObject[language].versionControl  = self.versionControl
439179860b2SJed Brown    return self.linkerObject[language]
440179860b2SJed Brown
441179860b2SJed Brown  def setLinkerObject(self, language, linker):
442179860b2SJed Brown    self.linkerObject[language] = linker
443179860b2SJed Brown    return self.getLinkerObject(language)
444179860b2SJed Brown
445179860b2SJed Brown  def getSharedLinkerObject(self, language):
446179860b2SJed Brown    if not language in self.sharedLinkerObject:
447179860b2SJed Brown      self.sharedLinkerObject[language] = self.getLanguageModule(language).SharedLinker(self.argDB)
448179860b2SJed Brown      self.sharedLinkerObject[language].setup()
449179860b2SJed Brown    if not self.compilers is None:
450179860b2SJed Brown      self.sharedLinkerObject[language].configCompilers = self.compilers
451179860b2SJed Brown    if not self.libraries is None:
452179860b2SJed Brown      self.sharedLinkerObject[language].configLibraries = self.libraries
453179860b2SJed Brown    if not self.versionControl is None:
454179860b2SJed Brown      self.sharedLinkerObject[language].versionControl  = self.versionControl
455179860b2SJed Brown    return self.sharedLinkerObject[language]
456179860b2SJed Brown
457179860b2SJed Brown  def setSharedLinkerObject(self, language, linker):
458179860b2SJed Brown    self.sharedLinkerObject[language] = linker
459179860b2SJed Brown    return self.getSharedLinkerObject(language)
460179860b2SJed Brown
461179860b2SJed Brown  def getDynamicLinkerObject(self, language):
462179860b2SJed Brown    if not language in self.dynamicLinkerObject:
463179860b2SJed Brown      self.dynamicLinkerObject[language] = self.getLanguageModule(language).DynamicLinker(self.argDB)
464179860b2SJed Brown      self.dynamicLinkerObject[language].setup()
465179860b2SJed Brown    if not self.compilers is None:
466179860b2SJed Brown      self.dynamicLinkerObject[language].configCompilers = self.compilers
467179860b2SJed Brown    if not self.libraries is None:
468179860b2SJed Brown      self.dynamicLinkerObject[language].configLibraries = self.libraries
469179860b2SJed Brown    if not self.versionControl is None:
470179860b2SJed Brown      self.dynamicLinkerObject[language].versionControl  = self.versionControl
471179860b2SJed Brown    return self.dynamicLinkerObject[language]
472179860b2SJed Brown
473179860b2SJed Brown  def setDynamicLinkerObject(self, language, linker):
474179860b2SJed Brown    self.dynamicLinkerObject[language] = linker
475179860b2SJed Brown    return self.getDynamicLinkerObject(language)
476