replace: Fix "make test" to actually test libreplace
[samba.git] / lib / replace / wscript
index a2e2d1184777c9e89db889a81f05dce9e31d2630..d442792433d718c4c1a0caef18b91fae828309ac 100644 (file)
@@ -3,22 +3,24 @@
 APPNAME = 'libreplace'
 VERSION = '1.2.1'
 
-blddir = 'bin'
-
-import Logs, sys, os
+import sys
+import os
 
 # find the buildtools directory
-srcdir = '.'
-while not os.path.exists(srcdir+'/buildtools') and len(srcdir.split('/')) < 5:
-    srcdir = srcdir + '/..'
-sys.path.insert(0, srcdir + '/buildtools/wafsamba')
+top = '.'
+while not os.path.exists(top+'/buildtools') and len(top.split('/')) < 5:
+    top = top + '/..'
+sys.path.insert(0, top + '/buildtools/wafsamba')
+
+out = 'bin'
 
-import wafsamba, samba_dist
-import Options, Utils
+import wafsamba
+from wafsamba import samba_dist
+from waflib import Options, Utils, Logs, Context
 
 samba_dist.DIST_DIRS('lib/replace buildtools:buildtools third_party/waf:third_party/waf')
 
-def set_options(opt):
+def options(opt):
     opt.BUILTIN_DEFAULT('NONE')
     opt.PRIVATE_EXTENSION_DEFAULT('')
     opt.RECURSE('buildtools/wafsamba')
@@ -39,7 +41,7 @@ def configure(conf):
     conf.CHECK_HEADERS('shadow.h sys/acl.h')
     conf.CHECK_HEADERS('sys/attributes.h attr/attributes.h sys/capability.h sys/dir.h sys/epoll.h')
     conf.CHECK_HEADERS('port.h')
-    conf.CHECK_HEADERS('sys/fcntl.h sys/filio.h sys/filsys.h sys/fs/s5param.h sys/fs/vx/quota.h')
+    conf.CHECK_HEADERS('sys/fcntl.h sys/filio.h sys/filsys.h sys/fs/s5param.h')
     conf.CHECK_HEADERS('sys/id.h sys/ioctl.h sys/ipc.h sys/mman.h sys/mode.h sys/ndir.h sys/priv.h')
     conf.CHECK_HEADERS('sys/resource.h sys/security.h sys/shm.h sys/statfs.h sys/statvfs.h sys/termio.h')
     conf.CHECK_HEADERS('sys/vfs.h sys/xattr.h termio.h termios.h sys/file.h')
@@ -68,7 +70,15 @@ def configure(conf):
     conf.CHECK_HEADERS('aio.h sys/unistd.h alloca.h float.h')
 
     conf.SET_TARGET_TYPE('tirpc', 'EMPTY')
