Document and detect issue with conditional checks

This commit is contained in:
Boris Kolpackov 2022-04-24 12:57:44 +02:00
parent 55d590890e
commit 55e7bd4edb
21 changed files with 152 additions and 0 deletions

View File

@ -85,6 +85,45 @@ h{config}: in{config}
} }
``` ```
Note that an implementation of a check may depend on another check. As a
result, substitutions should not be conditional at the preprocessor level
(unless all the checks are part of the same condition). Nor should the
results of checks be adjusted until after the last check. For example:
```
#ifndef _WIN32
# cmakedefine HAVE_EXPLICIT_BZERO // Condition substitution.
#endif
#cmakedefine HAVE_EXPLICIT_MEMSET // Shares implementation with BZERO.
#cmakedefine BYTE_ORDER
#if BYTE_ORDER == LITTLE_ENDIAN
# undef BYTE_ORDER // Adjusting the result.
#endif
#cmakedefine WORDS_BIGENDIAN // Based on BYTE_ORDER.
```
Below is the correct way to achieve the above semantics:
```
#cmakedefine HAVE_EXPLICIT_BZERO
#cmakedefine HAVE_EXPLICIT_MEMSET
#cmakedefine BYTE_ORDER
#cmakedefine WORDS_BIGENDIAN
#ifdef _WIN32
# undef HAVE_EXPLICIT_BZERO
#endif
#if BYTE_ORDER == LITTLE_ENDIAN
# undef BYTE_ORDER
#endif
```
The built-in checks can be prefixed in order to avoid clashes with similarly The built-in checks can be prefixed in order to avoid clashes with similarly
named macros in other headers. This is an especially good idea if the named macros in other headers. This is an especially good idea if the
resulting header is public. To enable this, we specify the prefix with resulting header is public. To enable this, we specify the prefix with
@ -177,6 +216,39 @@ functionality to avoid clashes across files. However, this does not help
unprefixable names and, as a result, such checks should be implemented in unprefixable names and, as a result, such checks should be implemented in
ways that deal with duplication (for example, include guards). ways that deal with duplication (for example, include guards).
The duplicate suppression is incompatible with conditional (at the
preprocessor level) checks, for example, assuming both `HAVE_EXPLICIT_*`
checks are based on `BUILD2_AUTOCONF_LIBC_VERSION`:
```
#ifndef _WIN32
# undef HAVE_EXPLICIT_BZERO
#endif
#undef HAVE_EXPLICIT_MEMSET
```
In this example, the `autoconf` module will omit the second copy of the
`BUILD2_AUTOCONF_LIBC_VERSION` check as part of the `HAVE_EXPLICIT_MEMSET`
substitution because it was already inserted as part of the
`HAVE_EXPLICIT_BZERO` substitution. But the first copy will not be
preprocessed on Windows.
While there is no bulletproof way to detect such situations (because the
unconditional check could be `BUILD2_AUTOCONF_LIBC_VERSION` itself), it is a
good idea for checks that are based on other checks to verify that the base
macros are in fact defined, for example:
```
// HAVE_EXPLICIT_BZERO : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
...
```
[module-in]: https://build2.org/build2/doc/build2-build-system-manual.xhtml#module-in [module-in]: https://build2.org/build2/doc/build2-build-system-manual.xhtml#module-in
[proj-config]: https://build2.org/build2/doc/build2-build-system-manual.xhtml#proj-config [proj-config]: https://build2.org/build2/doc/build2-build-system-manual.xhtml#proj-config
[checks]: https://github.com/build2/libbuild2-autoconf/tree/master/libbuild2-autoconf/libbuild2/autoconf/checks/ [checks]: https://github.com/build2/libbuild2-autoconf/tree/master/libbuild2-autoconf/libbuild2/autoconf/checks/

View File

@ -1,5 +1,9 @@
// HAVE_BIGENDIAN : BYTE_ORDER // HAVE_BIGENDIAN : BYTE_ORDER
#ifndef BYTE_ORDER
# error BYTE_ORDER appears to be conditionally included
#endif
#undef HAVE_BIGENDIAN #undef HAVE_BIGENDIAN
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN

View File

