Example #1
0
def build_module(name, srcdir, defs=[], deps=[], srcs=[], soversion=None):
    #print("Include EPICS module %s in %s"%(name, srcdir))
    src, inc, hdr = readlists(name, srcdir)
    if len(src) == 0:
        raise RuntimeError("module %s has no source" % name)
    defs = get_config_var('CPPFLAGS') + local_defs + defs

    MOD = DSO(
        name='epicscorelibs.lib.' + name,
        sources=srcs + src,
        include_dirs=[os.path.join('epicscorelibs', 'include')] + inc + ['.'],
        define_macros=defs,
        dsos=['epicscorelibs.lib.' + D for D in deps],
        libraries=get_config_var('LDADD'),
        extra_link_args=get_config_var('LDFLAGS'),
        lang_compile_args={
            'c': get_config_var('CFLAGS'),
            'c++': get_config_var('CXXFLAGS'),
        },
        soversion=soversion or abi_version,
    )

    modules.append(MOD)
    headers.extend(hdr)
Example #2
0
def readlists(name, prefix):
    prefix = os.path.normcase(prefix)
    groups = ['all', get_config_var('OS_CLASS')]

    ret = []

    for part in ('source', 'include', 'header'):
        R = []

        for grp in groups:
            fname = os.path.join(mydir, 'setup.py.d',
                                 '.'.join([name, grp, part]))
            if os.path.isfile(fname):
                with open(fname, 'r') as F:
                    for line in F:
                        line = line.strip()
                        if line[:1] in ('', '#'):
                            continue
                        R.append(os.path.normcase(line))

        R = [os.path.join(prefix, F) for F in R]
        ret.append(R)

    return tuple(ret)
Example #3
0
    extra += ['-v']

ext = Extension(
    name='p4p._p4p',
    sources=[
        "src/p4p_top.cpp",
        "src/p4p_type.cpp",
        "src/p4p_value.cpp",
        "src/p4p_array.cpp",
        "src/p4p_server.cpp",
        "src/p4p_server_provider.cpp",
        "src/p4p_server_sharedpv.cpp",
        "src/p4p_client.cpp",
    ],
    include_dirs=get_numpy_include_dirs() + [epicscorelibs.path.include_path],
    define_macros=get_config_var('CPPFLAGS'),
    extra_compile_args=get_config_var('CXXFLAGS'),
    extra_link_args=get_config_var('LDFLAGS') + extra,
    dsos=[
        'epicscorelibs.lib.pvAccess', 'epicscorelibs.lib.pvData',
        'epicscorelibs.lib.ca', 'epicscorelibs.lib.Com'
    ],
    libraries=get_config_var('LDADD'),
)

