LinuxSelfhelp.com

Go to the first, previous, next, last section, table of contents.


Writing Tests

If the existing feature tests don't do something you need, you have to write new ones. These macros are the building blocks. They provide ways for other macros to check whether various kinds of features are available and report the results.

This chapter contains some suggestions and some of the reasons why the existing tests are written the way they are. You can also learn a lot about how to write Autoconf tests by looking at the existing ones. If something goes wrong in one or more of the Autoconf tests, this information can help you understand the assumptions behind them, which might help you figure out how to best solve the problem.

These macros check the output of the C compiler system. They do not cache the results of their tests for future use (see section Caching Results), because they don't know enough about the information they are checking for to generate a cache variable name. They also do not print any messages, for the same reason. The checks for particular kinds of C features call these macros and do cache their results and print messages about what they're checking for.

When you write a feature test that could be applicable to more than one software package, the best thing to do is encapsulate it in a new macro. See section Writing Autoconf Macros, for how to do that.

Examining Declarations

The macro AC_TRY_CPP is used to check whether particular header files exist. You can check for one at a time, or more than one if you need several header files to all exist for some purpose.

Macro: AC_TRY_CPP (includes, @ovar{action-if-true}, @ovar{action-if-false})
includes is C or C++ #include statements and declarations, on which shell variable, back quote, and backslash substitutions are performed. (Actually, it can be any C program, but other statements are probably not useful.) If the preprocessor produces no error messages while processing it, run shell commands action-if-true. Otherwise run shell commands action-if-false.

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

Here is how to find out whether a header file contains a particular declaration, such as a typedef, a structure, a structure member, or a function. Use AC_EGREP_HEADER instead of running grep directly on the header file; on some systems the symbol might be defined in another header file that the file you are checking `#include's.

Macro: AC_EGREP_HEADER (pattern, header-file, action-if-found, @ovar{action-if-not-found})
If the output of running the preprocessor on the system header file header-file matches the egrep regular expression pattern, execute shell commands action-if-found, otherwise execute action-if-not-found.

To check for C preprocessor symbols, either defined by header files or predefined by the C preprocessor, use AC_EGREP_CPP. Here is an example of the latter:

AC_EGREP_CPP(yes,
[#ifdef _AIX
  yes
#endif
], is_aix=yes, is_aix=no)

Macro: AC_EGREP_CPP (pattern, program, @ovar{action-if-found}, @ovar{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 egrep regular expression pattern, execute shell commands action-if-found, otherwise execute action-if-not-found.

This macro calls AC_PROG_CPP or AC_PROG_CXXCPP (depending on which language is current, see section Language Choice), if it hasn't been called already.

Examining Syntax

To check for a syntax feature of the C, C++ or Fortran 77 compiler, such as whether it recognizes a certain keyword, use AC_TRY_COMPILE to try to compile a small program that uses that feature. You can also use it to check for structures and structure members that are not present on all systems.

Macro: AC_TRY_COMPILE (includes, function-body, @ovar{action-if-found}, @ovar{action-if-not-found})
Create a C, C++ or Fortran 77 test program (depending on which language is current, see section Language Choice), to see whether a function whose body consists of function-body can be compiled.

For C and C++, includes is any #include statements needed by the code in function-body (includes will be ignored if the currently selected language is Fortran 77). This macro also uses CFLAGS or CXXFLAGS if either C or C++ is the currently selected language, as well as CPPFLAGS, when compiling. If Fortran 77 is the currently selected language then FFLAGS will be used when compiling.

If the file compiles successfully, run shell commands action-if-found, otherwise run action-if-not-found.

This macro does not try to link; use AC_TRY_LINK if you need to do that (see section Examining Libraries).

Examining Libraries

To check for a library, a function, or a global variable, Autoconf configure scripts try to compile and link a small program that uses it. This is unlike Metaconfig, which by default uses nm or ar on the C library to try to figure out which functions are available. Trying to link with the function is usually a more reliable approach because it avoids dealing with the variations in the options and output formats of nm and ar and in the location of the standard libraries. It also allows configuring for cross-compilation or checking a function's runtime behavior if needed. On the other hand, it can be slower than scanning the libraries once.

A few systems have linkers that do not return a failure exit status when there are unresolved functions in the link. This bug makes the configuration scripts produced by Autoconf unusable on those systems. However, some of them can be given options that make the exit status correct. This is a problem that Autoconf does not currently handle automatically. If users encounter this problem, they might be able to solve it by setting LDFLAGS in the environment to pass whatever options the linker needs (for example, @option{-Wl,-dn} on @sc{mips risc/os}).

AC_TRY_LINK is used to compile test programs to test for functions and global variables. It is also used by AC_CHECK_LIB to check for libraries (see section Library Files), by adding the library being checked for to LIBS temporarily and trying to link a small program.

Macro: AC_TRY_LINK (includes, function-body, @ovar{action-if-found}, @ovar{action-if-not-found})
Depending on the current language (see section Language Choice), create a test program to see whether a function whose body consists of function-body can be compiled and linked.

For C and C++, includes is any #include statements needed by the code in function-body (includes will be ignored if the currently selected language is Fortran 77). This macro also uses CFLAGS or CXXFLAGS if either C or C++ is the currently selected language, as well as CPPFLAGS, when compiling. If Fortran 77 is the currently selected language then FFLAGS will be used when compiling. However, both LDFLAGS and LIBS will be used during linking in all cases.

If the file compiles and links successfully, run shell commands action-if-found, otherwise run action-if-not-found.

Macro: AC_TRY_LINK_FUNC (function, @ovar{action-if-found}, @ovar{action-if-not-found})
Depending on the current language (see section Language Choice), create a test program to see whether a program whose body consists of a prototype of and a call to function can be compiled and linked.

If the file compiles and links successfully, run shell commands action-if-found, otherwise run action-if-not-found.

Checking Run Time Behavior

Sometimes you need to find out how a system performs at run time, such as whether a given function has a certain capability or bug. If you can, make such checks when your program runs instead of when it is configured. You can check for things like the machine's endianness when your program initializes itself.

If you really need to test for a run-time behavior while configuring, you can write a test program to determine the result, and compile and run it using AC_TRY_RUN. Avoid running test programs if possible, because this prevents people from configuring your package for cross-compiling.

Running Test Programs

Use the following macro if you need to test run-time behavior of the system while configuring.

Macro: AC_TRY_RUN (program, @ovar{action-if-true}, @ovar{action-if-false}, @ovar{action-if-cross-compiling})
program is the text of a C program, on which shell variable and back quote substitutions are performed. If it compiles and links successfully and returns an exit status of 0 when executed, run shell commands action-if-true. Otherwise, run shell commands action-if-false; the exit status of the program is available in the shell variable `$?'. This macro uses CFLAGS or CXXFLAGS, CPPFLAGS, LDFLAGS, and LIBS when compiling.

