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