Complete built-in checks support, add few checks

This commit is contained in:
Boris Kolpackov 2021-11-04 07:38:20 +02:00
parent be2c4ff0b3
commit 5df3ee0dc1
12 changed files with 159 additions and 36 deletions

View File

@ -3,13 +3,47 @@
GNU Autoconf emulation build system module for `build2`. GNU Autoconf emulation build system module for `build2`.
Specifically, this module provides an [`in`][module-in]-based rule for Specifically, this module provides an [`in`][module-in]-based rule for
processing `config.h.in` files. Besides the Autoconf flavor, it also supports processing `config.h.in` files. Besides the Autoconf special line flavor
CMake and Meson variants. (`#undef`), it also supports the CMake (`#cmakedefine`) and Meson
(`#mesondefine`) variants.
Similar to Autoconf, the module provides built-in support for a number of Similar to Autoconf, this module provides built-in support for a number of
common `HAVE_*` configuration options. However, the values of these options common `HAVE_*` configuration options. However, the values of these options
are not discovered by dynamic probing, such as trying to compile a test are not discovered by dynamic probing, such as trying to compile a test
program to check if the header is present. Instead, they are set to static program to check if the feature is present. Instead, they are set to static
expected values based on the platform/compiler macros. expected values based on the platform/compiler macros (see note at the
beginning of [Project Configuration][proj-config] for rationale).
See [`libbuild2/autoconf/checks/`][checks] for the list of available build-in
configuration options.
## Adding new configuration options.
To add a new configuration option `<NAME>` simply create the `<NAME>.h` header
file with the corresponding check and place it into
[`libbuild2/autoconf/checks/`][checks] (use existing checks for inspiration).
The first line in this header file must be in the form:
```
// <NAME>
```
Subsequent lines should be C-style comments or preprocessor directives that
`#define` or `#undef` `<NAME>` depending on whether the feature is available
(though there can be idiosyncrasies; see `const.h`, for example). Note that
there should be no double-quotes or backslashes except for line
continuations. For example:
```
// HAVE_FOO
#ifndef _WIN32
# define HAVE_FOO 1
#else
# undef HAVE_FOO /* No foo on Windows. */
#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
[checks]: https://github.com/build2/libbuild2-autoconf/tree/master/libbuild2-autoconf/libbuild2/autoconf/checks/

View File

@ -43,8 +43,8 @@ cat <<EOI >=config.h.in;
#undef CUSTOM_LINE #undef CUSTOM_LINE
#undef CUSTOM_BLOCK #undef CUSTOM_BLOCK
#undef HAVE_TEST_DUMMY1_H #undef zzz_TEST_DUMMY1_H
#undef HAVE_TEST_DUMMY2_H #undef zzz_TEST_DUMMY2_H
EOI EOI
$* <<EOI &config.h &config.h.d; $* <<EOI &config.h &config.h.d;
./: h{config}: in{config} ./: h{config}: in{config}
@ -64,7 +64,7 @@ $* <<EOI &config.h &config.h.d;
#endif #endif
' '
HAVE_TEST_DUMMY2_H = '#define HAVE_TEST_DUMMY2_H 2' zzz_TEST_DUMMY2_H = '#define zzz_TEST_DUMMY2_H 2'
} }
EOI EOI
cat config.h >>EOO cat config.h >>EOO
@ -84,8 +84,8 @@ cat config.h >>EOO
# define CUSTOM 123 # define CUSTOM 123
#endif #endif
#define HAVE_TEST_DUMMY1_H 1 #define zzz_TEST_DUMMY1_H 1
#define HAVE_TEST_DUMMY2_H 2 #define zzz_TEST_DUMMY2_H 2
EOO EOO
: basics-cmake : basics-cmake
@ -111,8 +111,8 @@ cat <<EOI >=config.h.in;
#cmakedefine FALSE false #cmakedefine FALSE false
#cmakedefine VALUE @VALUE@ /* @version@ */ #cmakedefine VALUE @VALUE@ /* @version@ */
#cmakedefine HAVE_TEST_DUMMY1_H @HAVE_TEST_DUMMY1_H@ #cmakedefine zzz_TEST_DUMMY1_H @zzz_TEST_DUMMY1_H@
#cmakedefine HAVE_TEST_DUMMY2_H #cmakedefine zzz_TEST_DUMMY2_H
EOI EOI
$* <<EOI &config.h &config.h.d; $* <<EOI &config.h &config.h.d;
./: h{config}: in{config} ./: h{config}: in{config}
@ -134,7 +134,7 @@ $* <<EOI &config.h &config.h.d;
#endif #endif
' '
HAVE_TEST_DUMMY2_H = '#define HAVE_TEST_DUMMY2_H 2' zzz_TEST_DUMMY2_H = '#define zzz_TEST_DUMMY2_H 2'
} }
EOI EOI
cat config.h >>EOO cat config.h >>EOO
@ -162,8 +162,8 @@ cat config.h >>EOO
#undef FALSE #undef FALSE
#define VALUE 123 /* 1.2.3 */ #define VALUE 123 /* 1.2.3 */
#define HAVE_TEST_DUMMY1_H 1 #define zzz_TEST_DUMMY1_H 1
#define HAVE_TEST_DUMMY2_H 2 #define zzz_TEST_DUMMY2_H 2
EOO EOO
: basics-meson : basics-meson
@ -184,8 +184,8 @@ cat <<EOI >=config.h.in;
#mesondefine CUSTOM_LINE #mesondefine CUSTOM_LINE
#mesondefine CUSTOM_BLOCK #mesondefine CUSTOM_BLOCK
#mesondefine HAVE_TEST_DUMMY1_H #mesondefine zzz_TEST_DUMMY1_H
#mesondefine HAVE_TEST_DUMMY2_H #mesondefine zzz_TEST_DUMMY2_H
EOI EOI
$* <<EOI &config.h &config.h.d; $* <<EOI &config.h &config.h.d;
./: h{config}: in{config} ./: h{config}: in{config}
@ -207,7 +207,7 @@ $* <<EOI &config.h &config.h.d;
#endif #endif
' '
HAVE_TEST_DUMMY2_H = '#define HAVE_TEST_DUMMY2_H 2' zzz_TEST_DUMMY2_H = '#define zzz_TEST_DUMMY2_H 2'
} }
EOI EOI
cat config.h >>EOO cat config.h >>EOO
@ -227,6 +227,6 @@ cat config.h >>EOO
# define CUSTOM 123 # define CUSTOM 123
#endif #endif
#define HAVE_TEST_DUMMY1_H 1 #define zzz_TEST_DUMMY1_H 1
#define HAVE_TEST_DUMMY2_H 2 #define zzz_TEST_DUMMY2_H 2
EOO EOO

View File

@ -1,3 +1,4 @@
# Generated version header. # Generated sources.
# #
version.hxx checks.?xx

View File

@ -4,7 +4,78 @@ impl_libs = # Implementation dependencies.
import impl_libs += build2%lib{build2} # Implied interface dependency. import impl_libs += build2%lib{build2} # Implied interface dependency.
import impl_libs += build2%lib{build2-in} import impl_libs += build2%lib{build2-in}
lib{build2-autoconf}: {hxx ixx txx cxx}{**} $impl_libs $intf_libs lib{build2-autoconf}: {hxx ixx txx cxx}{* -checks} {hxx cxx}{checks} \
$impl_libs $intf_libs
# - File name must be the exact variable name plus .h (used for sorting).
# - First line in the file should be `// <NAME>`.
# - No double-quote or backslash escaping except for line continuations.
#
# NOTE: remember to update README.md if changing anything here.
#
<{hxx cxx}{checks}>: checks/file{*.h}
{
install = false
backlink = true
}
{{
diag gen ($>[1])
# We have to sort without the extension.
#
i = $regex.apply($sort($base($path($<))), '(.+)', '\1.h')
h = $path($>[0])
s = $path($>[1])
# We regularize the output with a dummy start entry plus add two end dummies
# that are used in tests.
#
n = $size($<)
n += 3
cat <<"EOI" >$h
namespace build2
{
namespace autoconf
{
struct check
{
const char* name;
const char* value;
};
extern const check checks[$n];
}
}
EOI
cat <<"EOI" >$s
#include <libbuild2/autoconf/checks.hxx>
const build2::autoconf::check build2::autoconf::checks[$n] = {
{\"\", \"\"
EOI
# @@ TODO: add \n once sed supports it.
#
cat $i | sed -n \
-e 's|^// ([^ ]+) *$|},{"\1",|p' \
-e 's|^(.*)\\$|"\1\\\\\\n"|p' \
-e 's|^(.*)$|"\1\\n"|p' \
- >>$s
cat <<EOI >>$s
},
{"zzz_TEST_DUMMY1_H",
"#define zzz_TEST_DUMMY1_H 1"
},
{"zzz_TEST_DUMMY2_H",
"#define zzz_TEST_DUMMY2_H 1"
}
};
EOI
}}
# Build options. # Build options.
# #

