Table of Contents
To extend a module's configure script, an understanding of Autoconf is required. Without this background, it is very difficult to make good changes. Furthermore, trying to write a decent configure script from scratch is nearly impossible without first having read the basic rules of configure script structure. We will not cover those in detail since the Autoconf documentation already addresses these topics.
We will, however, explain the basic structure of (nearly) all the
configure scripts in the Juggler Project. An understanding of this very
simple structure makes editing the configure.in
files much easier. We will also explain a little bit of
sh(1) syntax and the coding conventions used in
configure.in files.
Because there are so many configure.in files,
consistency among all of them is very important. It only takes one
script that does not follow the rules to complicate maintenance of the
entire build.
In this section, we present the basic concepts of
configure.in files in the Juggler Project. It may
be interesting to note that some of the content in this section was
written in mid-1998 and has been copied verbatim. Whether this is an
indication of robustness or stagnation is debatable.
Two types of comments can be used in
configure.in. The first is the relatively
standard “#” comment. Lines beginning with this
character are copied into the final configure script generated by
autoconf(1). The other type is the
m4(1) comment. Lines commented in this way begin
with dnl and are not copied into the configure
script.
The scripting language used in
configure.in is sh(1). All
conditional statements must use the form:
if test "x$some_var" = "xsome_val" ; then ... fi
rather than:
if [ "x$some_var" = "xsome_val" ] ; then ... fi
The brackets are recognized as special characters by
m4(1) and may not be copied into
configure properly.
When performing tests, it is recommended that some extra
character be used to avoid passing any empty strings to the
test(1) command. Some implementations do not deal
well with empty strings when performing comparisons. In the above
code examples, the character 'x' was used at the
beginning of the two strings. While there is still old code in
various configure scripts that do not use this convention, it is
recommended that all new code follow this rule. Furthermore, when
editing legacy code that does not protect the string operands, it is
recommended that the strings be updated accordingly.
When naming variables in configure.in, be
sure to follow the following conventions:
Names for variables that will be set externally (primarily
by command-line options such as --enable-debug)
and not substituted into generated files at the end of execution
are named in all lower-case letters. All other variables are
named in all upper-case letters.
Variables that are not substituted into generated files at the end of the configure script's execution begin with an underscore to imply that they are internal to the script. When referring to these variables, enclose the name in curly braces to clarify it fully. For example:
_some_internal_var='Some value'
[...]
if test [ "x${_some_internal_var}" = "xSome value" ; then
[...]
fiVariables used to preserve an existing variable's value in case it should need to be reset are named and used as follows:
_vjsave_VARIABLE="$VARIABLE"
[...]
if test <Old value needs to be restored> ; then
$VARIABLE="${_vjsave_VARIABLE}"
fiParameters spanning multiple lines may be passed to Autoconf
macros without using backslashes through a special block recognized
by m4(1). Simply enclose the parameter in []'s
and it will be parsed as one parameter. Some macros require the use
of backslashes, however. In these cases, the argument is taken as a
literal list used by sh(1) code. One such macro
is AC_CHECK_HEADERS().
Beyond multi-line arguments, the Autoconf documentation recommends that all parameters passed to macros be enclosed in square brackets. This is to protect the arguments so that m4(1) does not mangle anything in its expansion of the macros. Consider the following examples:
AC_CONFIG_HEADER([vpr/vprDefines.h])
DPP_PREREQ([1.4.107])
DPP_PERL_VER([5.004], , , [AC_MSG_ERROR([*** Perl is required ***])])
AC_CHECK_PROG([MTREE_CMD], [mtree], [mtree], [\$(PERL) \$(scriptdir)/mtree.pl])
DPP_HAVE_GNU_MAKE([3.78], ,
[AC_MSG_ERROR([*** The build system requires GNU make 3.78 or newer ***])])
DPP_BASIC_PROGS([$PLATFORM], [$OS_TYPE])While this does make the code harder to read, it saves a lot
of headache, especially between two different versions of Autoconf.
Unfortunately, not all macro calls are as well-protected as those in
the above example. (Doozer++ has complete argument protection, so errors are
usually caused by misuses in Juggler
configure.in files.) It is recommended that all
new code use square brackets. When editing exiting code, add
brackets when necessary.
Anything that defines preprocessor macros other than those
generated by the Autoconf macros must be defined in the module's
acconfig.h. If they are not defined in this
file, autoheader(1) will complain as it parses
configure.in and finds these customizations.
Follow the existing syntax and layout of
acconfig.h when making additions to it. In
general, additions only have to be made when a new
AC_DEFINE(),
AC_CHECK_TYPE(), etc. line is added to
configure.in.
Autoconf versions since 2.50 discourage the use of
acconfig.h and
autoheader(1). As of this writing, Autoconf
2.13 is still the most commonly available version, and as such, we
cannot update to Autoconf 2.5x conventions. All Juggler Project
configure scripts (and Doozer++) work with both versions.