xref: /petsc/config/BuildSystem/config/utilities/missing.py (revision 184b5a2ebdab3f1a9f61d1d96434018aa026c18c)
1from __future__ import generators
2import config.base
3
4class Configure(config.base.Configure):
5  def __init__(self, framework):
6    config.base.Configure.__init__(self, framework)
7    self.headerPrefix = ''
8    self.substPrefix  = ''
9    return
10
11  def __str__(self):
12    return ''
13
14  def setupHelp(self, help):
15    import nargs
16    return
17
18  def setupDependencies(self, framework):
19    config.base.Configure.setupDependencies(self, framework)
20    self.compilers = framework.require('config.compilers', self)
21    self.functions = framework.require('config.functions', self)
22    self.libraries = framework.require('config.libraries', self)
23    self.ftm = framework.require('config.utilities.featureTestMacros', self)
24    return
25
26  def featureTestMacros(self):
27    features = ''
28    if self.ftm.defines.get('_POSIX_C_SOURCE_200112L'):
29      features += '''
30#if !defined(_POSIX_C_SOURCE)
31#define _POSIX_C_SOURCE 200112L
32#endif
33'''
34    if self.ftm.defines.get('_BSD_SOURCE'):
35      features += '''
36#if !defined(_BSD_SOURCE)
37#define _BSD_SOURCE
38#endif
39'''
40    if self.ftm.defines.get('_DEFAULT_SOURCE'):
41      features += '''
42#if !defined(_DEFAULT_SOURCE)
43#define _DEFAULT_SOURCE
44#endif
45'''
46    if self.ftm.defines.get('_GNU_SOURCE'):
47      features += '''
48#if !defined(_GNU_SOURCE)
49#define _GNU_SOURCE
50#endif
51'''
52    return features
53
54  def configureMissingUtypeTypedefs(self):
55    ''' Checks if u_short is undefined '''
56    if not self.checkCompile('#include <sys/types.h>\n', 'u_short foo;\n(void)foo'):
57      self.addDefine('NEEDS_UTYPE_TYPEDEFS',1)
58    return
59
60  def configureMissingFunctions(self):
61    '''Checks for SOCKETS and getline'''
62    if not self.functions.haveFunction('socket'):
63      # solaris requires these two libraries for socket()
64      if self.libraries.haveLib('socket') and self.libraries.haveLib('nsl'):
65        # check if it can find the function
66        if self.functions.check('socket',['-lsocket','-lnsl']):
67          self.compilers.LIBS += ' -lsocket -lnsl'
68
69      # Windows requires Ws2_32.lib for socket(), uses stdcall, and declspec prototype decoration
70      if self.libraries.add('Ws2_32.lib','socket',prototype='#include <Winsock2.h>',call='socket(0,0,0);'):
71        self.addDefine('HAVE_WINSOCK2_H',1)
72        if self.checkLink('#include <Winsock2.h>','closesocket(0)'):
73          self.addDefine('HAVE_CLOSESOCKET',1)
74        if self.checkLink('#include <Winsock2.h>','WSAGetLastError()'):
75          self.addDefine('HAVE_WSAGETLASTERROR',1)
76    if not self.checkLink('#include <stdio.h>\nchar *lineptr;\nsize_t n;\nFILE *stream;\n', 'getline(&lineptr, &n, stream);\n'):
77      self.addDefine('MISSING_GETLINE', 1)
78    return
79
80  def configureMissingSignals(self):
81    '''Check for missing signals, and define MISSING_<signal name> if necessary'''
82    for signal in ['ABRT', 'ALRM', 'BUS',  'CHLD', 'CONT', 'FPE',  'HUP',  'ILL', 'INT',  'KILL', 'PIPE', 'QUIT', 'SEGV',
83                   'STOP', 'SYS',  'TERM', 'TRAP', 'TSTP', 'URG',  'USR1', 'USR2']:
84      if not self.checkCompile('#include <signal.h>\n', 'int i=SIG'+signal+';\n(void)i'):
85        self.addDefine('MISSING_SIG'+signal, 1)
86    return
87
88  def configureMissingGetdomainnamePrototype(self):
89    '''Check for missing function prototype for getdomainname()'''
90    head = self.featureTestMacros() + '''
91#ifdef PETSC_HAVE_UNISTD_H
92#include <unistd.h>
93#endif
94#ifdef PETSC_HAVE_NETDB_H
95#include <netdb.h>
96#endif
97'''
98    def code(t):
99      """The type of the len parameter is size_t on Linux and int on BSD, so we'll have to try both."""
100      return '''
101int (*getdomainname_ptr)(char*,%s) = getdomainname;
102char test[10];
103if (getdomainname_ptr(test,10)) return 1;
104''' % (t,)
105    if not (self.checkCompile(head,code('size_t')) or self.checkCompile(head,code('int'))):
106      self.addPrototype('#include <stddef.h>\nint getdomainname(char *, size_t);', 'C')
107    if hasattr(self.compilers, 'CXX'):
108      self.pushLanguage('C++')
109      if not (self.checkLink(head,code('size_t')) or self.checkLink(head,code('int'))):
110        self.addPrototype('#include <stddef.h>\nint getdomainname(char *, size_t);', 'extern C')
111      self.popLanguage()
112    return
113
114  def configureMissingSrandPrototype(self):
115    '''Checks for missing random number generator prototypes'''
116    head = self.featureTestMacros() + '''
117#include <stdlib.h>
118'''
119    code = '''
120double (*drand48_ptr)(void) = drand48;
121void (*srand48_ptr)(long int) = srand48;
122long int seed=10;
123srand48_ptr(seed);
124if (drand48_ptr() > 0.5) return 1;
125'''
126    if not self.checkCompile(head,code):
127      self.addPrototype('double drand48(void);', 'C')
128      self.addPrototype('void   srand48(long int);', 'C')
129    if hasattr(self.compilers, 'CXX'):
130      self.pushLanguage('C++')
131      if not self.checkLink(head,code):
132        self.addPrototype('double drand48(void);', 'extern C')
133        self.addPrototype('void   srand48(long int);', 'extern C')
134      self.popLanguage()
135    return
136
137  def configureMissingShmget(self):
138    if self.functions.check('shmget'):
139      self.addDefine('HAVE_SHMGET',1)
140
141  def configure(self):
142    self.executeTest(self.configureMissingUtypeTypedefs)
143    self.executeTest(self.configureMissingFunctions)
144    self.executeTest(self.configureMissingSignals)
145    self.executeTest(self.configureMissingGetdomainnamePrototype)
146    self.executeTest(self.configureMissingSrandPrototype)
147    self.executeTest(self.configureMissingShmget)
148    return
149