Skip to content

Updating configure tests, Makefiles, etc.

John W. Peterson edited this page May 21, 2018 · 12 revisions

Introduction

In order to avoid an explicit dependence on the GNU "autotools" (automake, autoconf, libtool, and friends) packages, we have elected to commit build system files, such as configure, Makefile.in, etc. to the repository. This has the nice end result of allowing git checkouts of libmesh to be easily built on operating systems (like MacOS) that don't come with these tools installed by default, but it also requires a bit more effort/understanding of the build system to be able to update said configuration files.

Set up the libmesh-specific autotools

  1. Before editing configure.ac or any of the m4 files, you will first need to ensure that you are using the same version of the autotools that was used to generate the current versions of all the build files. (Unless you are actually upgrading the versions of automake/autconf/libtool etc., in which case you can disregard this section.) The libmesh source distribution comes with source tarballs of the autotools currently in use by the library. To build them, simply run:

    ./bootstrap --build-autotools
    

    from the top level of the git clone. We strongly recommend working with a git clone rather than a tarball distribution if you are editing the build configuration files!

  2. Once the correct versions of the autotools are built, you will need to ensure they are in your PATH before any other autotools packages you may have installed on your system. You may be able to use modules to handle this PATH manipulation generically, or simply issue the command:

    export PATH=$LIBMESH_ROOT/contrib/autotools/bin:$PATH
    

    in the current shell and/or add it to the appropriate login (.bash_profile, etc.) configuration file.

  3. You can test the libmesh autotools build and installation by running ./bootstrap in the top level of the repository. As long as you have not changed configure.ac or any of the m4 files, you should see no changes to the committed build files as a result of running ./bootstrap. If you see that many of the Makefile.in files have changed, check to make sure that the libmesh-specific autotools are in your PATH, and send an email/open an issue on GitHub if you require additional help.

Modify/add configure tests

After following the setup instructions, you can begin editing and writing your own configure tests. Most of the libmesh-specific configure tests are in the m4 directory. The tests themselves are written in a combination of /bin/sh and m4, a general-purpose macro processor.

As with all shell programming, keep in mind that:

  1. Whitespace characters are syntactically important.
  2. Variables are created in a global namespace.
  3. There is a difference between an unset variable and a variable which is set to the empty string.

Coding by copy and paste is usually the quickest approach for writing new configure tests, but there is also the autoconf-archive which has many pre-existing scripts for configuring standard software packages that should be preferred if possible.

The m4 files in libmesh are loosely organized into individual tests (metis.m4, petsc.m4, glpk.m4, etc.) and composite test files that call individual tests (libmesh_core_features.m4, libmesh_optional_packages.m4, etc.). The order in which the tests are called is controlled by these composite files and, at the repository root, configure.ac itself. When the results of one test depend on another, it is important to ensure that they are called in the correct order. This can be done by inspecting configure.ac and the other composite test files, and by looking at the output of configure, but is often a trial-and-error process.

We strongly recommend using standard Autoconf Macros such as AS_IF, AS_CASE, and AS_ECHO when writing configure tests, rather than writing shell code directly, since the former approach is guaranteed to be portable. Furthermore, if you use an editor which matches opening and closing parentheses such as emacs, deeply nested Autoconf Macros are easier to maintain than the if/then/fi syntax used by POSIX shells.

When writing if-tests in m4 files, prefer && and || syntax to the -a and -o syntax for the reasons listed in this article. Also use the standard method for guarding against empty variables being used in string comparisons, i.e.

AS_IF([( test "x$var1" == "xyes" && test "x$var2" == "xyes" ) || test "x$var3" == "xno"],
      [enablefeature=yes])

Note that the parentheses around the && comparison are required because && and || otherwise have the same precedence in the shell. For non-compound logical comparisons, extra parentheses should not be used:

AS_IF([test "x$var1" == "xyes"],
      [enablefeature=yes])

Commit your changes

Once you have written (and tested, by running configure multiple times and confirming that the new option is correctly supported) it is time to commit your changes. We prefer to add human- and machine-generated changes in separate commits to ease the process of reviewing those changes. Generally speaking, the only files that should contain human-generated changes are Makefile.am, configure.ac, and the various files in the m4 directory. The machine-generated changes will be generally located in the configure, aclocal.m4, and the many Makefile.in files. We generally commit all the changes to machine-generated files with the command

git commit -a -m"Run bootstrap."

Note: you will likely require more than one attempt before all the m4 changes are correct. We recommend squashing all your bootstrap commits into a single commit before creating a PR, although this is not necessary, and not always preferred, in all situations.