Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Autotools for a new shared library

What I want to do is to create a new shared library called libxxx that links against another shared library called libzzz, this shared library has an independent "pkg-config"-like tool, let's say it's called "zzz-config" which gives the cflags needed by the compilation phase when using the libzzz. What I want to do is:

  • Create configure/makefile, etc.. using autotools like automake, autoconf, etc;
  • It must use the zzz-config script cited above;
  • It must generate automatic dependencies for sources;
  • It must have a mode for building debug (with no optimization) and release (with optimizations) builds;
  • The sources are in C++;
  • It must target for a shared library;
  • It must read sources for a src directory and put compiled files in another directory

I've read almost all available tutorials for autotools but I was not able to figure a way to do that, if you can point some example would be very kindly.

Thank you !

like image 752
Tarantula Avatar asked Sep 13 '26 17:09

Tarantula


1 Answers

It's fairly easy to do this with the autotools. A few things to note: libzzz might provide a macro to do most of the work for you. For example, glib provides a macro named AM_PATH_GLIB_2_0 that is installed along with the library, so that you merely need to invoke it in your configure.ac. (Note that the macro is misnamed, since it stomps on automake's namespace, but that is another issue entirely.) Here's a sample configure.ac and Makefile.am that does what you want (see below for remarks on debug and release builds):

configure.ac:

#                                               -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.

AC_PREREQ([2.66])
AC_INIT([libxxx], [0.0.0], [[email protected]])
AC_CONFIG_SRCDIR([libxxx.cc])
AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([foreign])
LT_INIT
AC_PROG_CXX

# Checks for libraries.
# If libzzz has an autoconf macro use it.  Otherwise:
AC_PATH_PROG([ZZZ_CONFIG],[zzz-config],[none])
AS_IF([test x"$ZZZ_CONFIG" = xnone],[
    AC_MSG_ERROR([zzz-config not found in PATH])
])
CPPFLAGS="$CPPFLAGS $(zzz-config -cflags)"
LIBS="$(zzz-config -libs) $LIBS"  # Totally unnecessary: we're not linking
# If zzz-config is found, we can probably assume that
# libzzz is installed, but check anyway:
AC_CHECK_LIB([zzz],[main],[],[AC_MSG_ERROR([libzzz required])])

# Checks for header files.
AC_CHECK_HEADERS([zzz.h])

AC_CONFIG_FILES([Makefile])
AC_OUTPUT

Makefile.am


lib_LTLIBRARIES = libxxx.la
libxxx_la_SOURCES = libxxx.cc
include_HEADERS = xxx.h
libxxx_la_LDFLAGS = -version-info 0:0:0

In terms of doing debug or release builds, there are lots of ways to do that with the autotools that do not involve editing the build scripts at all. The canonical way to do it is to set CXXFLAGS when you invoke configure (eg pass CXXFLAGS=-O2 CPPFLAGS=-DNDEBUG as arguments to configure to get a release build). You can also set your system up so that everything you install in /usr/local will be a release build by writing those assignments into /usr/local/share/config.site while everything built for install in $HOME will be a debug build by writing 'CXXFLAGS="-g -O0"' into $HOME/share/config.site. You could invoke AC_HEADER_ASSERT in configure.ac if you want to give the user a --disable-assert option at configure time to turn off assertions (but it's really just as easy for the user to put -DNDEBUG into CPPFLAGS). Another nice thing you can do is exploit automake's VPATH builds to configure distinct build directories where each is configured appropriately.

However, if you really feel the need to add the functionality into your build scripts, you can try putting something like this in configure.ac:

AC_ARG_ENABLE([debug],AS_HELP_STRING([--enable-debug],
    [configure a debug build]),
    [CXXFLAGS="$CXXFLAGS -g -O0"])
AC_ARG_ENABLE([release],AS_HELP_STRING([--enable-release],
    [configure a release build]),
    [CPPFLAGS="$CPPFLAGS -DNDEBUG"]
    [CXXFLAGS="$CXXFLAGS -O2"])

Note that this is not reliable and may cause confusion to the user. For example, if the user is using a config.site to set CPPFLAGS to -DDEBUG but invokes --enable-release, then CPPFLAGS will include "-DDEBUG -DNDEBUG". If you try to completely reset CPPFLAGS in response to --enable-release, then the -I flags needed for libzzz will be lost. You can avoid that last problem by AC_SUBST'ing LIBZZZ_CFLAGS and making modifications to Makefile.am, but it really is just easier to educate your user to set CPPFLAGS and CXXFLAGS when they invoke configure.

See more in my answer here: https://stackoverflow.com/a/4680578/140750

like image 53
William Pursell Avatar answered Sep 16 '26 07:09

William Pursell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!