How to add and implement configure flags in Autotools?
-
18-09-2019 - |
Question
A portion of our research group's program has auxiliary functionality provided by ctemplate library. On our dated cluster, we can not build the software due to compilation , so I would like to separate this functionality and control whether it is included or not via a configure
flag, such as --disable-ctemplate
.
The software, written in C++, uses the Autotools build system—neither of which I have much experience with. My understanding is that to accomplish this task, I need to do the following:
Add a new flag to the configure script by creating a new
AC_ARG_ENABLE
entry inconfigure.ac
.Add some
#ifdef
(or possibly#ifndef
) statements around the code that uses thectemplate
library, and around any code that calls that code.
I think the first step would look something like this:
AC_ARG_ENABLE(ctemplate,
[ --disable-ctemplate Disable HTML output],
[case "${enableval}" in
yes) ctemplate=false ;;
no) ctemplate=true ;;
*) AC_MSG_ERROR(bad value ${enableval} for --disable-ctemplate) ;;
esac],[ctemplate=true])
AM_CONDITIONAL(NOCTEMPLATE, test x$ctemplate = xfalse)
though I don't know if the logic is correct, since I've adapted this example from examples that used --enable-FLAG
instead of --disable-FLAG
.
For the second step, I'll wrap sections in preprocessor flags such as
#ifndef NOCTEMPLATE
void Class::MethodUsingCtemplate(...)
{
...
}
#endif
Would this correctly "wire up" everything if I did configure --disable-ctemplate
?
Also, will this ensure that the program does not go into the ctemplate
library for compilation? If not, then all of this is for nothing; it's imperative that I can prevent compilation of the ctemplate
library and dependent components.
I'll re-iterate that I'm unfamiliar with both C++ and Autotools; I have taken a very naive first approach at solving this problem. If you have experience in this area, I would really appreciate your corrections and any explanations you could offer.
Solution
Here is the solution that I put together after reading through documentation, tutorials, help threads, mailing lists, etc., and just plain trying things until they worked I could explain why they worked.
In configure.ac
, I placed the following lines of code
# This adds the option of compiling without using the ctemplate library,
# which has proved troublesome for compilation on some platforms
AC_ARG_ENABLE(ctemplate,
[ --disable-ctemplate Disable compilation with ctemplate and HTML output],
[case "${enableval}" in
yes | no ) WITH_CTEMPLATE="${enableval}" ;;
*) AC_MSG_ERROR(bad value ${enableval} for --disable-ctemplate) ;;
esac],
[WITH_CTEMPLATE="yes"]
)
dnl Make sure we register this option with Automake, so we know whether to
dnl descend into ctemplate for more configuration or not
AM_CONDITIONAL([WITH_CTEMPLATE], [test "x$WITH_CTEMPLATE" = "xyes"])
# Define CTEMPLATE in config.h if we're going to compile against it
if test "x$WITH_CTEMPLATE" = "xyes"; then
AC_DEFINE([CTEMPLATE], [], ["build using ctemplate library"])
AC_MSG_NOTICE([ctemplate will be used, HTML output enabled])
else
AC_MSG_NOTICE([ctemplate will not be used, HTML output disabled])
fi
In the next step, I changed the Makefile.am
at the top level to the following:
if WITH_CTEMPLATE
MAYBE_CTEMPLATE = ctemplate
endif
SUBDIRS = boost libgsl $(MAYBE_CTEMPLATE) libutil ...
In lower level Makefile.am
s, I added
if WITH_CTEMPLATE
# some change to the configuration
else
# some other change to the configuration
endif
Finally, I had to make sure that one of the key C++ header files (included by other parts of the code) had the following:
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
config.h
contains any new definitions one creates with AC_DEFINE
, so this file must be included in parts that check whether a macro definition created by this route is defined (or undefined).
This took a lot of time and pushing through frustration on my part; I can only hope documenting this explanation here saves someone else from the same fate.
OTHER TIPS
You're definitely on the right track. Autotools can seem very complicated at first, but one of the advantages is that there are thousands of projects out that have already done what you want to do. All you need to do is find them.
Here is a link to a Google code search for AC_ARG_DISABLE. Go nuts.
To prevent the build from attempting to compile in the ctemplate subdirectory, you'll want to do something like:
if CTEMPLATE SUBDIRS += ctemplate endif
in Makefile.am