xref: /petsc/config/BuildSystem/config/compilerFlags.py (revision 691b26d3a7ce3263bd9be9c446af0af2a46feecf)
1import config.base
2
3import re
4import os
5
6class Configure(config.base.Configure):
7  def __init__(self, framework):
8    config.base.Configure.__init__(self, framework)
9    self.headerPrefix = ''
10    self.substPrefix  = ''
11    self.version = {}
12    self.rejected = {}
13    return
14
15  def __str__(self):
16    return ''
17
18  def setupHelp(self, help):
19    import nargs
20    help.addArgument('Compiler Flags', '-optionsModule=<module name>', nargs.Arg(None, 'config.compilerOptions', 'The Python module used to determine compiler options and versions'))
21    help.addArgument('Compiler Flags', '-with-debugging=<bool>', nargs.ArgBool(None, 1, 'Specify debugging version of libraries'))
22    help.addArgument('Compiler Flags', '-C_VERSION=<string>',   nargs.Arg(None, 'Unknown', 'The version of the C compiler'))
23    help.addArgument('Compiler Flags', '-CXX_VERSION=<string>', nargs.Arg(None, 'Unknown', 'The version of the C++ compiler'))
24    help.addArgument('Compiler Flags', '-FC_VERSION=<string>',  nargs.Arg(None, 'Unknown', 'The version of the Fortran compiler'))
25    help.addArgument('Compiler Flags', '-CUDA_VERSION=<string>',nargs.Arg(None, 'Unknown', 'The version of the CUDA compiler'))
26    help.addArgument('Compiler Flags', '-COPTFLAGS=<string>',   nargs.Arg(None, None, 'Override the debugging/optimization flags for the C compiler'))
27    help.addArgument('Compiler Flags', '-CXXOPTFLAGS=<string>', nargs.Arg(None, None, 'Override the debugging/optimization flags for the C++ compiler'))
28    help.addArgument('Compiler Flags', '-FOPTFLAGS=<string>',   nargs.Arg(None, None, 'Override the debugging/optimization flags for the Fortran compiler'))
29    help.addArgument('Compiler Flags', '-CUDAOPTFLAGS=<string>',   nargs.Arg(None, None, 'Override the debugging/optimization flags for the CUDA compiler'))
30    # not sure where to put this, currently gcov is handled in ../compilerOptions.py
31    help.addArgument('Compiler Flags', '-with-gcov=<bool>', nargs.ArgBool(None, 0, 'Specify that GNUs coverage tool gcov is used'))
32    return
33
34  def setupDependencies(self, framework):
35    config.base.Configure.setupDependencies(self, framework)
36    self.setCompilers = framework.require('config.setCompilers', self)
37    return
38
39  def getOptionalFlagsName(self, language, compilerOnly = 0):
40    if language == 'C':
41      flagsArg = 'COPTFLAGS'
42    elif language == 'Cxx':
43      if compilerOnly:
44        flagsArg = 'CXX_CXXOPTFLAGS'
45      else:
46        flagsArg = 'CXXOPTFLAGS'
47    elif language == 'FC':
48      flagsArg = 'FOPTFLAGS'
49    elif language == 'CUDA':
50      flagsArg = 'CUDAOPTFLAGS'
51    else:
52      raise RuntimeError('Unknown language: '+language)
53    return flagsArg
54
55  def hasOptFlags(self,flags):
56    for flag in flags.split():
57      if flag.startswith('-g') or flag.startswith('-O') or flag in ['-fast']:
58        return 1
59    return 0
60
61  def getOptionsObject(self):
62    '''Get a configure object which will return default options for each compiler'''
63    options = None
64    try:
65      mod     = __import__(self.argDB['optionsModule'], locals(), globals(), ['CompilerOptions'])
66      options = mod.CompilerOptions(self.framework)
67      options.setup()
68    except ImportError:
69      self.logPrint('ERROR: Failed to load user options module '+str(self.argDB['optionsModule']))
70    return options
71
72  def configureCompilerFlags(self):
73    '''Get the default compiler flags'''
74    self.debugging = self.argDB['with-debugging']
75    bopts = ['']
76    if self.debugging:
77      bopts.append('g')
78    else:
79      bopts.append('O')
80
81    # According to gcc doc, gcov does not require -g, so we do it alone
82    if self.argDB['with-gcov']:
83      bopts.append('gcov')
84
85    options = self.getOptionsObject()
86    if not options:
87      return
88    options.saveLog()
89    for language, compiler in [('C', 'CC'), ('Cxx', 'CXX'), ('FC', 'FC'), ('CUDA', 'CUDAC')]:
90      if not hasattr(self.setCompilers, compiler):
91        continue
92      self.setCompilers.pushLanguage(language)
93      flagsName = config.base.Configure.getCompilerFlagsName(language)
94      try:
95        self.version[language] = self.argDB[language.upper()+'_VERSION']
96        if self.version[language] == 'Unknown':
97          self.version[language] = options.getCompilerVersion(language, self.setCompilers.getCompiler())
98      except RuntimeError:
99        pass
100      try:
101        self.rejected[language] = []
102        for bopt in bopts:
103          if bopt in ['g','O'] and self.getOptionalFlagsName(language) in self.argDB: # check --COPTFLAGS etc
104            # treat user supplied options as single option - as it could include options separated by spaces '-tp k8-64'
105            flags = [self.argDB[self.getOptionalFlagsName(language)]]
106          elif bopt in ['g','O'] and self.hasOptFlags(getattr(self.setCompilers,flagsName)): # check --CFLAGS etc
107            self.logPrint('Optimization options found in '+flagsName+ '. Skipping setting defaults')
108            flags = []
109          elif bopt == '' and flagsName in self.argDB:
110            self.logPrint('Ignoring default options which were overridden using --'+flagsName+ ' ' + self.argDB[flagsName])
111            flags = []
112          else:
113            flags = options.getCompilerFlags(language, self.setCompilers.getCompiler(), bopt)
114
115          for testFlag in flags:
116            if isinstance(testFlag,tuple):
117              testFlag = ' '.join(testFlag)
118            try:
119              self.logPrint('Trying '+language+' compiler flag '+testFlag)
120              self.setCompilers.saveLog()
121              self.setCompilers.addCompilerFlag(testFlag)
122              self.logWrite(self.setCompilers.restoreLog())
123            except RuntimeError:
124              self.logWrite(self.setCompilers.restoreLog())
125              self.logPrint('Rejected '+language+' compiler flag '+testFlag)
126              self.rejected[language].append(testFlag)
127      except RuntimeError:
128        pass
129      self.setCompilers.popLanguage()
130    return
131
132  def configure(self):
133    self.executeTest(self.configureCompilerFlags)
134    return
135