#-*-python-*- # SCons file to create Environment() for building Postgres libpq library import os from buildhelp import RATROOT, ROOTARCH, testenv import glob import pickle def rat_path(*args): """ Returns the canonical path to join(RATROOT, *args) by eliminating any symbolic links encountered in the path. Without this, scons will rebuild everything when compiling over NFS. """ return os.path.realpath(os.path.join(RATROOT, *args)) def checkSelectArgType(conf): ''' Adapted from autoconf ''' conf.Message('Checking for arg types for select... ') for arg234 in ['fd_set *', 'int *', 'void *']: for arg1 in ['int', 'size_t', 'unsigned long', 'unsigned']: for arg5 in ['struct timeval *', 'const struct timeval *']: check_select_source = ''' #if HAVE_SYS_SELECT_H # include #endif #if HAVE_SYS_SOCKET_H # include #endif extern int select (%s, %s, %s, %s, %s); int main() { return(0); } ''' % (arg1, arg234, arg234, arg234, arg5) ret = conf.TryLink(check_select_source, '.c') if ret: conf.Result(ret) return (arg1, arg234, arg5) conf.Result('no (use default)') return ('int', 'int *', 'struct timeval *') def checkAlignment(context,type): # -------------------------------------------- # Tries to find the compile-time value of EXPR in a program that includes # INCLUDES, setting VAR accordingly. Returns whether the value could be # computed context.Message('Determining size align of ' + type + '...') compile_src=''' #include #include #ifndef offsetof # define offsetof(type, member) ((char *) &((type *) 0)->member - (char *) 0) #endif typedef struct { char x; ''' + type + ''' y; } align_struc; /* end confdefs.h. */ int main () { printf("%d",(int) offsetof (align_struc, y)); return 0; } ''' ret = context.TryCompile(compile_src,'.c') if ret == 0: print 'Test failed.' Exit(1) ret = context.TryRun(compile_src,'.c') context.Result(str(ret[1])) return ret[1] def checkFlexArrayMember(context): context.Message('Checking for flexible array member...') program=''' /* end confdefs.h. */ #include #include #include struct s { int n; double d[]; }; int main () { int m = getchar (); struct s *p = malloc (offsetof (struct s, d) + m * sizeof (double)); p->d[0] = 0.0; return p->d != (double *) NULL; return 0; } ''' ret = context.TryCompile(program,'.c') if ret != 0: context.Result(True) return None else: context.Result(False) return 1 def checkInt64(context,type): context.Message('Checking if ' + type + ' is a working 64 bit integer type...') program=''' typedef ''' + type + ''' ac_int64; ac_int64 a = 20000001; ac_int64 b = 40000005; int does_int64_work() { ac_int64 c,d; if (sizeof(ac_int64) != 8) return 0; /* definitely not the right size */ /* Do perfunctory checks to see if 64-bit arithmetic seems to work */ c = a * b; d = (c + b) / b; if (d != a+1) return 0; return 1; } main() { exit(! does_int64_work()); } ''' ret = context.TryCompile(program,'.c') if ret == 0: print 'Test failed.' Exit(1) ret = context.TryRun(program,'.c') context.Result(ret[0]) if ret[0] == 1: return ret[0] else: return None def checkPosixSignal(context): context.Message('Checking for POSIX signal interface...') program = ''' #include int main () { struct sigaction act, oact; sigemptyset(&act.sa_mask); act.sa_flags = SA_RESTART; sigaction(0, &act, &oact); ; return 0; } ''' ret = context.TryCompile(program,'.c') if ret == 0: print 'Test failed.' Exit(1) ret = context.TryRun(program,'.c') context.Result(ret[0]) #print 'Got result ', ret if ret[0] == 1: return True else: return False def checkPPCHintBit(context): context.Message('Checking whether assembler supports lwarx hint bit...') program = ''' #include int main() { int a = 0; int *p = &a; int r; __asm__ __volatile__ (" lwarx %0,0,%1,1\n" : "=&r"(r) : "r"(p)); return 0; } ''' ret = context.TryCompile(program,'.c') context.Result(ret) #print ret if ret == 0: return False else: return True def checkMember(context,structure,member,includes=''): context.Message('Checking whether member ' + member + ' is part of ' + structure + '...') program = includes + ''' int main() { static ''' + structure + ''' ac_aggr; if (ac_aggr.'''+member+''') return 0; return 0; } ''' #print program ret = context.TryCompile(program,'.c') if ret == 0: context.Result(ret) return False ret = context.TryRun(program,'.c') context.Result(ret[0]) #print 'Got result ', ret if ret[0] == 1: return True else: return False def getTimeHeader(context): context.Message('Checking whether to use time.h ...') #try to program=''' #include #include int main () { struct tm tm; int *p = &tm.tm_sec; return !p; } ''' ret = context.TryCompile(program,'.c') #print ret if ret == 0: print 'Error performing check.' Exit(1) ret = context.TryRun(program,'.c') context.Result(ret[0]) #print 'Got result ', ret if ret[0] == 1: return "time.h" else: return "sys/time.h" def checkBuiltinTypesCompatible(context): context.Message('Checking whether compiler understands __builtin_types_compatible_p...') program=''' int main () { int x; static int y[__builtin_types_compatible_p(__typeof__(x), int)]; ; return 0; } ''' res = context.TryCompile(program,'.c') context.Result(res) if res == 0: return False else: return True def checkBuiltinUnreachable(context): context.Message('Checking whether compiler understands __builtin_unreachable...') program=''' int main () { __builtin_unreachable(); return 0; } ''' res = context.TryCompile(program,'.c') context.Result(res) if res == 0: return False else: return True def checkStaticAssert(context): context.Message('Checking whether compiler understands _Static_assert...') program=''' int main () { ({ _Static_assert(1, "foo"); }) ; return 0; } ''' res = context.TryCompile(program,'.c') context.Result(res) if res == 0: return False else: return True def checkVaArgs(context): context.Message('Checking whether compiler understands _Static_assert...') program=''' #include int main () { #define debug(...) fprintf(stderr, __VA_ARGS__) debug("%s", "blarg"); ; return 0; } ''' res = context.TryCompile(program,'.c') context.Result(res) if res == 0: return False else: return True def checkInt64Modifier(context,modifier): context.Message('Checking \''+modifier+'\' as snprintf length modifier for long long int...') program=''' #include typedef long long int ac_int64; #define INT64_FORMAT "%''' + modifier +'''d" ac_int64 a = 20000001; ac_int64 b = 40000005; int does_int64_snprintf_work() { ac_int64 c; char buf[100]; if (sizeof(ac_int64) != 8) { printf("Failed size.\\n"); return 0; /* doesn't look like the right size */ } c = a * b; snprintf(buf, 100, INT64_FORMAT, c); if (strcmp(buf, "800000140000005") != 0) { printf("Failed [%s]\\n",buf); return 0; /* either multiply or snprintf is busted */ } return 1; } main() { exit(! does_int64_snprintf_work()); } ''' #print program ret = context.TryCompile(program,'.c') #print "Return ",ret if ret == 0: context.Result(ret) return False ret = context.TryRun(program,'.c') context.Result(ret[0]) #print 'Got result ', ret #print context.lastTarget if ret[0] == 1: return True else: return False def checkInt128(context): context.Message('Checking for __int128...') program=''' /* * These are globals to discourage the compiler from folding all the * arithmetic tests down to compile-time constants. We do not have * convenient support for 64bit literals at this point... */ __int128 a = 48828125; __int128 b = 97656255; int main () { __int128 c,d; a = (a << 12) + 1; /* 200000000001 */ b = (b << 12) + 5; /* 400000000005 */ /* use the most relevant arithmetic ops */ c = a * b; d = (c + b) / b; /* return different values, to prevent optimizations */ if (d != a+1) return 0; return 1; ; return 0; } ''' ret = context.TryCompile(program,'.c') if ret == 0: context.Result(ret) return False ret = context.TryLink(program,'.c') context.Result(ret) if ret == 1: return True else: return False def checkQuietInline(context): context.Message('Checking for quiet inline (no complaint if unreferenced)...') program=''' /* * For the raison d'etre of this file, check the comment above the definition * of the PGAC_C_INLINE macro in config/c-compiler.m4. */ static inline int fun() { return 0; } /* * "IBM XL C/C++ for AIX, V12.1" miscompiles, for 32-bit, some inline * expansions of ginCompareItemPointers() "long long" arithmetic. To take * advantage of inlining, build a 64-bit PostgreSQL. */ #if defined(__ILP32__) && defined(__IBMC__) #error "known inlining bug" #endif int main () { ; return 0; } ''' res = context.TryCompile(program,'.c') context.Result(res) if res == 0: return False else: return True def checkStrErrorR(context): context.Message('Checking whether strerror_r returns int...') program = ''' /* end confdefs.h. */ #include int main () { #ifndef _AIX int strerror_r(int, char *, size_t); #else /* Older AIX has 'int' for the third argument so we don't test the args. */ int strerror_r(); #endif ; return 0; } ''' ret = context.TryCompile(program,'.c') context.Result(ret) if ret == 0: return False else: return True def checkSize_tSupportSnprintf(context,inttype,modifier): context.Message('Checking whether snprintf supports the %z modifier...') program=''' /* end confdefs.h. */ #include #include int main() { char bufz[100]; char buf64[100]; /* * Print the largest unsigned number fitting in a size_t using both %zu * and the previously-determined format for 64-bit integers. Note that * we don't run this code unless we know snprintf handles 64-bit ints. */ bufz[0] = '\\0'; /* in case snprintf fails to emit anything */ snprintf(bufz, sizeof(bufz), "%zu", ~((size_t) 0)); snprintf(buf64, sizeof(buf64), "%''' + modifier[1:-1]+'''u", (unsigned ''' + inttype +''') ~((size_t) 0)); if (strcmp(bufz, buf64) != 0) return 1; return 0; } ''' #print program ret = context.TryCompile(program,'.c') if ret == 0: context.Result(ret) return False ret = context.TryRun(program,'.c') context.Result(ret[0]) #print 'Got result ', ret if ret[0] == 1: return True else: return False def checkAcceptFcn(context,defines): context.Message('Checking types of arguments for accept()...') retlst = ['int','unsigned int PASCAL','SOCKET WSAAPI'] arg1lst = ['int','unsigned int','SOCKET'] arg2lst = ['struct sockaddr *','const struct sockaddr *','void *'] arg3lst = ['int','size_t','socklen_t','unsigned int','void'] headers = ''' #include #include ''' if defines.has_key('HAVE_SYS_TYPES_H'): headers = headers + ''' #include ''' if defines.has_key('HAVE_SYS_SOCKET_H'): headers = headers + ''' #include ''' declaration = '' for ret in retlst: for arg1 in arg1lst: for arg2 in arg2lst: for arg3 in arg3lst: program = headers + ''' extern ''' + ret +''' accept (''' +arg1 + ''',''' + arg2 + ''',''' +arg3+ '''*); int main () { ; return 0; } ''' res = context.TryCompile(program,'.c') if res == 0: # Failed this combination. Move to next. continue else: declaration = '''extern ''' + ret +''' accept (''' +arg1 + ''',''' + arg2 + ''',''' +arg3+ '''*);''' context.Result(declaration) if arg3 == 'void': arg3 = 'int' return True, (ret,arg1,arg2,arg3) context.Result('could not determine argument types!') return False , (None,None,None,None) ### ### Start the checks ### def psql_header_emitter(target,source,env): # for s in source: # print '/'.join(str(s).split('/')[3:]) target = [File(rat_path('include','libpq','/'.join(str(s).split('/')[3:]))) for s in source] return target,source def copy_generator(source,target,env,for_signature): #print target[0] , source[0] return Copy(target[0].path,source[0].path) ### ### ### Make the checks that the configure script makes ### These are used to construct the pg_config header file ### ### def configure_psqllib(): local_defines = {} incs = '' has_long_long = None time_header = '' int64_found = False need_repl_snprintf = True ## These are defined without testing, since they behave the same way in configure local_defines['BLCKSZ'] = 8192 local_defines['DEF_PGPORT'] = 5432 local_defines['DEF_PGPORT_STR'] = "\"5432\"" local_defines['ENABLE_THREAD_SAFETY'] = 1 local_defines['FLOAT4PASSBYVAL'] = "true" local_defines['FLOAT8PASSBYVAL'] = "true" #local_defines['XLOG_BLCKSZ'] = 8192 #local_defines['XLOG_SEG_SIZE'] = (16 * 1024 * 1024) local_defines['PG_VERSION_NUM'] = 90502 local_defines['PG_VERSION_STR'] = '\"PostgreSQL 9.5.2 on RAT\"' local_defines['PG_VERSION'] = '\"9.5.2\"' local_defines['PG_MAJORVERSION'] = '\"9.5\"' local_defines['PG_PRINTF_ATTRIBUTE'] = 'printf' ### ### ### This is the point that the environment is really set ### ### env = Environment() if os.environ.has_key("CC"): env.Replace(CC=os.environ["CC"]) if os.environ['RATSYSTEM'] == "Darwin": env.Append(CPPDEFINES=['_REENTRANT','_THREAD_SAFE','_POSIX_PTHREAD_SEMANTICS','FRONTEND','UNSAFE_STAT_OK','SO_MAJOR_VERSION=5']) # LINUX else: env.Append(CPPDEFINES=['_REENTRANT','_THREAD_SAFE','_POSIX_PTHREAD_SEMANTICS','REFINT_VERBOSE','_GNU_SOURCE']) conf = Configure(env,custom_tests = {'checkAlignment':checkAlignment, 'checkFlexArrayMember':checkFlexArrayMember, 'checkInt64':checkInt64, 'checkPosixSignal':checkPosixSignal, 'checkPPCHintBit':checkPPCHintBit, 'checkMember':checkMember, 'getTimeHeader':getTimeHeader, 'checkBuiltinTypesCompatible' : checkBuiltinTypesCompatible, 'checkBuiltinUnreachable':checkBuiltinUnreachable, 'checkStaticAssert':checkStaticAssert, 'checkVaArgs':checkVaArgs, 'checkInt128':checkInt128, 'checkInt64Modifier':checkInt64Modifier, 'checkQuietInline':checkQuietInline, 'checkStrErrorR':checkStrErrorR, 'checkSize_tSupportSnprintf':checkSize_tSupportSnprintf, 'checkAcceptFcn':checkAcceptFcn }) msg = ''' Performing checks to build Postgres library... ''' print(msg) for val in ['short','int','long','double']: local_defines['ALIGNOF_' + val.upper()] = conf.checkAlignment(val) local_defines['FLEXIBLE_ARRAY_MEMBER'] = conf.checkFlexArrayMember() if conf.CheckFunc('crypt',header='#include '): local_defines['HAVE_CRYPT'] = 1 if conf.CheckDeclaration('fdatasync',includes='#include '): local_defines['HAVE_DECL_FDATASYNC'] = 1 if conf.CheckDeclaration('F_FULLFSYNC',includes='#include '): local_defines['HAVE_DECL_F_FULLFSYNC'] = 1 if conf.CheckFunc('posix_fadvise',header='#include '): local_defines['HAVE_DECL_POSIX_FADVISE'] = 1 if conf.CheckFunc('snprintf'): local_defines['HAVE_DECL_SNPRINTF'] = 1 if conf.CheckFunc('vsnprintf'): local_defines['HAVE_DECL_VSNPRINTF'] = 1 #if conf.CheckFunc('strlcat',header='#include '): if conf.CheckFunc('strlcat'): local_defines['HAVE_DECL_STRLCAT'] = 1 if conf.CheckFunc('strlcpy'): local_defines['HAVE_DECL_STRLCPY'] = 1 # Not needed #if conf.CheckFunc('sys_siglist'): # local_defines['HAVE_DECL_SYS_SIGLIST'] = 1 #if conf.CheckFunc('dlopen'): # local_defines['HAVE_DLOPEN'] = 1 if conf.CheckFunc('fdatasync',header='#include '): local_defines['HAVE_FDATASYNC'] = 1 incs=''' #include #include ''' if conf.CheckFunc('fls',header=incs): local_defines['HAVE_FLS'] = 1 if conf.CheckFunc('fseeko'): local_defines['HAVE_FSEEKO'] = 1 #if conf.CheckDeclaration('__func__'): # local_defines['HAVE_FUNCNAME__FUNC'] = 1 # #if conf.CheckDeclaration('__FUNCTION__'): # local_defines['HAVE_FUNCNAME__FUNCTION'] = 1 # incs=''' #include ''' if conf.CheckFunc('getaddrinfo',header=incs): #if conf.CheckFunc('getaddrinfo'): local_defines['HAVE_GETADDRINFO'] = 1 if conf.CheckFunc('gethostbyname_r'): local_defines['HAVE_GETHOSTBYNAME_R'] = 1 if conf.CheckFunc('getifaddrs'): local_defines['HAVE_GETIFADDRS'] = 1 #if conf.CheckFunc('getopt'): # local_defines['HAVE_GETOPT'] = 1 # #if conf.CheckHeader('getopt.h'): # local_defines['HAVE_GETOPT_H'] = 1 # #if conf.CheckFunc('getopt_long'): # local_defines['HAVE_GETOPT_LONG'] = 1 # #if conf.CheckFunc('getpeereid'): # local_defines['HAVE_GETPEEREID'] = 1 # incs=''' #include ''' if conf.CheckFunc('getpeereid',header=incs): local_defines['HAVE_GETPEEREID'] = 1 # #if conf.CheckFunc('getpwuid_r'): # local_defines['HAVE_GETPWUID_R'] = 1 # #if conf.CheckFunc('getrlimit'): # local_defines['HAVE_GETRLIMIT'] = 1 # #if conf.CheckFunc('getrusage'): # local_defines['HAVE_GETRUSAGE'] = 1 if conf.CheckFunc('gettimeofday'): local_defines['HAVE_GETTIMEOFDAY'] = 1 if conf.CheckHeader('gssapi/gssapi.h'): local_defines['HAVE_GSSAPI_GSSAPI_H'] = 1 if conf.CheckHeader('gssapi.h'): local_defines['HAVE_GSSAPI_H'] = 1 if conf.CheckHeader('history.h'): local_defines['HAVE_HISTORY_H'] = 1 if conf.CheckFunc('history_truncate_file'): local_defines['HAVE_HISTORY_TRUNCATE_FILE'] = 1 if conf.CheckHeader('ieeefp.h'): local_defines['HAVE_IEEEFP_H'] = 1 if conf.CheckHeader('ifaddrs.h'): local_defines['HAVE_IFADDRS_H'] = 1 if conf.CheckFunc('inet_aton'): local_defines['HAVE_INET_ATON'] = 1 if conf.CheckHeader('inttypes.h'): local_defines['HAVE_INTTYPES_H'] = 1 incs=''' #include ''' if conf.CheckType('int64',includes=incs): local_defines['HAVE_INT64'] = 1 if conf.CheckType('int8',includes=incs): local_defines['HAVE_INT8'] = 1 if conf.CheckType('intptr_t',includes=incs): local_defines['HAVE_INTPTR_T'] = 1 if conf.CheckType('struct sockaddr_in6',includes='#include '): local_defines['HAVE_IPV6'] = 1 incs=''' #include #include ''' if conf.CheckFunc('isinf',header=incs): local_defines['HAVE_ISINF'] = 1 if conf.CheckHeader('langinfo.h'): local_defines['HAVE_LANGINFO_H'] = 1 if conf.CheckLib('-lm'): local_defines['HAVE_LIBM'] = 1 if conf.CheckLib('-lz'): local_defines['HAVE_LIBZ'] = 1 # Check for the valid definition of 64 bit int if conf.checkInt64('long int') == 1: int64_found = True local_defines['HAVE_LONG_INT_64'] =1 local_defines['PG_INT64_TYPE'] = 'long int' has_long_long = conf.CheckType('long long int',includes='#include ') if has_long_long == 1: local_defines['HAVE_LONG_LONG_INT'] = 1 if has_long_long: if conf.checkInt64('long long int') == 1: local_defines['HAVE_LONG_LONG_INT_64'] =1 if not int64_found: local_defines['PG_INT64_TYPE'] = 'long long int' if conf.CheckFunc('memmove'): # ,header='#include '): local_defines['HAVE_MEMMOVE'] = 1 if conf.CheckHeader('memory.h'): local_defines['HAVE_MEMORY_H'] = 1 if conf.CheckFunc('mkdtemp'): local_defines['HAVE_MKDTEMP'] = 1 if conf.CheckHeader('netinet/in.h'): local_defines['HAVE_NETINET_IN_H'] = 1 if conf.CheckHeader('netinet/tcp.h'): local_defines['HAVE_NETINET_TCP_H'] = 1 if conf.CheckHeader('net/if.h'): local_defines['HAVE_NET_IF_H'] = 1 if conf.CheckHeader('poll.h'): local_defines['HAVE_POLL_H'] = 1 if conf.CheckFunc('poll'): local_defines['HAVE_POLL'] = 1 if conf.CheckFunc('posix_fadvise'): local_defines['HAVE_POSIX_FADVISE'] = 1 if conf.checkPosixSignal(): local_defines['HAVE_POSIX_SIGNALS'] = 1 if conf.checkPPCHintBit(): local_defines['HAVE_PPC_LWARX_MUTEX_HINT'] = 1 #if conf.CheckFunc('pthread_is_threaded_np'): # local_defines['HAVE_PTHREAD_IS_THREADED_NP'] = 1 if conf.CheckFunc('random'): local_defines['HAVE_RANDOM'] = 1 if conf.CheckFunc('rint'): local_defines['HAVE_RINT'] = 1 if conf.CheckType('sig_atomic_t',includes='#include '): local_defines['HAVE_SIG_ATOMIC_T'] = 1 if conf.CheckFunc('snprintf'): local_defines['HAVE_SNPRINTF'] = 1 if conf.CheckFunc('srandom'): local_defines['HAVE_SRANDOM'] = 1 if conf.CheckHeader('stdint.h'): local_defines['HAVE_STDINT_H'] = 1 if conf.CheckHeader('stdlib.h'): local_defines['HAVE_STDLIB_H'] = 1 if conf.CheckFunc('strerror'): local_defines['HAVE_STRERROR'] = 1 if conf.CheckFunc('strerror_r'): local_defines['HAVE_STRERROR_R'] = 1 if conf.CheckHeader('strings.h'): local_defines['HAVE_STRINGS_H'] = 1 if conf.CheckFunc('strtoll'): local_defines['HAVE_STRTOLL'] = 1 if conf.CheckFunc('strtoq'): local_defines['HAVE_STRTOQ'] = 1 if conf.CheckFunc('strtoull'): local_defines['HAVE_STRTOULL'] = 1 if conf.CheckFunc('strtouq'): local_defines['HAVE_STRTOUQ'] = 1 if conf.CheckHeader('sys/socket.h'): local_defines['HAVE_SYS_SOCKET_H'] = 1 incs='''#include #include #include ''' if conf.CheckType('struct addrinfo',includes=incs): local_defines['HAVE_STRUCT_ADDRINFO'] = 1 if conf.CheckType('struct sockaddr',includes=incs): local_defines['HAVE_STRUCT_ADDRINFO'] = 1 incs = ''' #include #include ''' if local_defines.has_key('HAVE_SYS_SOCKET_H'): incs = incs + ''' #include ''' if conf.checkMember('struct sockaddr','sa_len',includes=incs): local_defines['HAVE_STRUCT_SOCKADDR_SA_LEN'] = 1 if conf.CheckType('struct sockaddr_storage',includes=incs): local_defines['HAVE_STRUCT_SOCKADDR_STORAGE'] = 1 if conf.checkMember('struct sockaddr_storage','ss_family',includes=incs): local_defines['HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY'] = 1 if conf.checkMember('struct sockaddr_storage','ss_len',includes=incs): local_defines['HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN'] = 1 if conf.checkMember('struct sockaddr_storage','__ss_family',includes=incs): local_defines['HAVE_STRUCT_SOCKADDR_STORAGE_SS_FAMILY'] = 1 if conf.checkMember('struct sockaddr_storage','__ss_len',includes=incs): local_defines['HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN'] = 1 if conf.CheckHeader('time.h'): local_defines['HAVE_TIME_H'] = 1 if conf.CheckHeader('sys/time.h'): local_defines['HAVE_SYS_TIME_H'] = 1 time_header=conf.getTimeHeader() incs=''' #include #include <'''+time_header+'''> ''' if conf.checkMember('struct tm','tm_zone',includes=incs): local_defines['HAVE_STRUCT_TM_TM_ZONE'] = 1 if conf.CheckHeader('sys/ioctl.h'): local_defines['HAVE_SYS_IOCTL_H'] = 1 if conf.CheckHeader('sys/poll.h'): local_defines['HAVE_SYS_POLL_H'] = 1 if conf.CheckHeader('sys/select.h'): local_defines['HAVE_SYS_SELECT_H'] = 1 if conf.CheckHeader('sys/sockio.h'): local_defines['HAVE_SYS_SOCKIO_H'] = 1 if conf.CheckHeader('sys/ucred.h'): local_defines['HAVE_SYS_UCRED_H'] = 1 if conf.CheckHeader('sys/un.h'): local_defines['HAVE_SYS_UN_H'] = 1 if conf.CheckHeader('sys/termios.h'): local_defines['HAVE_SYS_TERMIOS_H'] = 1 if conf.CheckFunc('towlower'): local_defines['HAVE_TOWLOWER'] = 1 if conf.checkMember('struct tm','tm_zone',includes=incs): local_defines['HAVE_STRUCT_TM_TM_ZONE'] = 1 if conf.CheckType('uint64',includes='#include '): local_defines['HAVE_UINT64'] = 1 if conf.CheckType('uint8',includes='#include '): local_defines['HAVE_UINT8'] = 1 incs = '''#include ''' if local_defines.has_key('HAVE_SYS_UN_H'): incs = incs + ''' #include ''' if conf.CheckType('struct sockaddr_un',includes=incs): local_defines['HAVE_UNIX_SOCKETS'] = 1 if conf.CheckFunc('unsetenv'): local_defines['HAVE_UNSETENV'] = 1 #if conf.CheckType('unsigned long long int',includes=incs): # local_defines['HAVE_UNSIGNED_LONG_LONG_INT'] = 1 if conf.CheckFunc('unsetenv'): local_defines['HAVE_UNSETENV'] = 1 if conf.CheckFunc('wcstombs'): local_defines['HAVE_WCSTOMBS'] = 1 if conf.CheckFunc('wcstombs_l'): local_defines['HAVE_WCSTOMBS_L'] = 1 if conf.checkBuiltinTypesCompatible(): local_defines['HAVE__BUILTIN_TYPES_COMPATIBLE_P'] = 1 if conf.checkBuiltinUnreachable(): local_defines['HAVE__BUILTIN_UNREACHABLE'] = 1 if conf.checkStaticAssert(): local_defines['HAVE__STATIC_ASSERT'] = 1 if conf.checkVaArgs(): local_defines['HAVE__VA_ARGS'] = 1 long_long_int_modifier = 'll' for mod in ['l','ll','q','I64']: if conf.checkInt64Modifier(mod): need_repl_snprintf = False long_long_int_modifier = mod break if not local_defines.has_key('HAVE_LONG_LONG_INT_64'): need_repl_snprintf = False long_long_int_modifier = 'l' local_defines['INT64_MODIFIER'] = "\"%s\"" %(long_long_int_modifier) max_alignof = local_defines['ALIGNOF_LONG'] if max_alignof < local_defines['ALIGNOF_DOUBLE']: max_alignof = local_defines['ALIGNOF_DOUBLE'] if local_defines.has_key('HAVE_LONG_LONG_INT_64'): align_llint = conf.checkAlignment('long long int') if max_alignof < align_llint: max_alignof = align_llint local_defines['MAXIMUM_ALIGNOF'] = max_alignof local_defines['MEMSET_LOOP_LIMIT'] = 1024 if conf.checkInt128(): local_defines['PG_INT128_TYPE'] = '__int128' if conf.checkQuietInline(): local_defines['PG_USE_INLINE'] = 1 if conf.checkStrErrorR(): local_defines['STRERROR_R_INT'] = 1 local_defines['USE_INTEGER_DATETIMES'] = 1 if not conf.checkSize_tSupportSnprintf(local_defines['PG_INT64_TYPE'],local_defines['INT64_MODIFIER']): local_defines['USE_REPL_SNPRINTF'] = 1 # Check that accept does actually exist if conf.CheckFunc('accept'): local_defines['HAVE_ACCEPT'] = 1 if local_defines.has_key('HAVE_ACCEPT'): # Check the argument types res,defs = conf.checkAcceptFcn(local_defines) if res: local_defines['ACCEPT_TYPE_RETURN'] = defs[0] local_defines['ACCEPT_TYPE_ARG1'] = defs[1] local_defines['ACCEPT_TYPE_ARG2'] = defs[2] local_defines['ACCEPT_TYPE_ARG3'] = defs[3] else: print ''' Error: Could not find a good definition of accept(). ''' else: print ''' Error: Couldn't find a good definition of accept(). Missing some header file? ''' Exit(1) msg = '''PSQL::Producing the configuration header 'pg_config.h'...''' print(msg) fout = open(RATROOT + '/src/libpq/include/pg_config.h','w') defines= [] for key,value in local_defines.iteritems(): if value is not None: defines.append('#define %s %s\n' %(key,value)) else: defines.append('#define %s /**/\n' %(key)) fout.writelines(defines) fout.close() msg = '''PSQL::Producing the configuration header 'pg_config_ext.h'...''' print(msg) fout = open(RATROOT + '/src/libpq/include/pg_config_ext.h','w') if local_defines.has_key('PG_INT64_TYPE'): fout.write('#define PG_INT64_TYPE %s\n' %(local_defines['PG_INT64_TYPE'])) else: fout.write('#undef PG_INT64_TYPE\n') fout.close() #print local_defines env = conf.Finish() # pickle the defines into a temporary cache file msg = '''PSQL::Storing configuration into cache 'pg_config.pkl'...''' print(msg) fout = open(RATROOT + '/src/libpq/pg_config.pkl','wb') pickle.dump(local_defines, fout) fout.close() # Append this to the configuration anyway env.Append(PSQLDEFINES=local_defines) msg = ''' PostgreSQL configuration completed... ''' print(msg) return env ######## Everything down to this point does not need to ######## occur every single time ### Check if we need to configure or the headers already exist def check_configuration(): import os.path pg_conf = os.path.isfile(RATROOT + '/src/libpq/include/pg_config_ext.h') pg_conf_ext = os.path.isfile(RATROOT + '/src/libpq/include/pg_config.h') pg_pkl = os.path.isfile(RATROOT + '/src/libpq/pg_config.pkl') #psql_lib = os.path.isfile(RATROOT + '/lib/libpqrat_{0}.a'.format(os.environ['RATSYSTEM'])) env = None if pg_conf and pg_conf_ext and pg_pkl: print "PSQL library already built..." env = Environment() try: fin = open(RATROOT + '/src/libpq/pg_config.pkl', 'rb') local_defines = pickle.load(fin) fin.close() env.Append(PSQLDEFINES=local_defines) except: # if something fails rerun the configuration env = configure_psqllib() else: env = configure_psqllib() return env env = check_configuration() ### ### Build the library properly ### psqlheader = Builder(generator=copy_generator, emitter=psql_header_emitter, duplicate=0) ### Builder LibPq([list of source files]) # We don't need anything external to compile libpq arch = SConscript('ARCH.'+ROOTARCH) #SYSTEM = os.environ['RATSYSTEM'] env.Append(ENV=os.environ,CPPPATH=['#/include','#/include/libpq'],LIBPATH=['#/lib']) # Add architecture-dependent flags, GEANT4, and ROOT env.Append(**arch['default']) # Add flags from the shell environment user_controlled_vars = ['CPPFLAGS', 'CXXFLAGS', 'LDFLAGS','LIBS','CFLAGS'] envdict = {} for envvar in user_controlled_vars: if envvar in os.environ: envdict[envvar] = os.environ[envvar] env.Append(**envdict) # Add some options that I know being necessary to build postgres env.Append(CFLAGS=' -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -O2 -pthread -fPIC -I$RATROOT/include/libpq') ## If system is Linux #env.Append(CFLAGS=' ') ##CFLAGS_OSX=" -Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -O2 -pthread -pthreads -mthreads -D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS -DFRONTEND -DUNSAFE_STAT_OK -DSO_MAJOR_VERSION=5" ##CFLAGS_LINUX="-Wall -Wmissing-prototypes -Wpointer-arith -Wdeclaration-after-statement -Wendif-labels -Wmissing-format-attribute -Wformat-security -fno-strict-aliasing -fwrapv -O2 -fpic -DREFINT_VERBOSE -D_GNU_SOURCE -pthread -D_REENTRANT -D_THREAD_SAFE -D_POSIX_PTHREAD_SEMANTICS" # Add flags from the command line envdict = {} for envvar in user_controlled_vars: if envvar in ARGUMENTS: envdict[envvar] = ARGUMENTS.get(envvar) env.Append(**envdict) ### Defines # OSX env.Append(CPPDEFINES=['_REENTRANT','_THREAD_SAFE','_POSIX_PTHREAD_SEMANTICS','FRONTEND','UNSAFE_STAT_OK','SO_MAJOR_VERSION=5']) if os.environ['RATSYSTEM'] == "Linux": env.Append(CPPDEFINES=['REFINT_VERBOSE','_GNU_SOURCE']) env['BUILDDIR'] = os.path.join('#/build',os.environ['RATSYSTEM']) env.VariantDir(env['BUILDDIR'], '#/', duplicate=0) env['PSQLLIB'] = rat_path('lib','libpqrat_{0}.a'.format(os.environ['RATSYSTEM'])) # We won't use a static lib unless we cannot do otherwise #env['SOPSQLLIB'] = rat_path('lib','libpq.so') env.Append(BUILDERS={'PSQL_header' : psqlheader}) msg='''Building list of sources to compile libpqrat_''' + os.environ['RATSYSTEM'] +'''.a...''' srcdir = 'src/libpq' modbuilddir=os.path.join(env['BUILDDIR'], 'libpq') incsubdirs = ['common','libpq','mb'] env.Append(PSQLSRCDIR=srcdir) env.Append(PSQLMODBUILDIR=modbuilddir) env.Append(PSQLINCSUBDIRS=incsubdirs) env['INCLUDE_SUBDIR'] = 'include' Return('env')