| Autoconf, Automake, and Libtool | ||
|---|---|---|
| <<< Previous | M4 | Next >>> |
With a good grasp of M4 concepts, we may turn our attention to applying these principles to writing configure.in files and new .m4 macro files. There are some differences between writing generic M4 input files and macros within the GNU Autotools framework and these will be covered in this section, along with some useful hints on working within the framework. This section ties in closely with the chapter called Writing New Macros for Autoconf.
Now that you are familiar with the capabilities of M4, you can forget about the names of the built-in M4 macros-they should be avoided in the GNU Autotools framework. Where appropriate, the framework provides a collection of macros that are laid on top of the M4 built-ins. For instance, the macros in the AC_ family are just regular M4 macros that take a number of arguments and rely on an extensive library of AC_ support macros.
Some conventions have grown over the life of the GNU Autotools, mostly as a disciplined way of avoiding M4 pitfalls. These conventions are designed to make your macros more robust, your code easier to read and, most importantly, improve your chances for getting things to work the first time! A brief list of recommended conventions appears below:
Do not use the M4 built-in changequote. Any good macro will already perform sufficient quoting.
Never use the argument macros (e.g. $1) within shell comments and dnl remarks. If such a comment were to be placed within a macro definition, M4 will expand the argument macros leading to strange results. Instead, quote the argument number to prevent unwanted expansion. For instance, you would use $[1] in the comment.
Quote the M4 comment character, #. This can appear often in shell code fragments and can have undesirable effects if M4 ignores any expansions in the text between the # and the next newline.
In general, macros invoked from configure.in should be placed one per line. Many of the GNU Autotools macros conclude their definitions with a dnl to prevent unwanted whitespace from accumulating in configure.
Many of the AC_ macros, and others which emulate their good behavior, permit default values for unspecified arguments. It is considered good style to explicitly show your intention to use an empty argument by using a pair of quotes, such as [].
Always quote the names of macros used within the definitions of other macros.
When writing new macros, generate a small configure.in that uses (and abuses!) the macro--particularly with respect to quoting. Generate a configure script with autoconf and inspect the results.
After writing a new macro or a configure.in template, the generated configure script may not contain what you expect. Frequently this is due to a problem in quoting (see the section called Quoting), but the interactions between macros can be complex. When you consider that the arguments to GNU Autotools macros are often shell scripts, things can get rather hairy. A number of techniques exist for helping you to debug these kinds of problems.
Expansion problems due to over-quoting and under-quoting can be difficult to pinpoint. Autoconf half-heartedly tries to detect this condition by scanning the generated configure script for any remaining invocations of the AC_ and AM_ families of macros. However, this only works for the AC_ and AM_ macros and not for third party macros.
M4 provides a comprehensive facility for tracing expansions. This makes it possible to see how macro arguments are expanded and how a macro is finally expanded. Often, this can be half the battle in discovering if the macro definition or the invocation is at fault. Autoconf 2.15 will include this tracing mechanism. To trace the generation of configure, Autoconf can be invoked like so:
$ autoconf --trace=AC_PROG_CC
|
Autoconf provides fine control over which macros are traced and the format of the trace output. You should refer to the Autoconf manual for further details.
GNU m4 also provides a debugging mode that can be helpful in discovering problems such as infinite recursion. This mode is activated with the -d option. In order to pass options to m4, invoke Autoconf like so:
$ M4='m4 -dV' autoconf
|
Another situation that can arise is the presence of shell syntax errors in the generated configure script. These errors are usually obvious, as the shell will abort configure when the syntax error is encountered. The task of then locating the troublesome shell code in the input files can be potentially quite difficult. If the erroneous shell code appears in configure.in, it should be easy to spot-presumably because you wrote it recently! If the code is imported from a third party macro, though, it may only be present because you invoked that macro. A trick to help locate these kinds of errors is to place some magic text (__MAGIC__) throughout configure.in:
AC_INIT
AC_PROG_CC
__MAGIC__
MY_SUSPECT_MACRO
__MAGIC__
AC_OUTPUT(Makefile)
|
After autoconf has generated configure, you can search through it for the magic text to determine the extremities of the suspect macro. If your erroneous code appears within the magic text markers, you've found the culprit! Don't be afraid to hack up configure. It can easily be regenerated.
Finally, due to an error on your part, m4 may generate a configure script that contains semantic errors. Something as simple as inverted logic may lead to a nonsense test result:
checking for /etc/passwd... no
|
Semantic errors of this kind are usually easy to solve once you can spot them. A fast and simple way of tracing the shell execution is to use the shell's -x and -v options to turn on its own tracing. This can be done by explicitly placing the required set commands into configure.in:
AC_INIT
AC_PROG_CC
set -x -v
MY_BROKEN_MACRO
set +x +v
AC_OUTPUT(Makefile)
|
This kind of tracing is invaluable in debugging shell code containing semantic errors.
| <<< Previous | Home | Next >>> |
| Features of M4 | Up | Writing Portable Bourne Shell |