我的项目遵循 POSIX.1-2008 标准,我希望确保用户的实施符合此标准。
到目前为止,我一直在使用AC_DEFINE
来定义POSIX标准中指定的_POSIX_C_SOURCE
宏。
AC_DEFINE([_POSIX_C_SOURCE], [200809L], [Define the POSIX version])
但是,由于这是一个简单的C预处理器#define
宏,因此它无法阻止不符合 POSIX标准的实现。
Autoconf 是否提供标准宏来检查实现是否符合特定的POSIX标准?
答案 0 :(得分:3)
要便于检查用户的实现是否符合特定的POSIX标准,请使用AC_EGREP_CPP
检查_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.])]
)
由于POSIX提供了多种保证,这是有效的。
我们首先将_POSIX_C_SOURCE
设置为200809L
。
#define _POSIX_C_SOURCE 200809L
POSIX.1-2008 指出当应用程序包含 POSIX.1-2008 描述的标头时,以及此功能测试宏(_POSIX_C_SOURCE
)被定义为具有值200809L
,然后是all symbols required by POSIX.1-2008 to appear when the header is included shall be made visible
。
因此,当我们在下一行中添加unistd.h
时, POSIX.1-2008 所需的所有符号将显示在unistd.h
中显而易见。
#include <unistd.h>
由于unistd.h
需要显示_POSIX_VERSION
,现在也可以看到它。
_POSIX_VERSION
为set to a value of 200809L
。
对于符合POSIX.1-2008的实现,值应为200809L。
所以我们现在要做的就是测试是否定义了_POSIX_VERSION
,如果是,那么它是否设置为等于200809L
的值。
#ifdef _POSIX_VERSION
#if _POSIX_VERSION == 200809L
检查_POSIX_VERSION
是否已定义有助于我们确定是否支持实施的任何 POSIX 标准。检查_POSIX_VERSION
的值有助于我们缩小是否支持特定版本的 POSIX 标准。
如果这两个条件都成立,那么实施几乎肯定支持 POSIX.1-2008 。
答案 1 :(得分:2)
这是一个依赖于负数组大小技巧的autoconf测试:
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[#include <unistd.h>]],
[[int n[(_POSIX_VERSION == 200809L) ? (-1) : (+1)];]])],
AC_MSG_FAILURE([POSIX.1-2008 profile required]))
如果仅在主机上构建软件,则使用getconf
就可以了。
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
这可能有错误(未经过测试)。在交叉编译中显然没有用。