build: enable real cacheing with waf configure -C
[nivanova/samba-autobuild/.git] / buildtools / wafsamba / samba_autoconf.py
index 6ad188b760928891eab40e74dc2fa503782e5df2..fc8027c5f237727c00075a6871c447c8b24be79c 100644 (file)
@@ -18,13 +18,20 @@ def DEFINE(conf, d, v, add_to_cflags=False):
     if add_to_cflags:
         conf.env.append_value('CCDEFINES', d + '=' + str(v))
 
-@runonce
+
 def CHECK_HEADER(conf, h, add_headers=True):
     '''check for a header'''
-    if conf.check(header_name=h) and add_headers:
-        conf.env.hlist.append(h)
+    d = 'HAVE_%s' % string.replace(h.upper(), '/', '_')
+    if CONFIG_SET(conf, d):
+        if add_headers:
+            conf.env.hlist.append(h)
+            conf.env.hlist = unique_list(conf.env.hlist)
         return True
-    return False
+    ret = conf.check(header_name=h)
+    if ret and add_headers:
+        conf.env.hlist.append(h)
+        conf.env.hlist = unique_list(conf.env.hlist)
+    return ret
 
 
 @conf
@@ -122,20 +129,29 @@ def CHECK_DECLS(conf, vars, reverse=False, headers=None):
     return ret
 
 
-@runonce
-def CHECK_FUNC(conf, f, checklink=False):
+def CHECK_FUNC(conf, f, checklink=False, header=''):
     '''check for a function'''
+    hlist = conf.env.hlist[:]
+    for h in TO_LIST(header):
+        if CHECK_HEADER(conf, h, add_headers=False):
+            hlist.append(h)
+    define='HAVE_%s' % f.upper()
+    if CONFIG_SET(conf, define):
+        return True
     if checklink:
-        return CHECK_CODE(conf, '%s()' % f, execute=False, define='HAVE_%s' % f.upper())
-    return conf.check(function_name=f, header_name=conf.env.hlist)
+        return CHECK_CODE(conf, 'void *x = (void *)%s' % f,
+                          execute=False, define=define,
+                          msg='Checking for %s' % f)
+
+    return conf.check_cc(function_name=f, header_name=hlist)
 
 
 @conf
-def CHECK_FUNCS(conf, list, checklink=False):
+def CHECK_FUNCS(conf, list, checklink=False, header=''):
     '''check for a list of functions'''
     ret = True
     for f in TO_LIST(list):
-        if not CHECK_FUNC(conf, f, checklink):
+        if not CHECK_FUNC(conf, f, checklink=checklink, header=header):
             ret = False
     return ret
 
@@ -284,36 +300,55 @@ Build.BuildContext.CONFIG_SET = CONFIG_SET
 #
 # optionally check for the functions first in libc
 @conf
-def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False):
-    # first see if the functions are in libc
+def CHECK_FUNCS_IN(conf, list, library, mandatory=False, checklibc=False, header=''):
+    remaining = TO_LIST(list)
+    liblist   = TO_LIST(library)
+
+    hlist = conf.env.hlist[:]
+    for h in TO_LIST(header):
+        if CHECK_HEADER(conf, h, add_headers=False):
+            hlist.append(h)
+
+    # check if some already found
+    for f in remaining[:]:
+        if CONFIG_SET(conf, 'HAVE_%s' % f.upper()):
+            remaining.remove(f)
+
+    # see if the functions are in libc
     if checklibc:
-        remaining = []
-        for f in TO_LIST(list):
-            if not CHECK_FUNC(conf, f):
-                remaining.append(f)
-    else:
-        remaining = TO_LIST(list)
+        for f in remaining[:]:
+            if CHECK_FUNC(conf, f, checklink=True, header=header):
+                remaining.remove(f)
 
     if remaining == []:
-        if GET_TARGET_TYPE(conf, library) != 'SYSLIB':
-            SET_TARGET_TYPE(conf, library, 'EMPTY')
+        for lib in liblist:
+            if GET_TARGET_TYPE(conf, lib) != 'SYSLIB':
+                SET_TARGET_TYPE(conf, lib, 'EMPTY')
         return True
 
-    for lib in TO_LIST(library):
+    ret = True
+    for lib in liblist[:]:
+        if GET_TARGET_TYPE(conf, lib):
+            continue
         if not conf.check(lib=lib, uselib_store=lib):
             conf.ASSERT(not mandatory,
-                        "Mandatory library '%s' not found for functions '%s'" % (library, list))
+                        "Mandatory library '%s' not found for functions '%s'" % (lib, list))
             # if it isn't a mandatory library, then remove it from dependency lists
-            SET_TARGET_TYPE(conf, library, 'EMPTY')
-            return False
-        conf.define('HAVE_LIB%s' % string.replace(lib.upper(),'-','_'), 1)
-        conf.env['LIB_' + lib.upper()] = lib
-        LOCAL_CACHE_SET(conf, 'TARGET_TYPE', lib, 'SYSLIB')
+            SET_TARGET_TYPE(conf, lib, 'EMPTY')
+            ret = False
+        else:
+            conf.define('HAVE_LIB%s' % string.replace(lib.upper(),'-','_'), 1)
+            conf.env['LIB_' + lib.upper()] = lib
+            LOCAL_CACHE_SET(conf, 'TARGET_TYPE', lib, 'SYSLIB')
+
+    if not ret:
+        return ret
 
     ret = True
     for f in remaining:
-        if not conf.check(function_name=f, lib=library, header_name=conf.env.hlist):
+        if not conf.check_cc(function_name=f, lib=liblist, header_name=hlist):
             ret = False
+
     return ret
 
 
@@ -325,6 +360,11 @@ def SAMBA_CONFIG_H(conf, path=None):
     # when we are building projects that depend on lib/replace
     if os.path.realpath(conf.curdir) != os.path.realpath(Options.launch_dir):
         return
+
+    if Options.options.developer:
+        # we add these here to ensure that -Wstrict-prototypes is not set during configure
+        conf.ADD_CFLAGS('-Wall -g -Wfatal-errors -Wshadow -Wstrict-prototypes -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Werror-implicit-function-declaration -Wformat=2 -Wno-format-y2k')
+
     if path is None:
         conf.write_config_header('config.h', top=True)
     else:
@@ -369,3 +409,33 @@ def CURRENT_CFLAGS(bld, target, cflags):
     ret = TO_LIST(cflags)
     ret.extend(list)
     return ret
+
+@conf
+def CHECK_RPATH_SUPPORT(conf):
+    '''see if the system supports rpath'''
+    return conf.CHECK_CODE('int x',
+                           define='HAVE_RPATH_SUPPORT',
+                           execute=True,
+                           msg='Checking for rpath support',
+                           cflags='-Wl,-rpath=.')
+
+@conf
+def CHECK_CC_ENV(conf):
+    '''trim whitespaces from 'CC'.
+    The build farm sometimes puts a space at the start'''
+    if os.environ.get('CC'):
+        conf.env.CC = TO_LIST(os.environ.get('CC'))
+        if len(conf.env.CC) == 1:
+            # make for nicer logs if just a single command
+            conf.env.CC = conf.env.CC[0]
+
+@conf
+def ENABLE_CONFIGURE_CACHE(conf):
+    '''enable cache of configure results'''
+    if os.environ.get('WAFCACHE'):
+        # already setup
+        return
+    cache_path = os.path.join(conf.blddir, '.confcache')
+    mkdir_p(cache_path)
+    Options.cache_global = os.environ['WAFCACHE'] = cache_path
+