Reputation: 11986
My project follows the POSIX.1-2008 standard and I would like to ensure that the user's implementation conforms to this standard.
So far I've been using AC_DEFINE
to define the _POSIX_C_SOURCE
macro as specified in the POSIX standard.
AC_DEFINE([_POSIX_C_SOURCE], [200809L], [Define the POSIX version])
However, since this is a simple C preprocessor #define
macro , it does nothing to prevent an implementation that isn't POSIX-compliant from compiling.
Does Autoconf offer a standard macro to check for the implementation's conformance to a specific POSIX standard?
Upvotes: 1
Views: 1631
Reputation: 11986
To portably check if the user's implementation conforms to a specific POSIX standard, use AC_EGREP_CPP
to check the existence and value of _POSIX_VERSION
:
AC_EGREP_CPP(posix_200809L_supported,
[#define _POSIX_C_SOURCE 200809L
#include <unistd.h>
#ifdef _POSIX_VERSION
#if _POSIX_VERSION == 200809L
posix_200809L_supported
#endif
#endif
],
[],
[AC_MSG_FAILURE([*** Implementation must conform to the POSIX.1-2008 standard.])]
)
This works due to several guarantees made by POSIX.
We first set _POSIX_C_SOURCE
to 200809L
.
#define _POSIX_C_SOURCE 200809L
POSIX.1-2008 states that when an application includes a header described by POSIX.1-2008, and when this feature test macro (_POSIX_C_SOURCE
) is defined to have the value 200809L
, then all symbols required by POSIX.1-2008 to appear when the header is included shall be made visible
.
So when we include unistd.h
in the next line, all symbols required by POSIX.1-2008 to appear in unistd.h
will be made visible.
#include <unistd.h>
Since _POSIX_VERSION
is required to appear in unistd.h
, it too is now visible.
_POSIX_VERSION
is required by the POSIX.1-2008 standard to be set to a value of 200809L
.
For implementations conforming to POSIX.1-2008, the value shall be 200809L.
So all we have to do now is test if _POSIX_VERSION
is defined, and if so, whether it's set to a value equal to 200809L
.
#ifdef _POSIX_VERSION
#if _POSIX_VERSION == 200809L
Checking whether _POSIX_VERSION
is defined helps us determine if there is support for any POSIX standard on the implementation. Checking the value of _POSIX_VERSION
helps us narrow down whether a specific version of the POSIX standard is supported.
If both of these conditions are true, then the implementation almost certainly supports POSIX.1-2008.
Upvotes: 3
Reputation: 22348
Here's an autoconf test that relies on the negative array size trick:
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[#include <unistd.h>]],
[[int n[(_POSIX_VERSION == 200809L) ? (-1) : (+1)];]])],
AC_MSG_FAILURE([POSIX.1-2008 profile required]))
Using getconf
is fine if the software is only being built on the host machine.
ac_posix_version=`getconf _POSIX_VERSION`
if test $ac_posix_version -ne 200809 >/dev/null 2>&1
AC_MSG_FAILURE([POSIX.1-2008 profile required])
fi
This might have bugs (not tested). It's clearly of no use in cross compilation.
Upvotes: 2