View File

@ -0,0 +1,2 @@
// HAVE_STDLIB_H
#define HAVE_STDLIB_H 1

View File

@ -0,0 +1,9 @@
// HAVE_STRLCAT
#if defined(__FreeBSD__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__) || \
defined(__APPLE__)
# define HAVE_STRLCAT 1
#else
# undef HAVE_STRLCAT
#endif

View File

@ -0,0 +1,9 @@
// HAVE_STRLCPY
#if defined(__FreeBSD__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__) || \
defined(__APPLE__)
# define HAVE_STRLCPY 1
#else
# undef HAVE_STRLCPY
#endif

View File

@ -0,0 +1,2 @@
// STDC_HEADERS
#define STDC_HEADERS 1

View File

@ -0,0 +1,2 @@
// const
#undef const

View File

@ -0,0 +1,2 @@
// inline
#undef inline

View File

@ -0,0 +1,2 @@
// volatile
#undef volatile

View File

@ -4,6 +4,8 @@
#include <libbuild2/algorithm.hxx> #include <libbuild2/algorithm.hxx>
#include <libbuild2/diagnostics.hxx> #include <libbuild2/diagnostics.hxx>
#include <libbuild2/autoconf/checks.hxx>
using namespace std; using namespace std;
namespace build2 namespace build2
@ -364,19 +366,6 @@ namespace build2
in::rule::process (l, a, t, dd, dd_skip, s, b, nl, sym, strict, null); in::rule::process (l, a, t, dd, dd_skip, s, b, nl, sym, strict, null);
} }
struct check
{
const char* name;
const char* value;
};
// Note: must be sorted.
//
const check checks[] = {
{"HAVE_TEST_DUMMY1_H", "#define HAVE_TEST_DUMMY1_H 1"},
{"HAVE_TEST_DUMMY2_H", "#define HAVE_TEST_DUMMY2_H 1"},
};
string rule:: string rule::
lookup (const location& l, lookup (const location& l,
action a, const target& t, action a, const target& t,