aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2023-02-07 21:15:17 -0500
committerDavid Robillard <d@drobilla.net>2023-02-12 16:11:24 -0500
commit39b2eaebb6639fcb9c291099a0681bf9ea9aac3b (patch)
tree4931c3be6c944f2d90aa85f30c2d0692b050b9a0
parentd6e6dfcc70212ec5cf552e446eb76caae9939426 (diff)
downloadserd-39b2eaebb6639fcb9c291099a0681bf9ea9aac3b.tar.gz
serd-39b2eaebb6639fcb9c291099a0681bf9ea9aac3b.tar.bz2
serd-39b2eaebb6639fcb9c291099a0681bf9ea9aac3b.zip
Check for POSIX features with the build system
-rw-r--r--NEWS3
-rw-r--r--meson.build56
-rw-r--r--meson_options.txt3
-rw-r--r--src/serd_config.h85
4 files changed, 105 insertions, 42 deletions
diff --git a/NEWS b/NEWS
index fe0d5cca..b9a34beb 100644
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,7 @@ serd (0.31.0) unstable; urgency=medium
* Allow SERD_API to be defined by the user
* Avoid creating test files in the current directory
* Avoid using ASCII grave as a quote
+ * Check for POSIX features with the build system
* Clean up code
* Fix crash when trying to read chunks without starting
* Fix hang when skipping an error at EOF when lax parsing
@@ -15,7 +16,7 @@ serd (0.31.0) unstable; urgency=medium
* Replace duplicated dox_to_sphinx script with sphinxygen dependency
* Test header for warnings more strictly
- -- David Robillard <d@drobilla.net> Tue, 20 Dec 2022 12:31:33 +0000
+ -- David Robillard <d@drobilla.net> Tue, 07 Feb 2023 23:34:12 +0000
serd (0.30.16) stable; urgency=medium
diff --git a/meson.build b/meson.build
index de5ba40c..ddef9fe2 100644
--- a/meson.build
+++ b/meson.build
@@ -42,13 +42,6 @@ m_dep = cc.find_library('m', required: false)
# Platform Configuration #
##########################
-platform_args = []
-if host_machine.system() in ['gnu', 'linux']
- platform_args += [
- '-D_POSIX_C_SOURCE=200809L',
- ]
-endif
-
# Use versioned name everywhere to support parallel major version installations
if host_machine.system() == 'windows'
if get_option('default_library') == 'both'
@@ -59,6 +52,49 @@ else
soversion = meson.project_version().split('.')[0]
endif
+# Request POSIX APIs from standard headers if necessary
+system_c_args = []
+if host_machine.system() in ['cygwin', 'gnu', 'linux']
+ system_c_args += ['-D_POSIX_C_SOURCE=200809L']
+endif
+
+# Build platform-specific configuration arguments
+platform_c_args = []
+if get_option('checks').disabled()
+ # Generic build without platform-specific features
+ platform_c_args += ['-DSERD_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 += ['-DSERD_NO_DEFAULT_CONFIG'] + system_c_args
+
+ # Define HAVE_SOMETHING symbols for all detected features
+ template = '#include <@0@>\nint main(void) { @1@; }'
+ if cc.links(
+ template.format('stdio.h',
+ 'return fileno(stdin);'),
+ args: system_c_args,
+ name: 'fileno')
+ platform_c_args += ['-DHAVE_FILENO']
+ endif
+ if cc.links(
+ template.format('fcntl.h',
+ 'posix_fadvise(0, 0, 4096, POSIX_FADV_SEQUENTIAL))'),
+ args: system_c_args,
+ name: 'posix_fadvise')
+ platform_c_args += ['-DHAVE_POSIX_FADVISE']
+ endif
+ if cc.links(
+ template.format('stdlib.h',
+ 'void* mem=NULL; posix_memalign(&mem, 8U, 8U);'),
+ args: system_c_args,
+ name: 'posix_memalign')
+ platform_c_args += ['-DHAVE_POSIX_MEMALIGN']
+ endif
+endif
+
###########
# Library #
###########
@@ -92,10 +128,10 @@ endif
libserd = library(
versioned_name,
sources,
- c_args: c_suppressions + extra_c_args + platform_args + [
+ c_args: [
'-DSERD_INTERNAL',
'-DSERD_VERSION="@0@"'.format(meson.project_version()),
- ],
+ ] + c_suppressions + extra_c_args + platform_c_args,
dependencies: m_dep,
gnu_symbol_visibility: 'hidden',
include_directories: include_dirs,
@@ -142,7 +178,7 @@ if not get_option('tools').disabled()
serdi = executable(
'serdi',
files('src/serdi.c'),
- c_args: c_suppressions + platform_args,
+ c_args: c_suppressions + platform_c_args,
dependencies: serd_dep,
install: true,
link_args: tool_link_args,
diff --git a/meson_options.txt b/meson_options.txt
index 38bc94e3..b32b4693 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -1,6 +1,9 @@
# Copyright 2021-2022 David Robillard <d@drobilla.net>
# SPDX-License-Identifier: 0BSD OR ISC
+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/serd_config.h b/src/serd_config.h
index df73522b..e54b8688 100644
--- a/src/serd_config.h
+++ b/src/serd_config.h
@@ -1,15 +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 (typically via
- the build system) while still allowing the source to be built without any
- configuration. The build system can define SERD_NO_DEFAULT_CONFIG to disable
- defaults, in which case it must define things like HAVE_FEATURE to enable
- features. The design here ensures that compiler warnings or
- include-what-you-use will catch any mistakes.
+ 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 `SERD_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 SERD_CONFIG_H
@@ -21,62 +41,65 @@
#if !defined(SERD_NO_DEFAULT_CONFIG)
// We need unistd.h to check _POSIX_VERSION
-# ifndef SERD_NO_POSIX
-# ifdef __has_include
-# if __has_include(<unistd.h>)
-# include <unistd.h>
-# endif
-# elif defined(__unix__)
+# ifdef __has_include
+# if __has_include(<unistd.h>)
# include <unistd.h>
# endif
+# elif defined(__unix__)
+# include <unistd.h>
+# endif
+
+// Define SERD_POSIX_VERSION unconditionally for convenience
+# if defined(_POSIX_VERSION)
+# define SERD_POSIX_VERSION _POSIX_VERSION
+# else
+# define SERD_POSIX_VERSION 0
# endif
// POSIX.1-2001: fileno()
# ifndef HAVE_FILENO
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
-# define HAVE_FILENO
+# if SERD_POSIX_VERSION >= 200112L || defined(_WIN32)
+# define HAVE_FILENO 1
# endif
# endif
// POSIX.1-2001: posix_fadvise()
# ifndef HAVE_POSIX_FADVISE
-# ifndef __APPLE__
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
-# define HAVE_POSIX_FADVISE
-# endif
+# if SERD__POSIX_VERSION >= 200112L && !defined(__APPLE__)
+# define HAVE_POSIX_FADVISE 1
# endif
# endif
// POSIX.1-2001: posix_memalign()
# ifndef HAVE_POSIX_MEMALIGN
-# if defined(_POSIX_VERSION) && _POSIX_VERSION >= 200112L
-# define HAVE_POSIX_MEMALIGN
+# if SERD_POSIX_VERSION >= 200112L
+# define HAVE_POSIX_MEMALIGN 1
# endif
# endif
#endif // !defined(SERD_NO_DEFAULT_CONFIG)
/*
- Make corresponding USE_FEATURE defines based on the HAVE_FEATURE defines from
- above or the command line. The code checks for these using #if (not #ifdef),
- so there will be an undefined warning if it checks for an unknown feature,
- and this header is always required by any code that checks for features, even
- if the build system defines them all.
+ Unconditionally define symbols like USE_SOMETHING based on HAVE_SOMETHING, if
+ it's defined. The code checks these using #if (not #ifdef), so there will be
+ a warning if it checks for an unknown feature or doesn't include this header.
+ This header should be the only file in the source code that touches symbols
+ like HAVE_SOMETHING.
*/
-#ifdef HAVE_FILENO
+#if defined(HAVE_FILENO) && HAVE_FILENO
# define USE_FILENO 1
#else
# define USE_FILENO 0
#endif
-#ifdef HAVE_POSIX_FADVISE
+#if defined(HAVE_POSIX_FADVISE) && HAVE_POSIX_FADVISE
# define USE_POSIX_FADVISE 1
#else
# define USE_POSIX_FADVISE 0
#endif
-#ifdef HAVE_POSIX_MEMALIGN
+#if defined(HAVE_POSIX_MEMALIGN) && HAVE_POSIX_MEMALIGN
# define USE_POSIX_MEMALIGN 1
#else
# define USE_POSIX_MEMALIGN 0