diff options
author | David Robillard <d@drobilla.net> | 2023-02-07 21:15:17 -0500 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2023-02-12 16:11:24 -0500 |
commit | 39b2eaebb6639fcb9c291099a0681bf9ea9aac3b (patch) | |
tree | 4931c3be6c944f2d90aa85f30c2d0692b050b9a0 | |
parent | d6e6dfcc70212ec5cf552e446eb76caae9939426 (diff) | |
download | serd-39b2eaebb6639fcb9c291099a0681bf9ea9aac3b.tar.gz serd-39b2eaebb6639fcb9c291099a0681bf9ea9aac3b.tar.bz2 serd-39b2eaebb6639fcb9c291099a0681bf9ea9aac3b.zip |
Check for POSIX features with the build system
-rw-r--r-- | NEWS | 3 | ||||
-rw-r--r-- | meson.build | 56 | ||||
-rw-r--r-- | meson_options.txt | 3 | ||||
-rw-r--r-- | src/serd_config.h | 85 |
4 files changed, 105 insertions, 42 deletions
@@ -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 |