Reputation: 25
I have a library that I am developing the configuration and makefiles for using Autotools suite. The library requires an external library (specifically fftw3) on the system it is being compiled on and I want Autoconf/Automake to automatically find and link/include the external library before/when compiling (Either in configure.ac or Makefile.am).
I currently am just using autoconf "--with-" flags for the user to provide the location of both the library file and the include folder of the external library on their system, but this seems like such a hassle for the user. The library I am building the configure file and makefiles for will be deployed on various shared systems, so it's difficult to assume the necessary external library will always be in the same place.
What's the best way to approach this?
Upvotes: 2
Views: 1715
Reputation: 37777
As fftw3
appears to install *.pc
files, I would use the pkg-config
based macros in configure.ac
similar to
PKG_CHECK_MODULES([FFTW3], [fftw3])
or, if you want to be a little more helpful to people compiling your library, something like
PKG_CHECK_MODULES([FFTW3], [fftw3], [],
[AC_MSG_ERROR([fftw3 devel package not found])])
Of course, this will require pkg-config
to be installed at autoreconf
and configure
time.
If someone happens to have fftw3
installed in an unusual place, they can add the installation directory of the *.pc
files to the PKG_CONFIG_PATH
environment variable.
In the Makefile.am
file where define your libfoo
library, you can then add lines like
libfoo_CFLAGS += $(FFTW3_CFLAGS)
libfoo_LIBADD += $(FFTW3_LIBS)
If you want to catch people early who attempt to run autoreconf
on your source code without having pkg-config
installed, you can add a line to configure.ac
to make sure the PKG_CHECK_MODULES
autoconf m4 macro is defined:
m4_pattern_forbid([PKG_CHECK_MODULES])dnl
This is rearely seen in the wild, though.
The advantage over the builtin AC_CHECK_LIB
& Co macros is that the *.pc
files may define more information. E.g.
[user@host ~]$ pkg-config --libs fftw3
-lfftw3
contains no surprises but
[user@host ~]$ pkg-config --libs fftw3q
-lfftw3q -lquadmath
may contain surprising additional flags. Distribution packages may also have added system specific information there.
IMHO, when a dependency ships *.pc
files, using PKG_CHECK_MDOULE
is very preferable to using AC_CHECK_LIB
.
Upvotes: 1
Reputation: 180201
You may be overthinking this. That libraries may be installed in different places on different systems is not in itself an issue. Development toolchains know about the layouts of the systems on which they are used. The base case is fairly robust; just (for example) ...
AC_CHECK_LIB([fftw3], [fftw_plan_dft])
That will recognize that libfftw3
is available in the search path if indeed it is, and in that case will prepend the appropriate link option to the LIBS
variable and define HAVE_LIBFFTW3
.
An issue arises only if you want to provide for use of libraries that are not in the linker's default search path, or where a different version of the library is found earlier in that path. That's the case for providing --with-foo
options by which the builder can specify a location. But note that it's a somewhat special-case problem, at least when linking against dynamic libraries, because dev libraries are usually installed alongside runtime libraries, and if a dev lib is not found by the static linker at build time, then typically you need some kind of special provision for the runtime lib to be found by the dynamic linker at run time.
Nevertheless, if you want to check a list of possible library locations encoded into configure
, then that can be done relatively easily. The generated configure
is a shell script, and you can write literal code for it into your configure.ac
without too much trouble. For example,
# Preserve the original value of LIBS
LIBS_save=$LIBS
# This is how we will report out the result
FFTW3_LIBS=
# Check the default locations first
AC_CHECK_LIB([fftw3], [fftw_plan_dft], [
# libfftw3 found in the library search path
FFTW3_LIBS=-lfftw3
], [
# libfftw3 not found in the library search path; try some other paths
# make the linker search the chosen path by adding an `-L` option to the LDFLAGS
LDFLAGS_save=$LDFLAGS
for fftw_libdir in
/usr/lib/fftw
/usr/lib/fftw3
/usr/local/lib/fftw3
do
LDFLAGS="${LDFLAGS_save} -L${fftw_libdir}"
AC_CHECK_LIB([fftw3], [fftw_plan_dft], [
# library found
FFTW3_LIBS="-L${fftw_libdir} -lfftw3"
break
])
done
# restore the original LDFLAGS
LDFLAGS=$LDFLAGS_save
])
# restore the original LIBS
LIBS=$LIBS_save
AS_IF([test x = "x${FFTW3_LIBS}"], [
# configure fails if it does not find libfftw3
AC_MSG_ERROR([libfftw3 not found])
])
# Make FFTW3_LIBS an output variable
AC_OUTPUT([FFTW3_LIBS])
Notable characteristics of that code include
LDFLAGS
) and reporting results (LIBS
)AC_CHECK_LIB
AC_CHECK_LIB
is a macro, not a function, so, for example, you can put a break
into its parameters that will exit the loop in which AC_CHECK_LIB
is usedMakefile.am
by adding $(FFTW3_LIBS)
to the appropriate *LIBADD
or *LDADD
variable(s). (Or if you're not using Automake, then by adding it to the link command in whatever manner is suitable.)Of course, you can combine that with using a --with-foo
option to support cases that you do not anticipate (left as an exercise).
Upvotes: 3