Chaoran
Chaoran

Reputation: 321

How to tell auto tools to use different implementations in different folders

I have a project that currently uses a communication library for communication. The library is not generic; it only runs on some machines. I want to port my project to be able to use a other libraries for communication. To do that, I defined a abstract layer that has different implementations. These implementations are consists of several files, so I want to group them into different folders.

For example, I might have a implementation that uses tcp, and another uses some system native library for communication. I have a folder tcp and a folder native in my src folder. I want the autotools to use one implementation that is selected at configure time with --with-comm=XXX.

How do I structure the Makefile.am to achieve this? I've read this: Different implementations in different files in autotools, but that one uses only different files for different implementations, but I want to use folders.

Upvotes: 1

Views: 90

Answers (1)

Brett Hale
Brett Hale

Reputation: 22318

You can use the AC_ARG_WITH macro in configure.ac, but it's more appropriate to use AC_ARG_ENABLE for internal, compile-time features. e.g., in configure.ac:

AC_ARG_ENABLE([comm], [AS_HELP_STRING([--enable-comm[[=tcp]]],
                  [specify a communications layer (default=tcp)])],
              , [enable_comm=yes])

enable_comm=`echo $enable_comm` # strip whitespace.

if test "x$enable_comm" = "xyes" || "x$enable_comm" = "xtcp" ; then
  enable_tcp="yes"
elif test "x$enable_comm" = "xnative" ; then
  enable_native="yes"
elif test "x$enable_comm" = "xno" ; then
  ; # ... error message? default to a dummy layer implementation?
else
  AC_MSG_ERROR([unknown option: '$enable_comm' for --enable-comm])
fi

AM_CONDITIONAL([ENABLE_COMM_TCP], [test "x$enable_tcp" = "xyes"])
AM_CONDITIONAL([ENABLE_COMM_NATIVE], [test "x$enable_native" = "xyes"])
...
AC_CONFIG_FILES([src/Makefile])
AC_CONFIG_FILES([src/tcp/Makefile src/native/Makefile])
...
AC_OUTPUT

You can, of course, put whatever you like in the help string, and set defaults differently.

In src/Makefile.am:

if ENABLE_COMM_TCP
COMM_DIR = tcp
endif

if ENABLE_COMM_NATIVE
COMM_DIR = native
endif

SUBDIRS = . $(COMM_DIR) # or '$(COMM_DIR) .' for depth-first order.

There are limitations because of the way automake works. It would be nice to be able to set COMM_DIR through a condition variable, but AFAIK this doesn't work. Furthermore, this approach automatically includes both tcp and native folders in the distribution if you use make dist. There's no need to put either in the EXTRA_DIST list, though it might be a better approach if the number of optional 'layers' becomes unwieldy.


If I understand your comments correctly, then the simple way would be to include the src files in the subdirectory build, so src/tcp/Makefile.am would use:

lib_LTLIBRARIES = libcomm.la
libcomm_la_SOURCES = driver.h driver.c ../comm.h ../wrapper.c ...

I can't remember offhand if comm.h needs to be specified as $(srcdir)/../comm.h for out-of-tree builds to work correctly. src/Makefile.am may or may not need to add comm.h, wrapper.c, etc., to its EXTRA_DIST variable. While this should work, it's not the 'right' way to go about things...


The library proper should be built in src, and that means using convenience libraries in either tcp or native, and letting libtool worry about the rest. e.g., src/Makefile:

lib_LTLIBRARIES = libcomm.la
libcomm_include_HEADERS = comm.h
libcomm_la_SOURCES = comm.h wrapper.c utils.c ...
libcomm_la_LIBADD = ./$(COMM_DIR)/libcomm_layer.la

It will also be necessary to order: SUBDIRS = $(COMM_DIR) .

In src/tcp/Makefile.am

AM_CPPFLAGS += -I$(srcdir)/.. # look for core headers in src

noinst_LTLIBRARIES = libcomm_layer.la # not for installation.
libcomm_layer_la_SOURCES = driver.h driver.c ...
# libcomm_layer_la_LDFLAGS = -static # optional... an archive is preferable.

This is a more future-proof approach as your 'core' and 'layer' libraries become more complex - and they will:)

Upvotes: 2

Related Questions