typedefs appear in headers, and we need to know which headers we can use before we look inside them.
Functions. Finally we check for functions. These come last because functions have dependencies on the
preceding items: When searching for functions, libraries are needed to correctly link; headers are needed to
find prototypes (this is especially important for C++, which has stricter prototyping rules than C); and
typedefs are needed for those functions that use or return types not built in.
7.
Output. This is done by invoking AC_OUTPUT.8.
This ordering should be considered a rough guideline, and not a list of hard-and-fast rules. Sometimes it is
necessary to interleave tests, either to make 'configure.in' easier to maintain, or because the tests themselves
do need to be in a different order. If your project uses both C and C++, for instance, you might choose to perform
all the C++ checks after all the C checks have been performed, to make 'configure.in' a bit easier to read.
Deciding what to check for is really the central part of writing 'configure.in'. After you have read the
Autoconf reference manual, the "how"s of writing a particular test should be fairly clear. The "when"s might
remain a mysteryand it is just as easy to check for too many things as it is to check for too few.
One notable area of divergence between various Unix-like systems is that the same programs don't exist on all
systems, and, even when they do, they don't always work in the same way. For these problems, we recommend,
when possible, following the advice of the GNU coding standards: Use the most common options from a relatively
limited set of programs. Failing that, try to stick to programs and options specified by POSIX, perhaps augmenting
this approach by doing checks for known problems on platforms you care about.
Checking for tools and their differences is usually a fairly small part of a 'configure' script; more common are
checks for functions, libraries, and the like.
Except for a few core libraries such as 'libc' and, usually, 'libm' and libraries such as 'libX11', which
typically aren't considered system libraries, there is not much agreement about library names or contents between
Unix systems. Still, libraries are easy to handle, because decisions about libraries almost always affect only the
various 'Makefile's. That means that checking for another library typically doesn't require major (or even,
sometimes, any) changes to the source code. Also, because adding a new library test has a small impact on the
development cycleeffectively just rerunning 'configure' and then a relinkyou can effectively adopt a lax
approach to libraries. You can just make things work on the few systems you immediately care about, for instance,
and then handle library changes on an as-needed basis.
Suppose you do end up with a link problem. How do you handle it? The first thing to do is use nm to look through
the system libraries to see whether the missing function exists. If it does, and it is in a library you can use, the
solution is easy: Just add another AC_CHECK_LIB. Note that just finding the function in a library is not enough,
because on some systems, some "standard" libraries are undesirable; 'libucb' is the most common example of a
library that you should avoid.
If you can't find the function in a system library, you have a somewhat more difficult problem: a non-portable
function. There are basically three approaches to a missing function. This chapter discusses functions, but really
these same approaches apply, more or less, to typedefs, structures, and global variables.
The first approach is to write a replacement function and either conditionally compile it, or put it into an
appropriately named file and use AC_REPLACE_FUNCS. For instance, Tcl uses
AC_REPLACE_FUNCS(strstr) to handle systems that have no strstr function.
The second approach is used when there is a similar function with a different name. The idea here is to check for all
the alternatives and then modify your source to use whichever one might exist. The idiom here is to use break in
the second argument to AC_CHECK_FUNCS; this is used both to skip unnecessary tests and to indicate to the
reader that these checks are related. For instance, here is how libgcj checks for inet_aton or inet_addr;
it uses only the first one found:
AC_CHECK_FUNCS(inet_aton inet_addr, break)
Code to use the results of these checks looks something like this:
19
19