@ -1,5 +1,9 @@
// HAVE_CLOCK_GETTIME : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_CLOCK_GETTIME : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_CLOCK_GETTIME #undef HAVE_CLOCK_GETTIME
/* Since Linux 2.6/glibc 2.2 (based on glibc commit history), FreeBSD 3.0, /* Since Linux 2.6/glibc 2.2 (based on glibc commit history), FreeBSD 3.0,

View File

@ -1,5 +1,9 @@
// HAVE_DLOPEN : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_DLOPEN : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_DLOPEN #undef HAVE_DLOPEN
/* Since Linux/glibc 2.0 and all versions of other supported UNIXes. /* Since Linux/glibc 2.0 and all versions of other supported UNIXes.

View File

@ -1,5 +1,9 @@
// HAVE_EVENTFD : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_EVENTFD : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_EVENTFD #undef HAVE_EVENTFD
/* Since Linux/glibc 2.8, FreeBSD 13. /* Since Linux/glibc 2.8, FreeBSD 13.

View File

@ -1,5 +1,9 @@
// HAVE_EXPLICIT_BZERO : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_EXPLICIT_BZERO : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_EXPLICIT_BZERO #undef HAVE_EXPLICIT_BZERO
/* Since FreeBSD 11, OpenBSD 5.5, and glibc 2.25. /* Since FreeBSD 11, OpenBSD 5.5, and glibc 2.25.

View File

@ -1,5 +1,9 @@
// HAVE_EXPLICIT_MEMSET : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_EXPLICIT_MEMSET : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_EXPLICIT_MEMSET #undef HAVE_EXPLICIT_MEMSET
/* Since NetBSD 7.0.0. /* Since NetBSD 7.0.0.

View File

@ -1,5 +1,9 @@
// HAVE_FUTIMENS : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_FUTIMENS : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_FUTIMENS #undef HAVE_FUTIMENS
/* Since Linux/glibc 2.6, FreeBSD 10.3, OpenBSD 5.0, NetBSD 6.0, Mac OS 10.6 /* Since Linux/glibc 2.6, FreeBSD 10.3, OpenBSD 5.0, NetBSD 6.0, Mac OS 10.6

View File

@ -1,5 +1,9 @@
// HAVE_FUTIMES : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_FUTIMES : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_FUTIMES #undef HAVE_FUTIMES
/* Since Linux/glibc 2.3, FreeBSD 3.x, OpenBSD 1.2 (but the `OpenBSD` macro /* Since Linux/glibc 2.3, FreeBSD 3.x, OpenBSD 1.2 (but the `OpenBSD` macro

View File

@ -1,5 +1,9 @@
// HAVE_GETAUXVAL : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_GETAUXVAL : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_GETAUXVAL #undef HAVE_GETAUXVAL
/* Since glibc 2.16. /* Since glibc 2.16.

View File

@ -1,5 +1,9 @@
// HAVE_GETENTROPY : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_GETENTROPY : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_GETENTROPY #undef HAVE_GETENTROPY
/* Since Linux/glibc 2.25, OpenBSD 5.6, FreeBSD 12, and Mac OS 12. /* Since Linux/glibc 2.25, OpenBSD 5.6, FreeBSD 12, and Mac OS 12.

View File

@ -1,5 +1,9 @@
// HAVE_INOTIFY : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_INOTIFY : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_INOTIFY #undef HAVE_INOTIFY
/* Since Linux 2.6.3/glibc 2.4. /* Since Linux 2.6.3/glibc 2.4.

View File

@ -1,5 +1,9 @@
// HAVE_LINKAT : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_LINKAT : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_LINKAT #undef HAVE_LINKAT
/* Since Linux 2.6.16/glibc 2.4, FreeBSD 8.0, OpenBSD 5.0, NetBSD 7.0 (it was /* Since Linux 2.6.16/glibc 2.4, FreeBSD 8.0, OpenBSD 5.0, NetBSD 7.0 (it was

View File

@ -1,5 +1,9 @@
// HAVE_POLL : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_POLL : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_POLL #undef HAVE_POLL
/* Since Linux 2.1.23/glibc (all versions; emulated using select() on older /* Since Linux 2.1.23/glibc (all versions; emulated using select() on older

View File

@ -1,5 +1,9 @@
// HAVE_POLLTS : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_POLLTS : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_POLLTS #undef HAVE_POLLTS
/* Since NetBSD 3.0. /* Since NetBSD 3.0.

View File

@ -1,5 +1,9 @@
// HAVE_POSIX_FALLOCATE : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_POSIX_FALLOCATE : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_POSIX_FALLOCATE #undef HAVE_POSIX_FALLOCATE
/* Since Linux/glibc 2.2, FreeBSD 9.0 /* Since Linux/glibc 2.2, FreeBSD 9.0

View File

@ -1,5 +1,9 @@
// HAVE_PPOLL : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_PPOLL : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_PPOLL #undef HAVE_PPOLL
/* Since Linux 2.6.16/glibc 2.4, FreeBSD 11, OpenBSD 5.4. /* Since Linux 2.6.16/glibc 2.4, FreeBSD 11, OpenBSD 5.4.

View File

@ -1,5 +1,9 @@
// HAVE_RENAMEAT2 : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_RENAMEAT2 : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_RENAMEAT2 #undef HAVE_RENAMEAT2
// Since Linux 3.15/glibc 2.28. // Since Linux 3.15/glibc 2.28.

View File

@ -1,5 +1,9 @@
// HAVE_STATX : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_STATX : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_STATX #undef HAVE_STATX
/* Since Linux 4.11/glibc 2.28. /* Since Linux 4.11/glibc 2.28.

View File

@ -1,5 +1,9 @@
// HAVE_THREADSAFE_CLOEXEC : BUILD2_AUTOCONF_LIBC_VERSION // HAVE_THREADSAFE_CLOEXEC : BUILD2_AUTOCONF_LIBC_VERSION
#ifndef BUILD2_AUTOCONF_LIBC_VERSION
# error BUILD2_AUTOCONF_LIBC_VERSION appears to be conditionally included
#endif
#undef HAVE_THREADSAFE_CLOEXEC #undef HAVE_THREADSAFE_CLOEXEC
/* Define if file descriptor-creating functions taking a *_CLOEXEC flag are /* Define if file descriptor-creating functions taking a *_CLOEXEC flag are

View File

@ -1,5 +1,9 @@
// WORDS_BIGENDIAN : BYTE_ORDER // WORDS_BIGENDIAN : BYTE_ORDER
#ifndef BYTE_ORDER
# error BYTE_ORDER appears to be conditionally included
#endif
#undef WORDS_BIGENDIAN #undef WORDS_BIGENDIAN
#if BYTE_ORDER == BIG_ENDIAN #if BYTE_ORDER == BIG_ENDIAN