If the C compiler being used does not produce executables that run on the system where configure is being run, then the test program is not run. If the optional shell commands action-if-cross-compiling are given, they are run instead. Otherwise, configure prints an error message and exits.

Try to provide a pessimistic default value to use when cross-compiling makes run-time tests impossible. You do this by passing the optional last argument to AC_TRY_RUN. autoconf prints a warning message when creating configure each time it encounters a call to AC_TRY_RUN with no action-if-cross-compiling argument given. You may ignore the warning, though users will not be able to configure your package for cross-compiling. A few of the macros distributed with Autoconf produce this warning message.

To configure for cross-compiling you can also choose a value for those parameters based on the canonical system name (see section Manual Configuration). Alternatively, set up a test results cache file with the correct values for the host system (see section Caching Results).

To provide a default for calls of AC_TRY_RUN that are embedded in other macros, including a few of the ones that come with Autoconf, you can call AC_PROG_CC before running them. Then, if the shell variable cross_compiling is set to `yes', use an alternate method to get the results instead of calling the macros.

Guidelines for Test Programs

Test programs should not write anything to the standard output. They should return 0 if the test succeeds, nonzero otherwise, so that success can be distinguished easily from a core dump or other failure; segmentation violations and other failures produce a nonzero exit status. Test programs should exit, not return, from main, because on some systems (old Suns, at least) the argument to return in main is ignored.

Test programs can use #if or #ifdef to check the values of preprocessor macros defined by tests that have already run. For example, if you call AC_HEADER_STDC, then later on in `configure.ac' you can have a test program that includes an ANSI C header file conditionally:

#if STDC_HEADERS
# include <stdlib.h>
#endif

If a test program needs to use or create a data file, give it a name that starts with `conftest', such as `conftest.data'. The configure script cleans up by running `rm -rf conftest*' after running test programs and if the script is interrupted.

