1import config.base 2 3import os 4import re 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.sizes = {} 12 self.c99_complex = 0 13 self.cxx_complex = 0 14 return 15 16 def setupHelp(self, help): 17 import nargs 18 help.addArgument('Visibility', '-with-visibility=<bool>', nargs.ArgBool(None, 1, 'Use compiler visibility flags to limit symbol visibility')) 19 return 20 21 def setupDependencies(self, framework): 22 config.base.Configure.setupDependencies(self, framework) 23 self.compilers = framework.require('config.compilers', self) 24 self.headers = framework.require('config.headers', self) 25 return 26 27 def check(self, typeName, defaultType = None, includes = []): 28 '''Checks that "typeName" exists, and if not defines it to "defaultType" if given''' 29 self.log.write('Checking for type: '+typeName+'\n') 30 include = ''' 31#include <sys/types.h> 32#include <stdlib.h> 33#include <stddef.h> 34%s 35 ''' % ('\n'.join(['#include<%s>' % inc for inc in includes])) 36 found = self.checkCompile(include,typeName+' a;') 37 if not found and defaultType: 38 self.addTypedef(defaultType, typeName) 39 else: 40 self.log.write(typeName+' found\n') 41 return found 42 43 def check_struct_sigaction(self): 44 '''Checks if "struct sigaction" exists in signal.h. This check is for C89 check.''' 45 if self.check('struct sigaction', includes = ['signal.h']): 46 self.addDefine('HAVE_STRUCT_SIGACTION',1) 47 return 48 49 def check__int64(self): 50 '''Checks if __int64 exists. This is primarily for windows.''' 51 if self.check('__int64'): 52 self.addDefine('HAVE___INT64',1) 53 return 54 55 def checkSizeTypes(self): 56 '''Checks for types associated with sizes, such as size_t.''' 57 self.check('size_t', 'int') 58 return 59 60 def checkIntegerTypes(self): 61 '''Checks for types associated with integers, such as int32_t.''' 62 self.check('int32_t', 'int') 63 return 64 65 def checkFileTypes(self): 66 '''Checks for types associated with files, such as mode_t, off_t, etc.''' 67 self.check('mode_t', 'int') 68 self.check('off_t', 'int') 69 return 70 71 def checkPID(self): 72 '''Checks for pid_t, and defines it if necessary''' 73 return self.check('pid_t', 'int') 74 75 def checkUID(self): 76 '''Checks for uid_t and gid_t, and defines them if necessary''' 77 if self.outputPreprocess('#include <sys/types.h>').find('uid_t') < 0: 78 self.addDefine('uid_t', 'int') 79 self.addDefine('gid_t', 'int') 80 return 81 82 def checkC99Complex(self): 83 '''Check for complex numbers in in C99 std 84 Note that since PETSc source code uses _Complex we test specifically for that, not complex''' 85 includes = '#include <complex.h>\n' 86 body = 'double _Complex x;\n x = I;\n' 87 if not self.checkCompile(includes, body): return # checkLink can succeed even if checkCompile fails 88 if self.checkLink(includes, body): 89 self.addDefine('HAVE_C99_COMPLEX', 1) 90 self.c99_complex = 1 91 return 92 93 def checkCxxComplex(self): 94 '''Check for complex numbers in namespace std''' 95 self.pushLanguage('C++') 96 includes = '#include <complex>\n' 97 body = 'std::complex<double> x;\n' 98 if self.checkLink(includes, body): 99 self.addDefine('HAVE_CXX_COMPLEX', 1) 100 self.cxx_complex = 1 101 self.popLanguage() 102 return 103 104 def checkConst(self): 105 '''Checks for working const, and if not found defines it to empty string''' 106 body = ''' 107 /* Ultrix mips cc rejects this. */ 108 typedef int charset[2]; const charset x; 109 /* SunOS 4.1.1 cc rejects this. */ 110 char const *const *ccp; 111 char **p; 112 /* NEC SVR4.0.2 mips cc rejects this. */ 113 struct point {int x, y;}; 114 static struct point const zero = {0,0}; 115 /* AIX XL C 1.02.0.0 rejects this. 116 It does not let you subtract one const X* pointer from another in an arm 117 of an if-expression whose if-part is not a constant expression */ 118 const char *g = "string"; 119 ccp = &g + (g ? g-g : 0); 120 /* HPUX 7.0 cc rejects these. */ 121 ++ccp; 122 p = (char**) ccp; 123 ccp = (char const *const *) p; 124 /* This section avoids unused variable warnings */ 125 if (zero.x); 126 if (x[0]); 127 { /* SCO 3.2v4 cc rejects this. */ 128 char *t; 129 char const *s = 0 ? (char *) 0 : (char const *) 0; 130 131 *t++ = 0; 132 if (*s); 133 } 134 { /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */ 135 int x[] = {25, 17}; 136 const int *foo = &x[0]; 137 ++foo; 138 } 139 { /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */ 140 typedef const int *iptr; 141 iptr p = 0; 142 ++p; 143 } 144 { /* AIX XL C 1.02.0.0 rejects this saying 145 "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */ 146 struct s { int j; const int *ap[3]; }; 147 struct s *b; b->j = 5; 148 } 149 { /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */ 150 const int foo = 10; 151 152 /* Get rid of unused variable warning */ 153 if (foo); 154 } 155 ''' 156 if not self.checkCompile('', body): 157 self.addDefine('const', '') 158 return 159 160 def checkSizeof(self, typeName, typeSizes, otherInclude = None, lang='C', save=True, codeBegin=''): 161 '''Determines the size of type "typeName", and defines SIZEOF_"typeName" to be the size''' 162 self.log.write('Checking for size of type: ' + typeName + '\n') 163 typename = typeName.replace(' ', '-').replace('*', 'p') 164 includes = ''' 165#include <sys/types.h> 166#include <stdlib.h> 167#include <stdio.h> 168#include <stddef.h>''' 169 mpiFix = ''' 170#define MPICH_IGNORE_CXX_SEEK 171#define MPICH_SKIP_MPICXX 1 172#define OMPI_SKIP_MPICXX 1\n''' 173 if otherInclude: 174 if otherInclude == 'mpi.h': 175 includes += mpiFix 176 includes += '#include <' + otherInclude + '>\n' 177 size = None 178 checkName = typeName 179 if typeName == 'enum': 180 checkName = 'enum{ENUM_DUMMY}' 181 with self.Language(lang): 182 for s in typeSizes: 183 body = 'char assert_sizeof[(sizeof({0})=={1})*2-1];'.format(checkName, s) 184 if self.checkCompile(includes, body, codeBegin=codeBegin, codeEnd='\n'): 185 size = s 186 break 187 if size is None: 188 raise RuntimeError('Unable to determine size of {0} not found'.format(typeName)) 189 if save: 190 self.sizes[typename] = size 191 self.addDefine('SIZEOF_'+typename.replace('-', '_').upper(), str(size)) 192 return size 193 194 def checkVisibility(self): 195 if not self.argDB['with-shared-libraries']: 196 self.argDB['with-visibility'] = 0 197 self.log.write('Disabled visibility attributes due to static build') 198 elif self.argDB['with-visibility']: 199 self.pushLanguage('C') 200 if self.checkCompile('','__attribute__((visibility ("default"))) int foo(void);'): 201 self.addDefine('USE_VISIBILITY_C',1) 202 else: 203 self.log.write('Cannot use visibility attributes with C') 204 self.argDB['with-visibility'] = 0 205 self.popLanguage() 206 if hasattr(self.compilers, 'CXX'): 207 self.pushLanguage('C++') 208 if self.checkCompile('','__attribute__((visibility ("default"))) int foo(void);'): 209 self.addDefine('USE_VISIBILITY_CXX',1) 210 else: 211 self.log.write('Cannot use visibility attributes with C++') 212 self.popLanguage() 213 else: 214 self.log.write('User turned off visibility attributes') 215 216 def checkMaxPathLen(self): 217 import re 218 HASHLINESPACE = ' *(?:\n#.*\n *)*' 219 self.log.write('Determining PETSC_MAX_PATH_LEN\n') 220 include = '' 221 if self.headers.haveHeader('sys/param.h'): 222 include = (include + '\n#include <sys/param.h>') 223 if self.headers.haveHeader('sys/types.h'): 224 include = (include + '\n#include <sys/types.h>') 225 length = include + ''' 226#if defined(MAXPATHLEN) 227# define PETSC_MAX_PATH_LEN MAXPATHLEN 228#elif defined(MAX_PATH) 229# define PETSC_MAX_PATH_LEN MAX_PATH 230#elif defined(_MAX_PATH) 231# define PETSC_MAX_PATH_LEN _MAX_PATH 232#else 233# define PETSC_MAX_PATH_LEN 4096 234#endif 235int petsc_max_path_len = PETSC_MAX_PATH_LEN; 236''' 237 MaxPathLength = 'unknown' 238 if self.checkCompile(length): 239 buf = self.outputPreprocess(length) 240 try: 241 MaxPathLength = re.compile('\nint petsc_max_path_len ='+HASHLINESPACE+'([0-9]+)'+HASHLINESPACE+';').search(buf).group(1) 242 except: 243 raise RuntimeError('Unable to determine PETSC_MAX_PATH_LEN') 244 if MaxPathLength == 'unknown' or not MaxPathLength.isdigit(): 245 raise RuntimeError('Unable to determine PETSC_MAX_PATH_LEN') 246 else: 247 self.addDefine('MAX_PATH_LEN',MaxPathLength) 248 249 250 def configure(self): 251 self.executeTest(self.check_struct_sigaction) 252 self.executeTest(self.check__int64) 253 self.executeTest(self.checkSizeTypes) 254 self.executeTest(self.checkFileTypes) 255 self.executeTest(self.checkIntegerTypes) 256 self.executeTest(self.checkPID) 257 self.executeTest(self.checkUID) 258 self.executeTest(self.checkC99Complex) 259 if hasattr(self.compilers, 'CXX'): 260 self.executeTest(self.checkCxxComplex) 261 self.executeTest(self.checkConst) 262 for t, sizes in {'void *': (8, 4), 263 'short': (2, 4, 8), 264 'int': (4, 8, 2), 265 'long': (8, 4), 266 'long long': (8,), 267 'enum': (4, 8), 268 'size_t': (8, 4)}.items(): 269 self.executeTest(self.checkSizeof, args=[t, sizes]) 270 self.executeTest(self.checkVisibility) 271 self.executeTest(self.checkMaxPathLen) 272 return 273