2010-03-25 01:56:57 +03:00
# a set of config tests that use the samba_autoconf functions
# to test for commonly needed configuration options
2010-03-28 10:24:05 +04:00
2012-05-17 16:49:08 +04:00
import os , shutil , re
import Build , Configure , Utils
2010-03-25 15:53:10 +03:00
from Configure import conf
2010-03-28 10:24:05 +04:00
from samba_utils import *
2010-03-25 01:56:57 +03:00
2012-05-17 16:49:08 +04:00
def add_option ( self , * k , * * kw ) :
''' syntax help: provide the " match " attribute to opt.add_option() so that folders can be added to specific config tests '''
match = kw . get ( ' match ' , [ ] )
if match :
del kw [ ' match ' ]
opt = self . parser . add_option ( * k , * * kw )
opt . match = match
return opt
Options . Handler . add_option = add_option
@conf
def check ( self , * k , * * kw ) :
''' Override the waf defaults to inject --with-directory options '''
if not ' env ' in kw :
kw [ ' env ' ] = self . env . copy ( )
# match the configuration test with speficic options, for example:
# --with-libiconv -> Options.options.iconv_open -> "Checking for library iconv"
additional_dirs = [ ]
if ' msg ' in kw :
msg = kw [ ' msg ' ]
for x in Options . Handler . parser . parser . option_list :
if getattr ( x , ' match ' , None ) and msg in x . match :
d = getattr ( Options . options , x . dest , ' ' )
if d :
additional_dirs . append ( d )
# we add the additional dirs twice: once for the test data, and again if the compilation test suceeds below
def add_options_dir ( dirs , env ) :
for x in dirs :
if not x in env . CPPPATH :
env . CPPPATH = [ os . path . join ( x , ' include ' ) ] + env . CPPPATH
if not x in env . LIBPATH :
env . LIBPATH = [ os . path . join ( x , ' lib ' ) ] + env . LIBPATH
add_options_dir ( additional_dirs , kw [ ' env ' ] )
self . validate_c ( kw )
self . check_message_1 ( kw [ ' msg ' ] )
ret = None
try :
ret = self . run_c_code ( * k , * * kw )
except Configure . ConfigurationError , e :
self . check_message_2 ( kw [ ' errmsg ' ] , ' YELLOW ' )
if ' mandatory ' in kw and kw [ ' mandatory ' ] :
if Logs . verbose > 1 :
raise
else :
self . fatal ( ' the configuration failed (see %r ) ' % self . log . name )
else :
kw [ ' success ' ] = ret
self . check_message_2 ( self . ret_msg ( kw [ ' okmsg ' ] , kw ) )
# success! keep the CPPPATH/LIBPATH
add_options_dir ( additional_dirs , self . env )
self . post_check ( * k , * * kw )
if not kw . get ( ' execute ' , False ) :
return ret == 0
return ret
2010-03-25 01:56:57 +03:00
@conf
def CHECK_ICONV ( conf , define = ' HAVE_NATIVE_ICONV ' ) :
''' check if the iconv library is installed
optionally pass a define '''
if conf . CHECK_FUNCS_IN ( ' iconv_open ' , ' iconv ' , checklibc = True , headers = ' iconv.h ' ) :
conf . DEFINE ( define , 1 )
return True
return False
@conf
def CHECK_LARGEFILE ( conf , define = ' HAVE_LARGEFILE ' ) :
''' see what we need for largefile support '''
2012-04-05 02:25:13 +04:00
getconf_cflags = conf . CHECK_COMMAND ( [ ' getconf ' , ' LFS_CFLAGS ' ] ) ;
if getconf_cflags is not False :
if ( conf . CHECK_CODE ( ' return !(sizeof(off_t) >= 8) ' ,
define = ' WORKING_GETCONF_LFS_CFLAGS ' ,
execute = True ,
cflags = getconf_cflags ,
msg = ' Checking getconf large file support flags work ' ) ) :
conf . ADD_CFLAGS ( getconf_cflags )
getconf_cflags_list = TO_LIST ( getconf_cflags )
for flag in getconf_cflags_list :
if flag [ : 2 ] == " -D " :
flag_split = flag [ 2 : ] . split ( ' = ' )
if len ( flag_split ) == 1 :
conf . DEFINE ( flag_split [ 0 ] , ' 1 ' )
else :
conf . DEFINE ( flag_split [ 0 ] , flag_split [ 1 ] )
2010-03-25 01:56:57 +03:00
if conf . CHECK_CODE ( ' return !(sizeof(off_t) >= 8) ' ,
define ,
execute = True ,
2012-04-05 02:25:13 +04:00
msg = ' Checking for large file support without additional flags ' ) :
2010-03-25 01:56:57 +03:00
return True
2012-04-05 02:25:13 +04:00
2010-03-25 01:56:57 +03:00
if conf . CHECK_CODE ( ' return !(sizeof(off_t) >= 8) ' ,
define ,
execute = True ,
cflags = ' -D_FILE_OFFSET_BITS=64 ' ,
msg = ' Checking for -D_FILE_OFFSET_BITS=64 ' ) :
conf . DEFINE ( ' _FILE_OFFSET_BITS ' , 64 )
return True
2012-06-08 00:43:43 +04:00
if conf . CHECK_CODE ( ' return !(sizeof(off_t) >= 8) ' ,
define ,
execute = True ,
cflags = ' -D_LARGE_FILES ' ,
msg = ' Checking for -D_LARGE_FILES ' ) :
conf . DEFINE ( ' _LARGE_FILES ' , 1 )
return True
2010-03-25 01:56:57 +03:00
return False
@conf
2010-06-18 00:41:57 +04:00
def CHECK_C_PROTOTYPE ( conf , function , prototype , define , headers = None , msg = None ) :
2010-03-25 01:56:57 +03:00
''' verify that a C prototype matches the one on the current system '''
if not conf . CHECK_DECLS ( function , headers = headers ) :
return False
2010-06-18 00:41:57 +04:00
if not msg :
msg = ' Checking C prototype for %s ' % function
2010-03-25 01:56:57 +03:00
return conf . CHECK_CODE ( ' %s ; void *_x = (void *) %s ' % ( prototype , function ) ,
define = define ,
local_include = False ,
headers = headers ,
2010-03-30 06:19:46 +04:00
link = False ,
execute = False ,
2010-06-18 00:41:57 +04:00
msg = msg )
2010-03-25 01:56:57 +03:00
@conf
2010-03-26 09:55:25 +03:00
def CHECK_CHARSET_EXISTS ( conf , charset , outcharset = ' UCS-2LE ' , headers = None , define = None ) :
2010-03-25 01:56:57 +03:00
''' check that a named charset is able to be used with iconv_open() for conversion
to a target charset
'''
msg = ' Checking if can we convert from %s to %s ' % ( charset , outcharset )
if define is None :
define = ' HAVE_CHARSET_ %s ' % charset . upper ( ) . replace ( ' - ' , ' _ ' )
return conf . CHECK_CODE ( '''
iconv_t cd = iconv_open ( " %s " , " %s " ) ;
2010-03-26 09:55:25 +03:00
if ( cd == 0 | | cd == ( iconv_t ) - 1 ) return - 1 ;
''' % (charset, outcharset),
2010-03-25 01:56:57 +03:00
define = define ,
execute = True ,
msg = msg ,
2010-03-26 09:55:25 +03:00
lib = ' iconv ' ,
2010-03-25 01:56:57 +03:00
headers = headers )
2010-03-26 05:12:50 +03:00
2010-03-28 14:00:51 +04:00
def find_config_dir ( conf ) :
''' find a directory to run tests in '''
2010-03-26 05:12:50 +03:00
k = 0
while k < 10000 :
dir = os . path . join ( conf . blddir , ' .conf_check_ %d ' % k )
try :
shutil . rmtree ( dir )
except OSError :
pass
try :
os . stat ( dir )
except :
break
k + = 1
try :
os . makedirs ( dir )
except :
conf . fatal ( ' cannot create a configuration test folder %r ' % dir )
try :
os . stat ( dir )
except :
conf . fatal ( ' cannot use the configuration test folder %r ' % dir )
2010-03-28 14:00:51 +04:00
return dir
2010-10-31 18:50:15 +03:00
@conf
def CHECK_SHLIB_INTRASINC_NAME_FLAGS ( conf , msg ) :
'''
check if the waf default flags for setting the name of lib
are ok
'''
snip = '''
int foo ( int v ) {
return v * 2 ;
}
'''
return conf . check ( features = ' cc cshlib ' , vnum = " 1 " , fragment = snip , msg = msg )
2010-12-10 23:16:28 +03:00
@conf
def CHECK_NEED_LC ( conf , msg ) :
''' check if we need -lc '''
dir = find_config_dir ( conf )
env = conf . env
bdir = os . path . join ( dir , ' testbuild2 ' )
if not os . path . exists ( bdir ) :
os . makedirs ( bdir )
subdir = os . path . join ( dir , " liblctest " )
os . makedirs ( subdir )
dest = open ( os . path . join ( subdir , ' liblc1.c ' ) , ' w ' )
dest . write ( ' #include <stdio.h> \n int lib_func(void) { FILE *f = fopen( " foo " , " r " );} \n ' )
dest . close ( )
bld = Build . BuildContext ( )
bld . log = conf . log
bld . all_envs . update ( conf . all_envs )
bld . all_envs [ ' default ' ] = env
bld . lst_variants = bld . all_envs . keys ( )
bld . load_dirs ( dir , bdir )
bld . rescan ( bld . srcnode )
bld ( features = ' cc cshlib ' ,
source = ' liblctest/liblc1.c ' ,
ldflags = conf . env [ ' EXTRA_LDFLAGS ' ] ,
target = ' liblc ' ,
name = ' liblc ' )
try :
bld . compile ( )
conf . check_message ( msg , ' ' , True )
return True
except :
conf . check_message ( msg , ' ' , False )
return False
2010-10-30 16:50:33 +04:00
@conf
def CHECK_SHLIB_W_PYTHON ( conf , msg ) :
''' check if we need -undefined dynamic_lookup '''
dir = find_config_dir ( conf )
env = conf . env
snip = '''
#include <Python.h>
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
static PyObject * ldb_module = NULL ;
int foo ( int v ) {
extern char * * environ ;
environ [ 0 ] = 1 ;
ldb_module = PyImport_ImportModule ( " ldb " ) ;
return v * 2 ;
} '''
return conf . check ( features = ' cc cshlib ' , uselib = ' PYEMBED ' , fragment = snip , msg = msg )
2010-03-28 14:00:51 +04:00
# this one is quite complex, and should probably be broken up
# into several parts. I'd quite like to create a set of CHECK_COMPOUND()
# functions that make writing complex compound tests like this much easier
@conf
2010-12-08 03:26:32 +03:00
def CHECK_LIBRARY_SUPPORT ( conf , rpath = False , version_script = False , msg = None ) :
2010-03-28 14:00:51 +04:00
''' see if the platform supports building libraries '''
if msg is None :
if rpath :
msg = " rpath library support "
else :
msg = " building library support "
dir = find_config_dir ( conf )
2010-03-26 05:12:50 +03:00
bdir = os . path . join ( dir , ' testbuild ' )
if not os . path . exists ( bdir ) :
os . makedirs ( bdir )
env = conf . env
subdir = os . path . join ( dir , " libdir " )
os . makedirs ( subdir )
dest = open ( os . path . join ( subdir , ' lib1.c ' ) , ' w ' )
dest . write ( ' int lib_func(void) { return 42; } \n ' )
dest . close ( )
dest = open ( os . path . join ( dir , ' main.c ' ) , ' w ' )
dest . write ( ' int main(void) { return !(lib_func() == 42);} \n ' )
dest . close ( )
bld = Build . BuildContext ( )
bld . log = conf . log
bld . all_envs . update ( conf . all_envs )
bld . all_envs [ ' default ' ] = env
bld . lst_variants = bld . all_envs . keys ( )
bld . load_dirs ( dir , bdir )
bld . rescan ( bld . srcnode )
2010-12-08 03:26:32 +03:00
ldflags = [ ]
if version_script :
ldflags . append ( " -Wl,--version-script= %s /vscript " % bld . path . abspath ( ) )
dest = open ( os . path . join ( dir , ' vscript ' ) , ' w ' )
dest . write ( ' TEST_1.0A2 { global: *; }; \n ' )
dest . close ( )
2010-03-26 05:12:50 +03:00
bld ( features = ' cc cshlib ' ,
source = ' libdir/lib1.c ' ,
target = ' libdir/lib1 ' ,
2010-12-08 03:26:32 +03:00
ldflags = ldflags ,
2010-03-26 05:12:50 +03:00
name = ' lib1 ' )
o = bld ( features = ' cc cprogram ' ,
source = ' main.c ' ,
target = ' prog1 ' ,
2010-03-28 10:24:05 +04:00
uselib_local = ' lib1 ' )
if rpath :
o . rpath = os . path . join ( bdir , ' default/libdir ' )
2010-03-26 05:12:50 +03:00
# compile the program
try :
bld . compile ( )
2010-03-26 05:20:05 +03:00
except :
2010-03-28 10:24:05 +04:00
conf . check_message ( msg , ' ' , False )
2010-03-26 05:20:05 +03:00
return False
2010-03-26 05:12:50 +03:00
# path for execution
lastprog = o . link_task . outputs [ 0 ] . abspath ( env )
2010-03-28 10:24:05 +04:00
if not rpath :
if ' LD_LIBRARY_PATH ' in os . environ :
old_ld_library_path = os . environ [ ' LD_LIBRARY_PATH ' ]
else :
old_ld_library_path = None
ADD_LD_LIBRARY_PATH ( os . path . join ( bdir , ' default/libdir ' ) )
2010-03-26 05:12:50 +03:00
# we need to run the program, try to get its result
2010-04-19 09:58:37 +04:00
args = conf . SAMBA_CROSS_ARGS ( msg = msg )
2010-03-26 05:12:50 +03:00
proc = Utils . pproc . Popen ( [ lastprog ] + args , stdout = Utils . pproc . PIPE , stderr = Utils . pproc . PIPE )
( out , err ) = proc . communicate ( )
w = conf . log . write
w ( str ( out ) )
w ( ' \n ' )
w ( str ( err ) )
w ( ' \n returncode %r \n ' % proc . returncode )
ret = ( proc . returncode == 0 )
2010-03-28 10:24:05 +04:00
if not rpath :
os . environ [ ' LD_LIBRARY_PATH ' ] = old_ld_library_path or ' '
conf . check_message ( msg , ' ' , ret )
2010-03-26 05:12:50 +03:00
return ret
2010-03-28 14:00:51 +04:00
@conf
def CHECK_PERL_MANPAGE ( conf , msg = None , section = None ) :
''' work out what extension perl uses for manpages '''
if msg is None :
if section :
msg = " perl man %s extension " % section
else :
msg = " perl manpage generation "
conf . check_message_1 ( msg )
dir = find_config_dir ( conf )
bdir = os . path . join ( dir , ' testbuild ' )
if not os . path . exists ( bdir ) :
os . makedirs ( bdir )
dest = open ( os . path . join ( bdir , ' Makefile.PL ' ) , ' w ' )
dest . write ( """
use ExtUtils : : MakeMaker ;
WriteMakefile (
2012-02-09 16:08:31 +04:00
' NAME ' = > ' WafTest ' ,
2010-03-28 14:00:51 +04:00
' EXE_FILES ' = > [ ' WafTest ' ]
) ;
""" )
dest . close ( )
back = os . path . abspath ( ' . ' )
os . chdir ( bdir )
proc = Utils . pproc . Popen ( [ ' perl ' , ' Makefile.PL ' ] ,
stdout = Utils . pproc . PIPE ,
stderr = Utils . pproc . PIPE )
( out , err ) = proc . communicate ( )
os . chdir ( back )
ret = ( proc . returncode == 0 )
if not ret :
conf . check_message_2 ( ' not found ' , color = ' YELLOW ' )
return
if section :
f = open ( os . path . join ( bdir , ' Makefile ' ) , ' r ' )
man = f . read ( )
f . close ( )
m = re . search ( ' MAN %s EXT \ s+= \ s+( \ w+) ' % section , man )
if not m :
conf . check_message_2 ( ' not found ' , color = ' YELLOW ' )
return
ext = m . group ( 1 )
conf . check_message_2 ( ext )
return ext
conf . check_message_2 ( ' ok ' )
return True
2010-04-20 17:17:32 +04:00
@conf
2010-06-24 10:02:43 +04:00
def CHECK_COMMAND ( conf , cmd , msg = None , define = None , on_target = True , boolean = False ) :
2010-04-21 09:15:55 +04:00
''' run a command and return result '''
2010-04-20 17:17:32 +04:00
if msg is None :
2010-04-21 09:15:55 +04:00
msg = ' Checking %s ' % ' ' . join ( cmd )
2010-04-20 17:17:32 +04:00
conf . COMPOUND_START ( msg )
2010-04-21 09:15:55 +04:00
cmd = cmd [ : ]
if on_target :
cmd . extend ( conf . SAMBA_CROSS_ARGS ( msg = msg ) )
try :
ret = Utils . cmd_output ( cmd )
except :
conf . COMPOUND_END ( False )
return False
2010-06-24 10:02:43 +04:00
if boolean :
conf . COMPOUND_END ( ' ok ' )
if define :
conf . DEFINE ( define , ' 1 ' )
else :
ret = ret . strip ( )
conf . COMPOUND_END ( ret )
if define :
conf . DEFINE ( define , ret , quote = True )
2010-04-20 17:17:32 +04:00
return ret
2010-04-21 09:15:55 +04:00
@conf
def CHECK_UNAME ( conf ) :
''' setup SYSTEM_UNAME_* defines '''
ret = True
for v in " sysname machine release version " . split ( ) :
if not conf . CHECK_CODE ( '''
struct utsname n ;
2010-05-02 18:12:14 +04:00
if ( uname ( & n ) == - 1 ) return - 1 ;
2010-04-21 09:15:55 +04:00
printf ( " %% s " , n . % s ) ;
''' % v,
define = ' SYSTEM_UNAME_ %s ' % v . upper ( ) ,
execute = True ,
define_ret = True ,
quote = True ,
headers = ' sys/utsname.h ' ,
local_include = False ,
msg = " Checking uname %s type " % v ) :
ret = False
return ret
2010-05-05 17:16:26 +04:00
@conf
def CHECK_INLINE ( conf ) :
''' check for the right value for inline '''
conf . COMPOUND_START ( ' Checking for inline ' )
for i in [ ' inline ' , ' __inline__ ' , ' __inline ' ] :
ret = conf . CHECK_CODE ( '''
typedef int foo_t ;
static % s foo_t static_foo ( ) { return 0 ; }
% s foo_t foo ( ) { return 0 ; } ''' % (i, i),
define = ' INLINE_MACRO ' ,
addmain = False ,
link = False )
if ret :
if i != ' inline ' :
conf . DEFINE ( ' inline ' , i , quote = False )
break
if not ret :
conf . COMPOUND_END ( ret )
else :
conf . COMPOUND_END ( i )
return ret
2010-06-24 10:02:43 +04:00
@conf
def CHECK_XSLTPROC_MANPAGES ( conf ) :
''' check if xsltproc can run with the given stylesheets '''
2010-05-05 17:16:26 +04:00
2010-06-24 10:02:43 +04:00
if not conf . CONFIG_SET ( ' XSLTPROC ' ) :
conf . find_program ( ' xsltproc ' , var = ' XSLTPROC ' )
if not conf . CONFIG_SET ( ' XSLTPROC ' ) :
return False
2010-08-22 07:02:00 +04:00
s = ' http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl '
conf . CHECK_COMMAND ( ' %s --nonet %s 2> /dev/null ' % ( conf . env . XSLTPROC , s ) ,
msg = ' Checking for stylesheet %s ' % s ,
define = ' XSLTPROC_MANPAGES ' , on_target = False ,
boolean = True )
2013-05-06 02:05:37 +04:00
if not conf . CONFIG_SET ( ' XSLTPROC_MANPAGES ' ) :
print " A local copy of the docbook.xsl wasn ' t found on your system " \
" consider installing package like docbook-xsl "