Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to conditionally compile in a autotools project?

I have an autotools project. I wish to exclude some files from the project, if the user configures so during build. For example, if the build is configured with --no-gui , the files related to GUI are not to be included in the build.

  1. What is the standard macro for such a flag in autoconf? Something that could be configured with like --disable-gui?

  2. How to establish the link between this configure option and automake input files?

I have Calcote's introductory book Autotools here. If you can give pointers as to the macros involved, I can look it up in the book or the net.

Thank you,

Elan.

like image 452
Elan Avatar asked Dec 08 '22 22:12

Elan


1 Answers

According to the autoconf manual, the correct way to do this is with an --enable-FEATURE argument to configure. That's done using the macro AC_ARG_ENABLE. The four argument to AC_ARG_ENABLE are, in order, FEATURE, HELP-STRING, ACTION-IF-GIVEN, ACTION-IF-NOT-GIVEN. So in configure.ac:

AC_ARG_ENABLE([gui],
  [AS_HELP_STRING([--disable-gui], [Enable GUI support @<:@check@:>@])],
  [:],
  [enable_gui=check])

AS_HELP_STRING wraps the help string nicely, and the @<:@ and @:>@ are quadrigraphs which expand to [ and ] in the output of ./configure --help. Even though I've specified an empty ACTION-IF-GIVEN, configure will still set enable_gui to yes or no, depending on whether --enable-gui or --disable-gui (which is an alias for --enable-gui=no) was passed.

So the shell variable $enable_gui will be either yes, no or check. This is for the benefit of the poor packagers who make the distribution packages, as it's considered poor form to build optional support based only on a check. See the gentoo article on automagic dependencies, but packagers would prefer for the build to fail than silently not include a wanted feature.

Now, if $enable_gui is yes or check, we want to check for dependencies and fail if we manually enabled the feature. Since I don't know what library your gui depends on, I'm just going to use pkg-config to check for gtk+-2.0. The four arguments to PKG_CHECK_MODULES (provided by the pkg-config package) are, in order, VARIABLE, MODULES, ACTION-IF-FOUND and ACTION-IF-NOT-FOUND:

AS_IF([test "$enable_gui" != "no"],
  [PKG_CHECK_MODULES([GTK],
    [gtk+-2.0],
    [enable_gui=yes],
    [AS_IF([test "$enable_gui" = "yes"],
      [AC_MSG_ERROR([gtk+-2.0 required, but not found.])],
      [enable_gui=no])])])

The reason we use AS_IF instead of just writing a normal shell if-expression is so that autoconf expands anything that an enclosed macro might require (here PKG_CHECK_MODULES internally depends on macros like PKG_PROG_PKG_CONFIG). You can test that this does the right thing in all cases by doing something like ./configure --enable-gui PKG_CONFIG=/bin/false.

Anyway, we've now resolved enable_gui=check into either enable_gui=yes or enable_gui=no. Now we have to pass this to automake. The macro to use is AM_CONDITIONAL. Its arguments are, in order, CONDITIONAL (the name used in Makefile.am) and CONDITION (the shell test to set CONDITIONAL):

AM_CONDITIONAL([ENABLE_GUI], [test "$enable_gui" = "yes"])

Now, we move over to Makefile.am, I'm going to assume a simple program with a couple of optional sources:

# You probably have something real for these.
AM_CFLAGS =
LDADD =

bin_PROGRAMS = elanprog
elanprog_SOURCES = elanprog.c elanfile.c

if ENABLE_GUI
AM_CFLAGS += $(GTK_CFLAGS)
LDADD += $(GTK_LIBS)
elanprog_SOURCES += elangui.c
endif
like image 181
Jack Kelly Avatar answered Jan 18 '23 15:01

Jack Kelly