Next: , Previous: , Up: Writing Tests   [Contents][Index]


6.3 Running the Preprocessor

Sometimes one might need to run the preprocessor on some source file. Usually it is a bad idea, as you typically need to compile your project, not merely run the preprocessor on it; therefore you certainly want to run the compiler, not the preprocessor. Resist the temptation of following the easiest path.

Nevertheless, if you need to run the preprocessor, then use AC_PREPROC_IFELSE.

The macros described in this section cannot be used for tests in Erlang, Fortran, or Go, since those languages require no preprocessor.

Macro: AC_PREPROC_IFELSE (input, [action-if-true], [action-if-false])

Run the preprocessor of the current language (see Language Choice) on the input, run the shell commands action-if-true on success, action-if-false otherwise. The input can be made by AC_LANG_PROGRAM and friends.

This macro uses CPPFLAGS, but not CFLAGS, because -g, -O, etc. are not valid options to many C preprocessors.

It is customary to report unexpected failures with AC_MSG_FAILURE. If needed, action-if-true can further access the preprocessed output in the file conftest.i.

For instance:

AC_INIT([Hello], [1.0], [bug-hello@example.org])
AC_DEFINE([HELLO_WORLD], ["Hello, World\n"],
  [Greetings string.])
AC_PREPROC_IFELSE(
   [AC_LANG_PROGRAM([[const char hw[] = "Hello, World\n";]],
                    [[fputs (hw, stdout);]])],
   [AC_MSG_RESULT([OK])],
   [AC_MSG_FAILURE([unexpected preprocessor failure])])

might result in:

checking for gcc... gcc
checking whether the C compiler works... yes
checking for C compiler default output file name... a.out
checking for suffix of executables...
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether the compiler supports GNU C... yes
checking whether gcc accepts -g... yes
checking for gcc option to enable C11 features... -std=gnu11
checking how to run the C preprocessor... gcc -std=gnu11 -E
OK

The macro AC_TRY_CPP (see Obsolete Macros) used to play the role of AC_PREPROC_IFELSE, but double quotes its argument, making it impossible to use it to elaborate sources. You are encouraged to get rid of your old use of the macro AC_TRY_CPP in favor of AC_PREPROC_IFELSE, but, in the first place, are you sure you need to run the preprocessor and not the compiler?

Macro: AC_EGREP_HEADER (pattern, header-file, action-if-found, [action-if-not-found])

If the output of running the preprocessor on the system header file header-file matches the extended regular expression pattern, execute shell commands action-if-found, otherwise execute action-if-not-found.

See below for some problems involving this macro.

Macro: AC_EGREP_CPP (pattern, program, [action-if-found], [action-if-not-found])

program is the text of a C or C++ program, on which shell variable, back quote, and backslash substitutions are performed. If the output of running the preprocessor on program matches the extended regular expression pattern, execute shell commands action-if-found, otherwise execute action-if-not-found.

See below for some problems involving this macro.

AC_EGREP_CPP and AC_EGREP_HEADER should be used with care, as preprocessors can insert line breaks between output tokens. For example, the preprocessor might transform this:

#define MAJOR 2
#define MINOR 23
Version MAJOR . MINOR

into this:

Version
       2
                 .
                   23

Because preprocessors are allowed to insert white space, change escapes in string contants, insert backlash-newline pairs, or do any of a number of things that do not change the meaning of the preprocessed program, it is better to rely on AC_PREPROC_IFELSE than to resort to AC_EGREP_CPP or AC_EGREP_HEADER.


Next: Running the Compiler, Previous: Writing Test Programs, Up: Writing Tests   [Contents][Index]