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