Test Functions

Function declarations in test programs should have a prototype conditionalized for C++. In practice, though, test programs rarely need functions that take arguments.

#ifdef __cplusplus
foo (int i)
#else
foo (i) int i;
#endif

Functions that test programs declare should also be conditionalized for C++, which requires `extern "C"' prototypes. Make sure to not include any header files containing clashing prototypes.

#ifdef __cplusplus
extern "C" void *malloc (size_t);
#else
char *malloc ();
#endif

If a test program calls a function with invalid parameters (just to see whether it exists), organize the program to ensure that it never invokes that function. You can do this by calling it in another function that is never invoked. You can't do it by putting it after a call to exit, because GCC version 2 knows that exit never returns and optimizes out any code that follows it in the same block.

If you include any header files, make sure to call the functions relevant to them with the correct number of arguments, even if they are just 0, to avoid compilation errors due to prototypes. GCC version 2 has internal prototypes for several functions that it automatically inlines; for example, memcpy. To avoid errors when checking for them, either pass them the correct number of arguments or redeclare them with a different return type (such as char).

Systemology

This section aims at presenting some systems and pointers to documentation. It may help you addressing particular problems reported by users.

QNX 4.25
QNX is a realtime operating system running on Intel architecture meant to be scalable from the small embedded systems to hundred processor super-computer. It claims to be POSIX certified. More information is available on the @href{www.qnx.com, QNX home page}, including the @href{http://support.qnx.com/support/docs/qnx4/, QNX man pages}.

Multiple Cases

Some operations are accomplished in several possible ways, depending on the UNIX variant. Checking for them essentially requires a "case statement". Autoconf does not directly provide one; however, it is easy to simulate by using a shell variable to keep track of whether a way to perform the operation has been found yet.

Here is an example that uses the shell variable fstype to keep track of whether the remaining cases need to be checked.

AC_MSG_CHECKING([how to get file system type])
fstype=no
# The order of these tests is important.
AC_TRY_CPP([#include <sys/statvfs.h>
#include <sys/fstyp.h>],
           [AC_DEFINE(FSTYPE_STATVFS) fstype=SVR4])
if test $fstype = no; then
  AC_TRY_CPP([#include <sys/statfs.h>
#include <sys/fstyp.h>],
             [AC_DEFINE(FSTYPE_USG_STATFS) fstype=SVR3])
fi
if test $fstype = no; then
  AC_TRY_CPP([#include <sys/statfs.h>
#include <sys/vmount.h>],
             [AC_DEFINE(FSTYPE_AIX_STATFS) fstype=AIX])
fi
# (more cases omitted here)
AC_MSG_RESULT([$fstype])

Language Choice

Autoconf-generated configure scripts check for the C compiler and its features by default. Packages that use other programming languages (maybe more than one, e.g. C and C++) need to test features of the compilers for the respective languages. The following macros determine which programming language is used in the subsequent tests in `configure.ac'.

Macro: AC_LANG (language)
Do compilation tests using the compiler, preprocessor and file extensions for the specified language.

Supported languages are:

`C'
Do compilation tests using CC and CPP and use extension `.c' for test programs.
`C++'
Do compilation tests using CXX and CXXCPP and use extension `.C' for test programs.
`Fortran 77'
Do compilation tests using F77 and use extension `.f' for test programs.

Macro: AC_LANG_PUSH (language)
Remember the current language (as set by AC_LANG) on a stack, and then select the language. Use this macro and AC_LANG_POP in macros that need to temporarily switch to a particular language.

Macro: AC_LANG_POP (@ovar{language})
Select the language that is saved on the top of the stack, as set by AC_LANG_PUSH, and remove it from the stack.

If given, language specifies the language we just quit. It is a good idea to specify it when it's known (which should be the case...), since Autoconf will detect inconsistencies.

AC_LANG_PUSH(Fortran 77)
# Perform some tests on Fortran 77.
# ...
AC_LANG_POP(Fortran 77)

Macro: AC_REQUIRE_CPP
Ensure that whichever preprocessor would currently be used for tests has been found. Calls AC_REQUIRE (see section Prerequisite Macros) with an argument of either AC_PROG_CPP or AC_PROG_CXXCPP, depending on which language is current.


Go to the first, previous, next, last section, table of contents.