summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--meson.build203
-rw-r--r--meson_options.txt4
-rw-r--r--src/ring.c16
-rw-r--r--src/zix_config.h124
4 files changed, 156 insertions, 191 deletions
diff --git a/meson.build b/meson.build
index 55e460f..545d759 100644
--- a/meson.build
+++ b/meson.build
@@ -45,9 +45,10 @@ endif
# Platform Configuration #
##########################
+# Determine system dependencies of the library
+dependencies = []
thread_dep = dependency('threads', required: get_option('threads'))
-
-platform_c_args = []
+dependencies = [thread_dep]
# Use versioned name everywhere to support parallel major version installations
if host_machine.system() == 'windows'
@@ -59,145 +60,119 @@ else
soversion = meson.project_version().split('.')[0]
endif
-# Determine whether to use POSIX
-no_posix = get_option('posix').disabled() or host_machine.system() == 'windows'
-if no_posix
- platform_c_args += ['-DZIX_NO_POSIX']
-elif host_machine.system() == 'darwin'
- platform_c_args += [
+# Request POSIX and system APIs from standard headers if necessary
+system_c_args = []
+if host_machine.system() == 'darwin'
+ system_c_args += [
'-D_DARWIN_C_SOURCE',
]
elif host_machine.system() in ['gnu', 'linux']
- platform_c_args += [
+ system_c_args += [
'-D_GNU_SOURCE',
'-D_POSIX_C_SOURCE=200809L',
'-D_XOPEN_SOURCE=600',
]
elif host_machine.system() in ['dragonfly', 'freebsd', 'netbsd', 'openbsd']
- platform_c_args += [
+ system_c_args += [
'-D_BSD_SOURCE',
]
else
- platform_c_args += [
+ system_c_args += [
'-D_POSIX_C_SOURCE=200809L',
'-D_XOPEN_SOURCE=600',
]
endif
-# Check for platform features with the build system
-if get_option('checks')
- clock_gettime_code = '''#include <time.h>
-int main(void) { struct timespec t; return clock_gettime(CLOCK_MONOTONIC, &t); }
-'''
+# Build platform-specific configuration arguments
+platform_c_args = []
+if get_option('checks').disabled()
+ # Generic build without platform-specific features
+ platform_c_args += ['-DZIX_NO_DEFAULT_CONFIG']
+elif get_option('checks').auto()
+ # Statically detect configuration from the build environment
+ platform_c_args += system_c_args
+else
+ # Only use the features detected by the build system
+ platform_c_args += ['-DZIX_NO_DEFAULT_CONFIG'] + system_c_args
- clonefile_code = '''#include <sys/attr.h>
-#include <sys/clonefile.h>
-int main(void) { return clonefile("/src", "/dst", 0); }'''
+ # Define HAVE_SOMETHING symbols for all detected features
+ template = '#include <@0@>\nint main(void) { @1@ }'
- copy_file_range_code = '''#include <unistd.h>
-int main(void) { return copy_file_range(0, NULL, 1, NULL, 0U, 0U); }'''
+ mac_checks = {
+ 'clonefile':
+ template.format(
+ 'sys/clonefile.h',
+ 'return clonefile("/src", "/dst", 0);'),
+ }
- CreateSymbolicLink_code = '''#include <windows.h>
-int main(void) {
- return CreateSymbolicLink(
- "l", "t", SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);
-}'''
+ posix_checks = {
+ 'clock_gettime':
+ template.format(
+ 'time.h',
+ 'struct timespec t; return clock_gettime(CLOCK_MONOTONIC, &t);'),
- fileno_code = '''#include <stdio.h>
-int main(void) { return fileno(stdin); }'''
+ 'copy_file_range':
+ template.format(
+ 'unistd.h',
+ 'return copy_file_range(0, NULL, 1, NULL, 0U, 0U);'),
- flock_code = '''#include <sys/file.h>
-int main(void) { return flock(0, 0); }'''
+ 'fileno': template.format('stdio.h', 'return fileno(stdin);'),
+ 'flock': template.format('sys/file.h', 'return flock(0, 0);'),
- lstat_code = '''#include <sys/stat.h>
-int main(void) { struct stat s; return lstat("/", &s); }'''
+ 'lstat':
+ template.format('sys/stat.h', 'struct stat s; return lstat("/", &s);'),
- mlock_code = '''#include <sys/mman.h>
-int main(void) { return mlock(0, 0); }'''
+ 'mlock': template.format('sys/mman.h', 'return mlock(0, 0);'),
- pathconf_code = '''#include <unistd.h>
-int main(void) { return pathconf("/", _PC_PATH_MAX) > 0L; }'''
+ 'pathconf':
+ template.format('unistd.h', 'return pathconf("/", _PC_PATH_MAX) > 0L;'),
- posix_fadvise_code = '''#include <fcntl.h>
-int main(void) { posix_fadvise(0, 0, 4096, POSIX_FADV_SEQUENTIAL); }'''
+ 'posix_fadvise': template.format(
+ 'fcntl.h',
+ 'posix_fadvise(0, 0, 4096, POSIX_FADV_SEQUENTIAL);'),
- posix_memalign_code = '''#include <stdlib.h>
-int main(void) { void* mem; posix_memalign(&mem, 8, 8); }'''
+ 'posix_memalign':
+ template.format('stdlib.h', 'void* mem; posix_memalign(&mem, 8, 8);'),
- realpath_code = '''#include <stdlib.h>
-int main(void) { return realpath("/", NULL) != NULL; }'''
+ 'realpath':
+ template.format('stdlib.h', 'return realpath("/", NULL) != NULL;'),
+
+ 'sysconf':
+ template.format('unistd.h', 'return sysconf(_SC_PAGE_SIZE) > 0L;'),
+ }
+
+ windows_checks = {
+ 'CreateSymbolicLink':
+ template.format(
+ 'windows.h',
+ 'return CreateSymbolicLink(' +
+ '"l", "t", SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE);'),
+ }
+
+ if host_machine.system() == 'darwin'
+ checks = posix_checks + mac_checks
+ elif host_machine.system() == 'windows'
+ checks = windows_checks
+ else
+ checks = posix_checks
- sem_timedwait_code = '''#include <semaphore.h>
+ if thread_dep.found()
+ if cc.links('''#include <semaphore.h>
#include <time.h>
-int main(void) { sem_t s; struct timespec t; return sem_timedwait(&s, &t); }'''
-
- sysconf_code = '''#include <unistd.h>
-int main(void) { return sysconf(_SC_PAGE_SIZE) > 0L; }'''
-
- platform_c_args += [
- '-DZIX_NO_DEFAULT_CONFIG',
- '-DHAVE_CLOCK_GETTIME=@0@'.format(
- cc.links(clock_gettime_code,
- args: platform_c_args,
- name: 'clock_gettime').to_int()),
- '-DHAVE_CLONEFILE=@0@'.format(
- (host_machine.system() == 'darwin' and
- cc.links(clonefile_code,
- args: platform_c_args,
- name: 'clonefile')).to_int()),
- '-DHAVE_COPY_FILE_RANGE=@0@'.format(
- (host_machine.system() not in ['darwin', 'windows'] and
- cc.links(copy_file_range_code,
- args: platform_c_args,
- name: 'copy_file_range')).to_int()),
- '-DHAVE_CREATESYMBOLICLINK=@0@'.format(
- (host_machine.system() == 'windows' and
- cc.links(CreateSymbolicLink_code,
- args: platform_c_args,
- name: 'CreateSymbolicLink')).to_int()),
- '-DHAVE_FILENO=@0@'.format(
- cc.links(fileno_code,
- args: platform_c_args,
- name: 'fileno').to_int()),
- '-DHAVE_FLOCK=@0@'.format(
- (host_machine.system() != 'windows' and
- cc.links(flock_code,
- args: platform_c_args,
- name: 'flock')).to_int()),
- '-DHAVE_MLOCK=@0@'.format(
- cc.links(mlock_code,
- args: platform_c_args,
- name: 'mlock').to_int()),
- '-DHAVE_PATHCONF=@0@'.format(
- (host_machine.system() != 'windows' and
- cc.links(pathconf_code,
- args: platform_c_args,
- name: 'pathconf')).to_int()),
- '-DHAVE_POSIX_FADVISE=@0@'.format(
- cc.links(posix_fadvise_code,
- args: platform_c_args,
- name: 'posix_fadvise').to_int()),
- '-DHAVE_POSIX_MEMALIGN=@0@'.format(
- cc.links(posix_memalign_code,
- args: platform_c_args,
- name: 'posix_memalign').to_int()),
- '-DHAVE_REALPATH=@0@'.format(
- (host_machine.system() != 'windows' and
- cc.links(realpath_code,
- args: platform_c_args,
- name: 'realpath')).to_int()),
- '-DHAVE_SEM_TIMEDWAIT=@0@'.format(
- (host_machine.system() not in ['darwin', 'windows'] and
- cc.links(sem_timedwait_code,
- args: platform_c_args,
- dependencies: [thread_dep],
- name: 'sem_timedwait')).to_int()),
- '-DHAVE_SYSCONF=@0@'.format(
- (host_machine.system() != 'windows' and
- cc.links(sysconf_code,
- args: platform_c_args,
- name: 'sysconf')).to_int()),
- ]
+int main(void) { sem_t s; struct timespec t; return sem_timedwait(&s, &t); }''',
+ args: system_c_args,
+ dependencies: thread_dep,
+ name: 'sem_timedwait')
+ platform_c_args += ['-DHAVE_SEM_TIMEDWAIT']
+ endif
+ endif
+ endif
+
+ foreach name, check_code : checks
+ if cc.links(check_code, args: system_c_args, name: name)
+ platform_c_args += ['-DHAVE_@0@'.format(name.to_upper())]
+ endif
+ endforeach
endif
###########
@@ -317,7 +292,7 @@ libzix = library(
versioned_name,
sources,
c_args: c_suppressions + library_c_args,
- dependencies: [thread_dep],
+ dependencies: dependencies,
gnu_symbol_visibility: 'hidden',
include_directories: include_dirs,
install: true,
@@ -340,7 +315,7 @@ pkg.generate(
extra_cflags: extra_c_args,
filebase: versioned_name,
name: 'Zix',
- requires: [thread_dep],
+ requires: dependencies,
subdirs: [versioned_name],
version: meson.project_version(),
)
diff --git a/meson_options.txt b/meson_options.txt
index 975eb3b..0912856 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,8 +1,8 @@
option('benchmarks', type: 'feature', value: 'auto', yield: true,
description: 'Build benchmarks')
-option('checks', type: 'boolean', value: true, yield: true,
- description: 'Check for features with the build system')
+option('checks', type: 'feature', value: 'enabled', yield: true,
+ description: 'Check for platform-specific features')
option('docs', type: 'feature', value: 'auto', yield: true,
description: 'Build documentation')
diff --git a/src/ring.c b/src/ring.c
index 23199a0..ad00f75 100644
--- a/src/ring.c
+++ b/src/ring.c
@@ -9,10 +9,10 @@
#include "zix/allocator.h"
#include "zix/status.h"
-#if USE_MLOCK
-# include <sys/mman.h>
-#elif defined(_WIN32)
+#if defined(_WIN32)
# include <windows.h>
+#elif USE_MLOCK
+# include <sys/mman.h>
#endif
/*
@@ -108,16 +108,16 @@ zix_ring_free(ZixRing* const ring)
ZixStatus
zix_ring_mlock(ZixRing* const ring)
{
-#if USE_MLOCK
- return zix_errno_status_if(mlock(ring, sizeof(ZixRing)) +
- mlock(ring->buf, ring->size));
-
-#elif defined(_WIN32)
+#if defined(_WIN32)
return (VirtualLock(ring, sizeof(ZixRing)) &&
VirtualLock(ring->buf, ring->size))
? ZIX_STATUS_SUCCESS
: ZIX_STATUS_ERROR;
+#elif USE_MLOCK
+ return zix_errno_status_if(mlock(ring, sizeof(ZixRing)) +
+ mlock(ring->buf, ring->size));
+
#else
return ZIX_STATUS_NOT_SUPPORTED;
#endif
diff --git a/src/zix_config.h b/src/zix_config.h
index 7b87826..0aab586 100644
--- a/src/zix_config.h
+++ b/src/zix_config.h
@@ -1,26 +1,35 @@
-// Copyright 2021-2022 David Robillard <d@drobilla.net>
+// Copyright 2021-2023 David Robillard <d@drobilla.net>
// SPDX-License-Identifier: ISC
/*
- Configuration header that defines reasonable defaults at compile time.
-
- This allows compile-time configuration from the command line, while still
- allowing the source to be built "as-is" without any configuration. The idea
- is to support an advanced build system with configuration checks, while still
- allowing the code to be simply "thrown at a compiler" with features
- determined from the compiler or system headers. Everything can be
- overridden, so it should never be necessary to edit this file to build
- successfully.
-
- To ensure that all configure checks are performed, the build system can
- define ZIX_NO_DEFAULT_CONFIG to disable defaults. In this case, it must
- define all HAVE_FEATURE symbols below to 1 or 0 to enable or disable
- features. Any missing definitions will generate a compiler warning.
-
- To ensure that this header is always included properly, all code that uses
- configuration variables includes this header and checks their value with #if
- (not #ifdef). Variables like USE_FEATURE are internal and should never be
- defined on the command line.
+ Configuration header that defines reasonable defaults at compile-time.
+
+ This allows configuration from the command-line (usually by the build system)
+ while still allowing the code to compile "as-is" with reasonable default
+ features on supported platforms.
+
+ This system is designed so that, ideally, no command-line or build-system
+ configuration is needed, but automatic feature detection can be disabled or
+ overridden for maximum control. It should never be necessary to edit the
+ source code to achieve a given configuration.
+
+ Usage:
+
+ - By default, features are enabled if they can be detected or assumed to be
+ available from the build environment, unless `ZIX_NO_DEFAULT_CONFIG` is
+ defined, which disables everything by default.
+
+ - If a symbol like `HAVE_SOMETHING` is defined to non-zero, then the
+ "something" feature is assumed to be available.
+
+ Code rules:
+
+ - To check for a feature, this header must be included, and the symbol
+ `USE_SOMETHING` used as a boolean in an `#if` expression.
+
+ - None of the other configuration symbols described here may be used
+ directly. In particular, this header should be the only place in the
+ source code that touches `HAVE` symbols.
*/
#ifndef ZIX_CONFIG_H
@@ -39,12 +48,17 @@
# endif
# endif
+// Define ZIX_POSIX_VERSION unconditionally for convenience
+# if defined(_POSIX_VERSION)
+# define ZIX_POSIX_VERSION _POSIX_VERSION
+# else
+# define ZIX_POSIX_VERSION 0
+# endif
+
// POSIX.1-2001: clock_gettime()
# ifndef HAVE_CLOCK_GETTIME
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# if ZIX_POSIX_VERSION >= 200112L
# define HAVE_CLOCK_GETTIME 1
-# else
-# define HAVE_CLOCK_GETTIME 0
# endif
# endif
@@ -52,8 +66,6 @@
# ifndef HAVE_CLONEFILE
# if defined(__APPLE__) && __has_include(<sys/clonefile.h>)
# define HAVE_CLONEFILE 1
-# else
-# define HAVE_CLONEFILE 0
# endif
# endif
@@ -63,8 +75,6 @@
(defined(__GLIBC__) && \
(__GLIBC__ > 2 || __GLIBC__ == 2 && __GLIBC_MINOR__ >= 27))
# define HAVE_COPY_FILE_RANGE 1
-# else
-# define HAVE_COPY_FILE_RANGE 0
# endif
# endif
@@ -72,8 +82,6 @@
# ifndef HAVE_CREATESYMBOLICLINK
# if defined(_MSC_VER) && _MSC_VER >= 1910
# define HAVE_CREATESYMBOLICLINK 1
-# else
-# define HAVE_CREATESYMBOLICLINK 0
# endif
# endif
@@ -81,8 +89,6 @@
# ifndef HAVE_FILENO
# if defined(_WIN32) || defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
# define HAVE_FILENO 1
-# else
-# define HAVE_FILENO 0
# endif
# endif
@@ -90,71 +96,55 @@
# ifndef HAVE_FLOCK
# if defined(__APPLE__) || defined(__unix__)
# define HAVE_FLOCK 1
-# else
-# define HAVE_FLOCK 0
# endif
# endif
// POSIX.1-2001: mlock()
# ifndef HAVE_MLOCK
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# if ZIX_POSIX_VERSION >= 200112L
# define HAVE_MLOCK 1
-# else
-# define HAVE_MLOCK 0
# endif
# endif
// POSIX.1-2001: pathconf()
# ifndef HAVE_PATHCONF
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# if ZIX_POSIX_VERSION >= 200112L
# define HAVE_PATHCONF 1
-# else
-# define HAVE_PATHCONF 0
# endif
# endif
// POSIX.1-2001: posix_fadvise()
# ifndef HAVE_POSIX_FADVISE
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# if ZIX_POSIX_VERSION >= 200112L
# define HAVE_POSIX_FADVISE 1
-# else
-# define HAVE_POSIX_FADVISE 0
# endif
# endif
// POSIX.1-2001: posix_memalign()
# ifndef HAVE_POSIX_MEMALIGN
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# if ZIX_POSIX_VERSION >= 200112L
# define HAVE_POSIX_MEMALIGN 1
-# else
-# define HAVE_POSIX_MEMALIGN 0
# endif
# endif
// POSIX.1-2001: realpath()
# ifndef HAVE_REALPATH
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# if ZIX_POSIX_VERSION >= 200112L
# define HAVE_REALPATH 1
-# else
-# define HAVE_REALPATH 0
# endif
# endif
// POSIX.1-2001: sem_timedwait()
# ifndef HAVE_SEM_TIMEDWAIT
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# if ZIX_POSIX_VERSION >= 200112L
# define HAVE_SEM_TIMEDWAIT 1
-# else
-# define HAVE_SEM_TIMEDWAIT 0
# endif
# endif
// POSIX.1-2001: sysconf()
# ifndef HAVE_SYSCONF
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
+# if ZIX_POSIX_VERSION >= 200112L
# define HAVE_SYSCONF 1
-# else
-# define HAVE_SYSCONF 0
# endif
# endif
@@ -168,79 +158,79 @@
if the build system defines them all.
*/
-#if HAVE_CLOCK_GETTIME
+#if defined(HAVE_CLOCK_GETTIME) && HAVE_CLOCK_GETTIME
# define USE_CLOCK_GETTIME 1
#else
# define USE_CLOCK_GETTIME 0
#endif
-#if HAVE_CLONEFILE
+#if defined(HAVE_CLONEFILE) && HAVE_CLONEFILE
# define USE_CLONEFILE 1
#else
# define USE_CLONEFILE 0
#endif
-#if HAVE_COPY_FILE_RANGE
+#if defined(HAVE_COPY_FILE_RANGE) && HAVE_COPY_FILE_RANGE
# define USE_COPY_FILE_RANGE 1
#else
# define USE_COPY_FILE_RANGE 0
#endif
-#if HAVE_CREATESYMBOLICLINK
+#if defined(HAVE_CREATESYMBOLICLINK) && HAVE_CREATESYMBOLICLINK
# define USE_CREATESYMBOLICLINK 1
#else
# define USE_CREATESYMBOLICLINK 0
#endif
-#if HAVE_FILENO
+#if defined(HAVE_FILENO) && HAVE_FILENO
# define USE_FILENO 1
#else
# define USE_FILENO 0
#endif
-#if HAVE_FLOCK
+#if defined(HAVE_FLOCK) && HAVE_FLOCK
# define USE_FLOCK 1
#else
# define USE_FLOCK 0
#endif
-#if HAVE_MLOCK
+#if defined(HAVE_MLOCK) && HAVE_MLOCK
# define USE_MLOCK 1
#else
# define USE_MLOCK 0
#endif
-#if HAVE_PATHCONF
+#if defined(HAVE_PATHCONF) && HAVE_PATHCONF
# define USE_PATHCONF 1
#else
# define USE_PATHCONF 0
#endif
-#if HAVE_POSIX_FADVISE
+#if defined(HAVE_POSIX_FADVISE) && HAVE_POSIX_FADVISE
# define USE_POSIX_FADVISE 1
#else
# define USE_POSIX_FADVISE 0
#endif
-#if HAVE_POSIX_MEMALIGN
+#if defined(HAVE_POSIX_MEMALIGN) && HAVE_POSIX_MEMALIGN
# define USE_POSIX_MEMALIGN 1
#else
# define USE_POSIX_MEMALIGN 0
#endif
-#if HAVE_REALPATH
+#if defined(HAVE_REALPATH) && HAVE_REALPATH
# define USE_REALPATH 1
#else
# define USE_REALPATH 0
#endif
-#if HAVE_SEM_TIMEDWAIT
+#if defined(HAVE_SEM_TIMEDWAIT) && HAVE_SEM_TIMEDWAIT
# define USE_SEM_TIMEDWAIT 1
#else
# define USE_SEM_TIMEDWAIT 0
#endif
-#if HAVE_SYSCONF
+#if defined(HAVE_SYSCONF) && HAVE_SYSCONF
# define USE_SYSCONF 1
#else
# define USE_SYSCONF 0