setup(
    name='p4p',
    version='3.0.0',
    description="Python interface to PVAccess protocol client",
    url='https://mdavidsaver.github.io/p4p',
    author='Michael Davidsaver',
Example #4
0
    def run(self):
        log.info("In GetVersionError")
        self.mkpath(self.build_temp)
        defs = {}
        readmake(defs, 'configure', 'CONFIG_BASE_VERSION')
        defs['EPICS_SITE_VERSION'] = 'pipi'

        outfile = os.path.join(self.build_temp, 'epicsVersion.h')
        if self.dry_run:
            log.info("Would write %s", outfile)
        else:
            log.info("Writing %s", outfile)
            with open(outfile, 'w') as F:
                F.write("""
#ifndef INC_epicsVersion_H
#define INC_epicsVersion_H

#define EPICS_VERSION        %(EPICS_VERSION)s
#define EPICS_REVISION       %(EPICS_REVISION)s
#define EPICS_MODIFICATION   %(EPICS_MODIFICATION)s
#define EPICS_PATCH_LEVEL    %(EPICS_PATCH_LEVEL)s
#define EPICS_DEV_SNAPSHOT   "%(EPICS_DEV_SNAPSHOT)s"
#define EPICS_SITE_VERSION   "%(EPICS_SITE_VERSION)s"

#define EPICS_VERSION_SHORT "%(EPICS_VERSION)s.%(EPICS_REVISION)s.%(EPICS_MODIFICATION)s.%(EPICS_PATCH_LEVEL)s"
#define EPICS_VERSION_FULL "%(EPICS_VERSION)s.%(EPICS_REVISION)s.%(EPICS_MODIFICATION)s.%(EPICS_PATCH_LEVEL)s%(EPICS_DEV_SNAPSHOT)s"
#define EPICS_VERSION_STRING "EPICS %(EPICS_VERSION)s.%(EPICS_REVISION)s.%(EPICS_MODIFICATION)s.%(EPICS_PATCH_LEVEL)s%(EPICS_DEV_SNAPSHOT)s"
#define epicsReleaseVersion  "EPICS %(EPICS_VERSION)s.%(EPICS_REVISION)s.%(EPICS_MODIFICATION)s.%(EPICS_PATCH_LEVEL)s%(EPICS_DEV_SNAPSHOT)s"

#ifndef VERSION_INT
#  define VERSION_INT(V,R,M,P) ( ((V)<<24) | ((R)<<16) | ((M)<<8) | (P))
#endif
#define EPICS_VERSION_INT VERSION_INT(EPICS_VERSION, EPICS_REVISION, EPICS_MODIFICATION, EPICS_PATCH_LEVEL)

#endif /* INC_epicsVersion_H */
""" % defs)

        defs = {}
        defs['EPICS_BUILD_TARGET_ARCH'] = get_config_var('EPICS_HOST_ARCH')
        readmake(defs, 'configure', 'CONFIG_ENV')
        readmake(defs, 'configure', 'CONFIG_SITE_ENV')

        outfile = os.path.join(self.build_temp, 'generated.c')
        if self.dry_run:
            log.info("Would write %s", outfile)
        else:
            log.info("Writing %s", outfile)
            with open(outfile, 'w') as F:
                F.write("""
#include <stddef.h>
#include "envDefs.h"
""")

                for N, V in defs.items():
                    F.write('const ENV_PARAM %s = {"%s", "%s"};\n' %
                            (N, N, V.strip('"')))

                F.write('const ENV_PARAM* env_param_list[] = {\n')
                for N, V in defs.items():
                    F.write('    &%s,\n' % N)
                F.write('    NULL\n};\n')

                F.write("""
#include "errMdef.h"
#include "errSymTbl.h"
#include "dbDefs.h"
""")

                defM, defS = [], []
                for errfile in self.distribution.x_errtable or []:
                    with open(os.path.normcase(errfile), 'r') as I:
                        for line in I:
                            M = err_def.match(line)
                            if M is None:
                                continue
                            D = M.groupdict()
                            # TODO: escape 'desc'?
                            if D['macro'][0] == 'M':
                                defM.append(D)
                            elif D['macro'][0] == 'S':
                                defS.append(D)

                if len(defM) == 0 or len(defS) == 0:
                    log.warn("Warning: generated error string table is empty!")
                    # MSVC doesn't like zero length C arrays
                    # so give it something
                    defS.append({
                        'macro': 'S_generic',
                        'value': '1',
                        'desc': 'placeholder'
                    })

                for D in defM:
                    F.write(
                        "#ifndef %(macro)s\n#  define %(macro)s (%(value)s) /*%(desc)s*/\n#endif\n"
                        % D)

                for D in defS:
                    F.write("#define %(macro)s (%(value)s) /*%(desc)s*/\n" % D)

                F.write("""
static ERRSYMBOL symbols[] = {
""")

                for D in defS:
                    F.write("    { (long)%(macro)s, \"%(desc)s\" },\n" % D)

                F.write("""
}; /* TODO */
static ERRSYMTAB symTbl = {NELEMENTS(symbols), symbols};
ERRSYMTAB_ID errSymTbl = &symTbl;
""")

        outfile = os.path.join(self.build_temp, 'epicsVCS.h')
        if self.dry_run:
            log.info("Would write %s", outfile)
        else:
            log.info("Writing %s", outfile)
            with open(outfile, 'w') as F:
                F.write("""
#ifndef EPICS_VCS_VERSION
  #define EPICS_VCS_VERSION "%s"
#endif
""" % package_version)
Example #5
0
# I will use some of what I'm about to install
sys.path.insert(0, os.path.join(mydir, 'src', 'python'))

from epicscorelibs.config import get_config_var

# our choice of version suffix is constrained by PEP 440
# so we always append .99.ABI.SRC to most recent upstream version
# the following line is matched from cibuild.py
package_version = '7.0.6.99.2.0'

assert package_version.split('.')[-3] == '99', package_version

abi_version = '.'.join(
    package_version.split('.')[:-1])  # strip off the last component

OS_CLASS = get_config_var('OS_CLASS')

# Extract error symbol definitoins from C headers
# eg.
# | #define M_asLib                   (501 << 16)  /* Access Security */
# | #define S_asLib_asNotActive       (M_asLib|10) /*access security is not active*/
#            <macro>                  <value>        <desc>
err_def = re.compile(
    r'''
    ^\s* \# \s* define \s+ (?P<macro>[SM]_[A-Za-z0-9_]+)
        \s+ \( (?P<value>[^)]*) \)
        \s* /\* (?P<desc>.*) \*/ \s*$
''', re.X)


def readmake(defs, *parts):
Example #6
0
    # c++ debug symbols size is huge.  ~20x code size.
    # So we choose to only emit debug symbols when building for an interpreter
    # with debugging enabled (aka 'python-dbg' on debian).
    cxxflags += ['-g0']

elif platform.system()=='Darwin':
    # avoid later failure where install_name_tool may run out of space.
    #   install_name_tool: changing install names or rpaths can't be redone for:
    #   ... because larger updated load commands do not fit (the program must be relinked,
    #   and you may need to use -headerpad or -headerpad_max_install_names)
    ldflags += ['-Wl,-headerpad_max_install_names']

# Our internal interfaces with generated cython
# are all c++, and MSVC doesn't allow extern "C" to
# return c++ types.
cppflags = get_config_var('CPPFLAGS') + [('__PYX_EXTERN_C','extern')]

exts = cythonize([
    Extension(
        name='p4p._p4p',
        sources = [
            "src/p4p/_p4p.pyx",
            "src/pvxs_client.cpp",
            "src/pvxs_sharedpv.cpp",
            "src/pvxs_source.cpp",
            "src/pvxs_type.cpp",
            "src/pvxs_value.cpp",
        ],
        include_dirs = get_numpy_include_dirs()+[epicscorelibs.path.include_path, pvxslibs.path.include_path, 'src', 'src/p4p'],
        define_macros = cppflags + [('PY_ARRAY_UNIQUE_SYMBOL', 'PVXS_PyArray_API'), ('PVXS_ENABLE_EXPERT_API', None)],
        extra_compile_args = get_config_var('CXXFLAGS')+cxxflags,
Example #7
0
    "osdCpuUtilization.c",
    "osdFdUsage.c",
    "osdMemUsage.c",
    "osdWorkspaceUsage.c",
    "osdClustInfo.c",
    "osdSuspTasks.c",
    "osdIFErrors.c",
    "osdBootInfo.c",
    "osdSystemInfo.c",
    "osdHostInfo.c",
    "osdPIDInfo.c",
]

devIocStats_src = os.path.join("softioc", "iocStats", "devIocStats")
devIocStats_os = os.path.join(devIocStats_src, "os",
                              get_config_var('OS_CLASS'))
devIocStats_default = os.path.join(devIocStats_src, "os", "default")

for f in devIocStats_OSI:
    sources.append(os.path.join(devIocStats_src, f))
for f in devIocStats_OSD:
    if os.path.exists(os.path.join(devIocStats_os, f)):
        sources.append(os.path.join(devIocStats_os, f))
    else:
        sources.append(os.path.join(devIocStats_default, f))

# Extension with all our C code
ext = Extension(
    name='softioc._extension',
    sources=sources,
    include_dirs=[
Example #8
0
def define_DSOS(self):
    DEFS = self.distribution.DEFS
    OS_CLASS = get_config_var('OS_CLASS')

    src_core = [
        'buffer.c',
        'bufferevent.c',
        'bufferevent_filter.c',
        'bufferevent_pair.c',
        'bufferevent_ratelim.c',
        'bufferevent_sock.c',
        'event.c',
        'evmap.c',
        'evthread.c',
        'evutil.c',
        'evutil_rand.c',
        'evutil_time.c',
        'watch.c',
        'listener.c',
        'log.c',
        'signal.c',
        'strlcpy.c',
    ]

    if DEFS['EVENT__HAVE_POLL'] == '1':
        src_core += ['poll.c']

    if DEFS['EVENT__HAVE_KQUEUE'] == '1':
        src_core += ['kqueue.c']

    if DEFS['EVENT__HAVE_DEVPOLL'] == '1':
        src_core += ['devpoll.c']

    if DEFS['EVENT__HAVE_WEPOLL'] == '1':
        src_core += ['wepoll.c', 'epoll.c']
    elif DEFS['EVENT__HAVE_EPOLL'] == '1':
        src_core += ['epoll.c']

    if DEFS['EVENT__HAVE_EVENT_PORTS'] == '1':
        src_core += ['evport.c']

    if OS_CLASS == 'WIN32':
        src_core += [
            'buffer_iocp.c',
            'bufferevent_async.c',
            'event_iocp.c',
            'win32select.c',
            'evthread_win32.c',
        ]
    elif DEFS['EVENT__HAVE_SELECT'] == '1':
        src_core += ['select.c']

    src_core = [os.path.join('bundle', 'libevent', src) for src in src_core]

    src_pvxs = [
        'describe.cpp',
        'log.cpp',
        'unittest.cpp',
        'util.cpp',
        'osgroups.cpp',
        'sharedarray.cpp',
        'bitmask.cpp',
        'type.cpp',
        'data.cpp',
        'datafmt.cpp',
        'pvrequest.cpp',
        'dataencode.cpp',
        'nt.cpp',
        'evhelper.cpp',
        'udp_collector.cpp',
        'config.cpp',
        'conn.cpp',
        'server.cpp',
        'serverconn.cpp',
        'serverchan.cpp',
        'serverintrospect.cpp',
        'serverget.cpp',
        'servermon.cpp',
        'serversource.cpp',
        'sharedpv.cpp',
        'client.cpp',
        'clientreq.cpp',
        'clientconn.cpp',
        'clientintrospect.cpp',
        'clientget.cpp',
        'clientmon.cpp',
    ]

    src_pvxs = [os.path.join('src', src) for src in src_pvxs]

    event_libs = []
    if OS_CLASS == 'WIN32':
        event_libs = ['ws2_32', 'shell32', 'advapi32', 'bcrypt', 'iphlpapi']

    probe = ProbeToolchain()

    cxx11_flags = []
    if probe.try_compile('int probefn() { auto x=1; return x; }',
                         language='c++',
                         extra_preargs=['-std=c++11']):
        cxx11_flags += ['-std=c++11']

    pvxs_abi = '%(PVXS_MAJOR_VERSION)s.%(PVXS_MINOR_VERSION)s' % pvxsversion
    event_abi = '%(EVENT_VERSION_MAJOR)s.%(EVENT_VERSION_MINOR)s.%(EVENT_VERSION_PATCH)s' % eventversion

    DSOS = []

    dsos_pvxs = [
        'epicscorelibs.lib.Com',
        'pvxslibs.lib.event_core',
    ]

    if OS_CLASS != 'WIN32':
        DSOS += [
            DSO(
                'pvxslibs.lib.event_pthread',
                [os.path.join('bundle', 'libevent', 'evthread_pthread.c')],
                define_macros=[('event_pthreads_shared_EXPORTS', None)],
                include_dirs=[
                    'bundle/libevent/include',
                    'bundle/libevent/compat',  # for sys/queue.h
                    '.'
                ],
                soversion=event_abi,
            )
        ]
        dsos_pvxs += ['pvxslibs.lib.event_pthread']

    DSOS += [
        DSO(
            'pvxslibs.lib.event_core',
            src_core,
            define_macros=[('event_core_shared_EXPORTS', None)],
            include_dirs=[
                'bundle/libevent/include',
                'bundle/libevent/compat',  # for sys/queue.h
                '.'
            ],
            soversion=event_abi,
            libraries=event_libs,
        ),
        DSO(
            'pvxslibs.lib.pvxs',
            src_pvxs,
            define_macros=[('PVXS_API_BUILDING', None),
                           ('PVXS_ENABLE_EXPERT_API', None)] +
            get_config_var('CPPFLAGS'),
            include_dirs=[
                'bundle/libevent/include',
                'src',
                '.',  # generated headers under build/tmp
                'pvxslibs/include',  # generated headers under build/lib
                epicscorelibs.path.include_path
            ],
            extra_compile_args=cxx11_flags + get_config_var('CXXFLAGS'),
            extra_link_args=cxx11_flags + get_config_var('LDFLAGS'),
            soversion=pvxs_abi,
            dsos=dsos_pvxs,
            libraries=get_config_var('LDADD') + event_libs,
        )
    ]

    return DSOS
Example #9
0
    def run(self):
        log.info("In Expand")
        self.mkpath(os.path.join(self.build_temp, 'event2'))
        self.mkpath(os.path.join(self.build_lib, 'pvxslibs', 'include',
                                 'pvxs'))

        OS_CLASS = get_config_var('OS_CLASS')

        self.distribution.DEFS = DEFS = {
            # *NIX unsupported by EPICS Base
            '_ALL_SOURCE': None,
            '_TANDEM_SOURCE': None,
            '__EXTENSIONS__': None,
            '_MINIX': None,
            '__EXT_POSIX2': None,
            '_LARGE_FILES': None,
            '_POSIX_PTHREAD_SEMANTICS': None,
            'EVENT__HAVE_SA_FAMILY_T': None,
            # unused
            '_FILE_OFFSET_BITS': None,
            '_POSIX_1_SOURCE': None,
            '_POSIX_SOURCE': None,
            # config
            'EVENT__DISABLE_DEBUG_MODE': None,
            'EVENT__DISABLE_MM_REPLACEMENT': None,
            'EVENT__DISABLE_THREAD_SUPPORT': None,
            'EVENT__HAVE_LIBZ': None,
            'EVENT__HAVE_OPENSSL': None,
            'EVENT__HAVE_MBEDTLS': None,
        }

        DEFS.update(pvxsversion)  # PVXS_*_VERSION
        DEFS.update(eventversion)  # EVENT*VERSION

        for var in ('EPICS_HOST_ARCH', 'T_A', 'OS_CLASS', 'CMPLR_CLASS'):
            DEFS[var] = get_config_var(var)

        probe = ProbeToolchain()

        if probe.check_symbol('__GNU_LIBRARY__', headers=['features.h']):
            DEFS['_GNU_SOURCE'] = '1'
            probe.define_macros += [('_GNU_SOURCE', None)]
        else:
            DEFS['_GNU_SOURCE'] = None

        if OS_CLASS == 'WIN32':
            probe.headers += ['winsock2.h', 'ws2tcpip.h']
            probe.define_macros += [('Iwinsock2.h', None),
                                    ('Iws2tcpip.h', None),
                                    ('_WIN32_WINNT', '0x0600')]

            if probe.check_include('afunix.h'):
                DEFS['EVENT__HAVE_AFUNIX_H'] = '1'
                probe.headers.append('afunix.h')
            else:
                DEFS['EVENT__HAVE_AFUNIX_H'] = None

            DEFS.update({
                'EVENT__HAVE_INET_NTOP': '0',
                'EVENT__HAVE_INET_PTON': '0',
                'EVENT__HAVE_PTHREADS': '0',
                'EVENT__HAVE_WEPOLL': '1',
            })

        else:
            DEFS.update({
                'EVENT__HAVE_AFUNIX_H': None,
                'EVENT__HAVE_PTHREADS': '1',
                'EVENT__HAVE_WEPOLL': None,
            })
            probe.headers += ['pthread.h']

        for hfile, isextra in [
            ('sys/types.h', True),
            ('sys/socket.h', True),
            ('sys/random.h', True),
            ('netinet/in.h', True),
            ('sys/un.h', True),
            ('netinet/in6.h', True),
            ('unistd.h', False),
            ('netdb.h', False),
            ('dlfcn.h', False),
            ('arpa/inet.h', False),
            ('fcntl.h', True),
            ('inttypes.h', False),
            ('memory.h', False),
            ('poll.h', False),
            ('port.h', True),
            ('signal.h', False),
            ('stdarg.h', False),
            ('stddef.h', False),
            ('stdint.h', False),
            ('stdlib.h', False),
            ('strings.h', False),
            ('string.h', False),
            ('sys/devpoll.h', False),
            ('sys/epoll.h', False),
            ('sys/eventfd.h', False),
            ('sys/event.h', False),
            ('sys/ioctl.h', False),
            ('sys/mman.h', False),
            ('sys/param.h', False),
            ('sys/queue.h', False),
            ('sys/select.h', False),
            ('sys/sendfile.h', False),
            ('sys/stat.h', False),
            ('sys/time.h', True),
            ('sys/uio.h', False),
            ('sys/types.h', True),
            ('ifaddrs.h', False),
            ('mach/mach_time.h', False),
            ('mach/mach.h', False),
            ('netinet/tcp.h', False),
            ('sys/wait.h', False),
            ('sys/resource.h', False),
            ('sys/sysctl.h', False),  # TODO !linux
            ('sys/timerfd.h', False),
            ('errno.h', False)
        ]:
            if probe.check_include(hfile):
                DEFS['EVENT__HAVE_' +
                     hfile.upper().replace('/', '_').replace('.', '_')] = '1'
                probe.headers.append(hfile)
            else:
                DEFS['EVENT__HAVE_' +
                     hfile.upper().replace('/', '_').replace('.', '_')] = None

        for sym in [
                'epoll_create', 'epoll_ctl', 'eventfd', 'clock_gettime',
                'fcntl', 'gettimeofday', 'kqueue', 'mmap', 'pipe', 'pipe2',
                'poll', 'port_create', 'sendfile', 'sigaction', 'signal',
                'strsignal', 'splice', 'strlcpy', 'strsep', 'strtok_r',
                'vasprintf', 'sysctl', 'accept4', 'arc4random',
                'arc4random_buf', 'arc4random_addrandom', 'epoll_create1',
                'getegid', 'geteuid', 'getifaddrs', 'issetugid',
                'mach_absolute_time', 'nanosleep', 'usleep', 'timeradd',
                'timerfd_create', 'pthread_mutexattr_setprotocol', 'setenv',
                'setrlimit', 'umask', 'unsetenv', 'gethostbyname_r',
                'getservbyname', 'select', '_gmtime64_s', '_gmtime64',
                '__FUNCTION__', 'F_SETFD', 'getrandom', 'getaddrinfo',
                'getnameinfo', 'getprotobynumber', 'inet_ntop', 'inet_pton',
                'strtoll', 'timerclear', 'timercmp', 'timerisset', 'putenv'
        ]:
            DEFS['EVENT__HAVE_' + sym.upper().replace('/', '_').replace(
                '.', '_')] = '1' if probe.check_symbol(sym) else None

        DEFS['EVENT__HAVE___func__'] = '1' if probe.check_symbol(
            '__func__') else None

        DEFS['EVENT__HAVE_EPOLL'] = DEFS['EVENT__HAVE_EPOLL_CREATE']
        DEFS['EVENT__HAVE_DEVPOLL'] = DEFS['EVENT__HAVE_SYS_DEVPOLL_H']

        DEFS['EVENT__HAVE_TAILQFOREACH'] = '1' if probe.check_symbol(
            'TAILQ_FOREACH', ['sys/queue.h']) else None
        DEFS['EVENT__HAVE_DECL_CTL_KERN'] = '1' if probe.check_symbol(
            'CTL_KERN', ['sys/sysctl.h']) else '0'
        DEFS['EVENT__HAVE_DECL_KERN_ARND'] = '1' if probe.check_symbol(
            'KERN_ARND', ['sys/sysctl.h']) else '0'
        DEFS['EVENT__HAVE_FD_MASK'] = '1' if probe.check_symbol(
            'FD_MASK') else '0'
        DEFS['EVENT__HAVE_SETFD'] = '1' if probe.check_symbol(
            'F_SETFD') else '0'

        DEFS['EVENT__DNS_USE_CPU_CLOCK_FOR_ID'] = DEFS[
            'EVENT__HAVE_CLOCK_GETTIME']

        DEFS['EVENT__DNS_USE_GETTIMEOFDAY_FOR_ID'] = None
        DEFS['EVENT__DNS_USE_FTIME_FOR_ID'] = None

        DEFS['EVENT__HAVE_EVENT_PORTS'] = '1' if DEFS[
            'EVENT__HAVE_PORT_H'] == '1' and DEFS[
                'EVENT__HAVE_PORT_CREATE'] == '1' else None

        if OS_CLASS == 'WIN32':
            # windows has select(), but support comes from win32select.c instead of the usual select.c
            DEFS['EVENT__HAVE_SELECT'] = None

        for kw in ['inline', 'size_t']:
            DEFS['EVENT__' + kw] = kw
        DEFS['EVENT__inline'] = 'inline'
        DEFS['EVENT__size_t'] = 'size_t'

        DEFS['EVENT__HAVE_GETHOSTBYNAME_R_3_ARG'] = '1' if probe.try_compile(
            '''
            #include <netdb.h>
            int wrap_gethostbyname_r(const char *name, struct hostent *hp, struct hostent_data *hdata) {
                return gethostbyname_r(name, hp, hdata);
            }
            ''') else None

        DEFS['EVENT__HAVE_GETHOSTBYNAME_R_5_ARG'] = '1' if probe.try_compile(
            '''
            #include <netdb.h>
            struct hostent *wrap_gethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t buflen, int *herr) {
                return gethostbyname_r(name, hp, buf, buflen, herr);
            }
            ''') else None

        DEFS['EVENT__HAVE_GETHOSTBYNAME_R_6_ARG'] = '1' if probe.try_compile(
            '''
            #include <netdb.h>
            int wrap_gethostbyname_r(const char *name, struct hostent *hp, char *buf, size_t buflen, struct hostent **result, int *herr) {
                return gethostbyname_r(name, hp, buf, buflen, result, herr);
            }
            ''') else None

        for type in [
                'uint8_t',
                'uint16_t',
                'uint32_t',
                'uint64_t',
                'short',
                'int',
                'unsigned',
                'unsigned',
                'unsigned int',
                'long',
                'long long',
                'void *',
                'pthread_t',
                'uintptr_t',
                'size_t',
                #'ssize_t',
                #'SSIZE_T',
                'off_t',
                'socklen_t',
                'pid_t',
                'sa_family_t',
                'struct addrinfo',
                'struct in6_addr',
                'struct sockaddr_in',
                'struct sockaddr_in6',
                'struct sockaddr_un',
                'struct sockaddr_storage',
                'time_t',
                'struct linger'
        ]:
            mangled_type = type.upper().replace(' ', '_').replace('*', 'P')
            try:
                DEFS['EVENT__SIZEOF_' + mangled_type] = str(probe.sizeof(type))
            except CompileError:
                DEFS['EVENT__SIZEOF_' + mangled_type] = '0'
                DEFS['EVENT__HAVE_' + mangled_type] = None
            else:
                DEFS['EVENT__HAVE_' + mangled_type] = '1'

        try:
            DEFS['EVENT__SIZEOF_SSIZE_T'] = str(probe.sizeof('ssize_t'))
            DEFS['EVENT__ssize_t'] = 'ssize_t'
        except CompileError:
            DEFS['EVENT__SIZEOF_SSIZE_T'] = str(probe.sizeof('SSIZE_T'))
            DEFS['EVENT__ssize_t'] = 'SSIZE_T'
            # libevent CMakeLists.txt defaults to 'int' if neither is available, which seems wrong...
        DEFS['EVENT__HAVE_SSIZE_T'] = '1'

        if DEFS['EVENT__SIZEOF_SOCKLEN_T'] != '0':
            DEFS['EVENT__socklen_t'] = 'socklen_t'

        else:
            DEFS['EVENT__socklen_t'] = 'unsigned int'
            DEFS['EVENT__SIZEOF_SOCKLEN_T'] = DEFS[
                'EVENT__SIZEOF_UNSIGNED_INT']

        for struct, member in [('struct in6_addr', 's6_addr16'),
                               ('struct in6_addr', 's6_addr32'),
                               ('struct sockaddr_in6', 'sin6_len'),
                               ('struct sockaddr_in', 'sin_len'),
                               ('struct sockaddr_storage', 'ss_family'),
                               ('struct sockaddr_storage', '__ss_family')]:
            mangled_mem = ('EVENT__HAVE_%s_%s' %
                           (struct, member)).upper().replace(' ', '_')
            DEFS[mangled_mem] = '1' if probe.check_member(struct,
                                                          member) else None

        DEFS['EVENT__TIME_WITH_SYS_TIME'] = None

        # TODO: assume working kqueue
        DEFS['EVENT__HAVE_WORKING_KQUEUE'] = DEFS['EVENT__HAVE_KQUEUE']
        print(DEFS)

        cexpand('src/describe.h@',
                os.path.join(self.build_temp, 'describe.h'),
                DEFS,
                dry_run=self.dry_run)
        cexpand('src/pvxs/versionNum.h@',
                os.path.join(self.build_lib, 'pvxslibs', 'include', 'pvxs',
                             'versionNum.h'),
                DEFS,
                dry_run=self.dry_run)
        cexpand('bundle/libevent/evconfig-private.h.cmake',
                os.path.join(self.build_temp, 'evconfig-private.h'),
                DEFS,
                dry_run=self.dry_run)
        cexpand('bundle/libevent/event-config.h.cmake',
                os.path.join(self.build_temp, 'event2', 'event-config.h'),
                DEFS,
                dry_run=self.dry_run)

        if self.dry_run:
            log.info('Would create pvxsVCS.h')
        else:
            log.info('Writing pvxsVCS.h')
            with open(os.path.join(self.build_temp, 'pvxsVCS.h'), 'w') as F:
                F.write('''
#ifndef PVXS_VCS_VERSION
#  define PVXS_VCS_VERSION "pip"
#endif 
''')