-    conf.CHECK_HEADERS('rpc/rpc.h rpc/nettype.h')
+
+    if conf.CHECK_CODE(
+            '\n#ifndef _TIRPC_RPC_H\n#error "no tirpc headers in system path"\n#endif\n',
+            'HAVE_RPC_RPC_HEADERS',
+            headers=['rpc/rpc.h', 'rpc/nettype.h'],
+            msg='Checking for tirpc rpc headers in default system path'):
+        if conf.CONFIG_SET('HAVE_RPC_RPC_H'):
+            conf.undefine('HAVE_RPC_RPC_H')
+
     if not conf.CONFIG_SET('HAVE_RPC_RPC_H'):
         if conf.CHECK_CFG(package='libtirpc', args='--cflags --libs',
                        msg='Checking for libtirpc headers',
@@ -100,12 +110,13 @@ def configure(conf):
     conf.CHECK_HEADERS('sys/fileio.h sys/filesys.h sys/dustat.h sys/sysmacros.h')
     conf.CHECK_HEADERS('xfs/libxfs.h netgroup.h')
 
-    conf.CHECK_HEADERS('valgrind.h valgrind/valgrind.h valgrind/memcheck.h')
+    conf.CHECK_HEADERS('valgrind.h valgrind/valgrind.h')
+    conf.CHECK_HEADERS('valgrind/memcheck.h valgrind/helgrind.h')
     conf.CHECK_HEADERS('nss_common.h nsswitch.h ns_api.h')
     conf.CHECK_HEADERS('sys/extattr.h sys/ea.h sys/proplist.h sys/cdefs.h')
     conf.CHECK_HEADERS('utmp.h utmpx.h lastlog.h')
     conf.CHECK_HEADERS('syscall.h sys/syscall.h inttypes.h')
-    conf.CHECK_HEADERS('sys/atomic.h')
+    conf.CHECK_HEADERS('sys/atomic.h stdatomic.h')
     conf.CHECK_HEADERS('libgen.h')
 
     if conf.CHECK_CFLAGS('-Wno-format-truncation'):
@@ -114,6 +125,9 @@ def configure(conf):
     if conf.CHECK_CFLAGS('-Wno-unused-function'):
         conf.define('HAVE_WNO_UNUSED_FUNCTION', '1')
 
+    if conf.CHECK_CFLAGS('-Wno-strict-overflow'):
+        conf.define('HAVE_WNO_STRICT_OVERFLOW', '1')
+
     # Check for process set name support
     conf.CHECK_CODE('''
                     #include <sys/prctl.h>
@@ -181,6 +195,23 @@ def configure(conf):
                         'socket nsl', checklibc=True,
                         headers='sys/socket.h netinet/in.h arpa/inet.h netdb.h')
 
+    conf.CHECK_FUNCS('memset_s memset_explicit')
+
+    conf.CHECK_CODE('''
+                    #include <string.h>
+
+                    int main(void)
+                    {
+                        char buf[] = "This is some content";
+                        memset(buf, '\0', sizeof(buf)); __asm__ volatile("" : : "g"(&buf) : "memory");
+                        return 0;
+                    }
+                    ''',
+                    define='HAVE_GCC_VOLATILE_MEMORY_PROTECTION',
+                    addmain=False,
+                    msg='Checking for volatile memory protection',
+                    local_include=False)
+
     # Some old Linux systems have broken header files and
     # miss the IPV6_V6ONLY define in netinet/in.h,
     # but have it in linux/in6.h.
@@ -249,6 +280,60 @@ def configure(conf):
                     headers='stdint.h sys/atomic.h',
                     msg='Checking for atomic_add_32 compiler builtin')
 
+    # Check for thread fence. */
+    tf = conf.CHECK_CODE('atomic_thread_fence(memory_order_seq_cst);',
+                         'HAVE_ATOMIC_THREAD_FENCE',
+                         headers='stdatomic.h',
+                         msg='Checking for atomic_thread_fence(memory_order_seq_cst) in stdatomic.h')
+    if not tf:
+        tf = conf.CHECK_CODE('__atomic_thread_fence(__ATOMIC_SEQ_CST);',
+                             'HAVE___ATOMIC_THREAD_FENCE',
+                             msg='Checking for __atomic_thread_fence(__ATOMIC_SEQ_CST)')
+    if not tf:
+        # __sync_synchronize() is available since 2005 in gcc.
+        tf = conf.CHECK_CODE('__sync_synchronize();',
+                             'HAVE___SYNC_SYNCHRONIZE',
+                             msg='Checking for __sync_synchronize')
+    if tf:
+        conf.DEFINE('HAVE_ATOMIC_THREAD_FENCE_SUPPORT', 1)
+
+    conf.CHECK_CODE('''
+                    #define FALL_THROUGH __attribute__((fallthrough))
+
+                    enum direction_e {
+                        UP = 0,
+                        DOWN,
+                    };
+
+                    int main(void) {
+                        enum direction_e key = UP;
+                        int i = 10;
+                        int j = 0;
+
+                        switch (key) {
+                        case UP:
+                            i = 5;
+                            FALL_THROUGH;
+                        case DOWN:
+                            j = i * 2;
+                            break;
+                        default:
+                            break;
+                        }
+
+                        if (j < i) {
+                            return 1;
+                        }
+
+                        return 0;
+                    }
+                    ''',
+                    'HAVE_FALLTHROUGH_ATTRIBUTE',
+                    addmain=False,
+                    strict=True,
+                    cflags=['-Werror=missing-declarations'],
+                    msg='Checking for fallthrough attribute')
+
     # these may be builtins, so we need the link=False strategy
     conf.CHECK_FUNCS('strdup memmem printf memset memcpy memmove strcpy strncpy bzero', link=False)
 
@@ -341,40 +426,30 @@ def configure(conf):
     conf.CHECK_FUNCS('getgrent_r getgrgid_r getgrnam_r getgrouplist getpagesize')
     conf.CHECK_FUNCS('getpwent_r getpwnam_r getpwuid_r epoll_create')
     conf.CHECK_FUNCS('port_create')
+    conf.CHECK_FUNCS('getprogname')
 
     conf.SET_TARGET_TYPE('attr', 'EMPTY')
 
     xattr_headers='sys/attributes.h attr/xattr.h sys/xattr.h'
 
-    conf.CHECK_FUNCS_IN('''
-fgetxattr flistea flistxattr
-fremovexattr fsetxattr getxattr
-listxattr removexattr setxattr
-''', 'attr', checklibc=True, headers=xattr_headers)
-
-    # We need to check for linux xattrs first, as we do not wish to link to -lattr
-    # (the XFS compat API) on Linux systems with the native xattr API
-    if not conf.CONFIG_SET('HAVE_GETXATTR'):
-        conf.CHECK_FUNCS_IN('''
-attr_get attr_getf attr_list attr_listf attropen attr_remove
-attr_removef attr_set attr_setf extattr_delete_fd extattr_delete_file
-extattr_get_fd extattr_get_file extattr_list_fd extattr_list_file
-extattr_set_fd extattr_set_file fgetea
-fremoveea fsetea getea listea
-removeea setea
-''', 'attr', checklibc=True, headers=xattr_headers)
-
-    if (conf.CONFIG_SET('HAVE_ATTR_LISTF') or
-        conf.CONFIG_SET('HAVE_EXTATTR_LIST_FD') or
-        conf.CONFIG_SET('HAVE_FLISTEA') or
-        conf.CONFIG_SET('HAVE_FLISTXATTR')):
-            conf.DEFINE('HAVE_XATTR_SUPPORT', 1)
-
-    # Darwin has extra options to xattr-family functions
-    conf.CHECK_CODE('getxattr(NULL, NULL, NULL, 0, 0, 0)',
-                    headers=xattr_headers, local_include=False,
-                    define='XATTR_ADDITIONAL_OPTIONS',
-                    msg="Checking whether xattr interface takes additional options")
+    # default to 1, we set it to 0 if we don't find any EA implementation below:
+    conf.DEFINE('HAVE_XATTR_SUPPORT', 1)
+    if conf.CHECK_FUNCS_IN('getxattr', 'attr', checklibc=True, headers=xattr_headers):
+        conf.DEFINE('HAVE_XATTR_XATTR', 1)
+        # Darwin has extra options to xattr-family functions
+        conf.CHECK_CODE('getxattr(NULL, NULL, NULL, 0, 0, 0)',
+                        headers=xattr_headers, local_include=False,
+                        define='XATTR_ADDITIONAL_OPTIONS',
+                        msg="Checking whether xattr interface takes additional options")
+    elif conf.CHECK_FUNCS_IN('attr_listf', 'attr', checklibc=True, headers=xattr_headers):
+        conf.DEFINE('HAVE_XATTR_ATTR', 1)
+    elif conf.CHECK_FUNCS('extattr_list_fd'):
+        conf.DEFINE('HAVE_XATTR_EXTATTR', 1)
+    elif conf.CHECK_FUNCS('flistea'):
+        conf.DEFINE('HAVE_XATTR_EA', 1)
+    elif not conf.CHECK_FUNCS('attropen'):
+            conf.DEFINE('HAVE_XATTR_SUPPORT', 0)
+
 
     conf.CHECK_FUNCS_IN('dlopen dlsym dlerror dlclose', 'dl',
                         checklibc=True, headers='dlfcn.h dl.h')
@@ -515,17 +590,31 @@ removeea setea
              conf.CONFIG_SET('HAVE_PTHREAD_MUTEX_CONSISTENT_NP'))):
             conf.DEFINE('HAVE_ROBUST_MUTEXES', 1)
 
+    # __thread is available since 2002 in gcc.
+    conf.CHECK_CODE('''
+        __thread int tls;
+
+        int main(void) {
+            return 0;
+        }
+        ''',
+        'HAVE___THREAD',
+        addmain=False,
+        msg='Checking for __thread local storage')
+
     conf.CHECK_FUNCS_IN('crypt', 'crypt', checklibc=True)
     conf.CHECK_FUNCS_IN('crypt_r', 'crypt', checklibc=True)
 
     conf.CHECK_VARIABLE('rl_event_hook', define='HAVE_DECL_RL_EVENT_HOOK', always=True,
                         headers='readline.h readline/readline.h readline/history.h')
+    conf.CHECK_VARIABLE('program_invocation_short_name', headers='errno.h')
 
     conf.CHECK_DECLS('snprintf vsnprintf asprintf vasprintf')
 
     conf.CHECK_DECLS('errno', headers='errno.h', reverse=True)
     conf.CHECK_DECLS('EWOULDBLOCK', headers='errno.h')
-    conf.CHECK_DECLS('environ getgrent_r getpwent_r', reverse=True, headers='pwd.h grp.h')
+    conf.CHECK_DECLS('environ', reverse=True, headers='unistd.h')
+    conf.CHECK_DECLS('getgrent_r getpwent_r', reverse=True, headers='pwd.h grp.h')
     conf.CHECK_DECLS('pread pwrite setenv setresgid setresuid', reverse=True)
 
     if conf.CONFIG_SET('HAVE_EPOLL_CREATE') and conf.CONFIG_SET('HAVE_SYS_EPOLL_H'):
@@ -543,7 +632,7 @@ removeea setea
     conf.CHECK_FUNCS('strptime')
     conf.CHECK_DECLS('strptime', headers='time.h')
     conf.CHECK_CODE('''#define LIBREPLACE_CONFIGURE_TEST_STRPTIME
-                       #include "test/strptime.c"''',
+                       #include "tests/strptime.c"''',
                        define='HAVE_WORKING_STRPTIME',
                        execute=True,
                        addmain=False,
@@ -558,25 +647,25 @@ removeea setea
                            define='HAVE_GETTIMEOFDAY_TZ_VOID',
                            headers='sys/time.h')
 
-    conf.CHECK_CODE('#include "test/snprintf.c"',
+    conf.CHECK_CODE('#include "tests/snprintf.c"',
                     define="HAVE_C99_VSNPRINTF",
                     execute=True,
                     addmain=False,
                     msg="Checking for C99 vsnprintf")
 
-    conf.CHECK_CODE('#include "test/shared_mmap.c"',
+    conf.CHECK_CODE('#include "tests/shared_mmap.c"',
                     addmain=False, add_headers=False, execute=True,
                     define='HAVE_SHARED_MMAP',
                     msg="Checking for HAVE_SHARED_MMAP")
 
-    conf.CHECK_CODE('#include "test/shared_mremap.c"',
+    conf.CHECK_CODE('#include "tests/shared_mremap.c"',
                     addmain=False, add_headers=False, execute=True,
                     define='HAVE_MREMAP',
                     msg="Checking for HAVE_MREMAP")
 
     # OpenBSD (and I've heard HPUX) doesn't sync between mmap and write.
     # FIXME: Anything other than a 0 or 1 exit code should abort configure!
-    conf.CHECK_CODE('#include "test/incoherent_mmap.c"',
+    conf.CHECK_CODE('#include "tests/incoherent_mmap.c"',
                     addmain=False, add_headers=False, execute=True,
                     define='HAVE_INCOHERENT_MMAP',
                     msg="Checking for HAVE_INCOHERENT_MMAP")
@@ -623,6 +712,10 @@ removeea setea
                                 headers='sys/socket.h netinet/in.h',
                                 define='HAVE_SOCK_SIN_LEN')
 
+    conf.CHECK_STRUCTURE_MEMBER('struct sockaddr_in6', 'sin6_len',
+                                headers='sys/socket.h netinet/in.h',
+                                define='HAVE_SOCK_SIN6_LEN')
+
     conf.CHECK_CODE('struct sockaddr_un sunaddr; sunaddr.sun_family = AF_UNIX;',
                     define='HAVE_UNIXSOCKET', headers='sys/socket.h sys/un.h')
 
@@ -670,7 +763,7 @@ removeea setea
                            #include "snprintf.c"
                            #include "getifaddrs.c"
                            #define getifaddrs_test main
-                           #include "test/getifaddrs.c"
+                           #include "tests/getifaddrs.c"
                            ''' % method,
                            method,
                            lib='nsl socket' + bsd_for_strlcpy,
@@ -698,7 +791,7 @@ REPLACEMENT_FUNCTIONS = {
                   'utime', 'utimes', 'dup2', 'chown', 'link', 'readlink',
                   'symlink', 'lchown', 'realpath', 'memmem', 'vdprintf',
                   'dprintf', 'get_current_dir_name',
-                  'strerror_r', 'clock_gettime'],
+                  'strerror_r', 'clock_gettime', 'memset_s'],
     'timegm.c': ['timegm'],
     # Note: C99_VSNPRINTF is not a function, but a special condition
     # for replacement
@@ -714,8 +807,8 @@ def build(bld):
 
     REPLACE_HOSTCC_SOURCE = ''
 
-    for filename, functions in REPLACEMENT_FUNCTIONS.iteritems():
-        for function in functions:
+    for filename in REPLACEMENT_FUNCTIONS.keys():
+        for function in REPLACEMENT_FUNCTIONS[filename]:
             if not bld.CONFIG_SET('HAVE_%s' % function.upper()):
                 REPLACE_HOSTCC_SOURCE += ' %s' % filename
                 break
@@ -764,20 +857,19 @@ def build(bld):
                       private_library=True,
                       deps='crypt dl nsl socket rt attr' + extra_libs)
 
-    replace_test_cflags="-Wno-format-zero-length"
+    replace_test_cflags = ''
     if bld.CONFIG_SET('HAVE_WNO_FORMAT_TRUNCATION'):
         replace_test_cflags += " -Wno-format-truncation"
     bld.SAMBA_SUBSYSTEM('replace-test',
-                        source='''test/testsuite.c test/strptime.c
-                        test/os2_delete.c test/getifaddrs.c''',
+                        source='''tests/testsuite.c tests/strptime.c
+                        tests/os2_delete.c tests/getifaddrs.c''',
                         deps='replace',
                         cflags=replace_test_cflags)
 
-    if bld.env.standalone_replace:
-        bld.SAMBA_BINARY('replace_testsuite',
-                         source='test/main.c',
-                         deps='replace replace-test',
-                         install=False)
+    bld.SAMBA_BINARY('replace_testsuite',
+                     source='tests/main.c',
+                     deps='replace replace-test',
+                     install=False)
 
     # build replacements for stdint.h and stdbool.h if needed
     bld.SAMBA_GENERATOR('replace_stdint_h',
@@ -793,6 +885,24 @@ def build(bld):
 
     bld.SAMBA_SUBSYSTEM('samba_intl', source='', use_global_deps=False,deps=bld.env.intl_libs)
 
+def testonly(ctx):
+    '''run talloc testsuite'''
+    import samba_utils
+
+    samba_utils.ADD_LD_LIBRARY_PATH('bin/shared')
+    samba_utils.ADD_LD_LIBRARY_PATH('bin/shared/private')
+
+    cmd = os.path.join(Context.g_module.out, 'replace_testsuite')
+    ret = samba_utils.RUN_COMMAND(cmd)
+    print("testsuite returned %d" % ret)
+    sys.exit(ret)
+
+# WAF doesn't build the unit tests for this, maybe because they don't link with talloc?
+# This forces it
+def test(ctx):
+    Options.commands.append('build')
+    Options.commands.append('testonly')
+
 def dist():
     '''makes a tarball for distribution'''
     samba_dist.dist()