In the previous instalment a skeleton Autotools project was created. In this instalment the usage of libraries for the application code will be added. I like putting my application data into libraries as it makes it more convenient to reuse the code, e.g. when doing unit testing (which will be shown in a later instalment).

In this instalment a skeleton setup for handling libraries using Libtool will be presented. At the end the methods to link against the static or dynamic libraries will be shown. The created library will be a very trivial one but the created skeleton should be enough to expand on this.

Necessary files and directories

Libraries by convention reside in a different directory, namely ‘lib’ in your project root directory. This section will create the necessary structure and files.

Create the ‘lib’-directory

From the project root directory issue the following command:

mkdir lib

Create lib/create_hello.h

In the newly created ‘lib’-directory add a file ‘create_hello.h’ with the following contents:

#ifndef CREATE_HELLO_H
#define CREATE_HELLO_H
 
#include <string>
 
std::string create_hello(const char* const addressee);
 
#endif // CREATE_HELLO_H

Create lib/create_hello.cpp

Of course an implementation is needed. Add the file ‘create_hello.cpp’ with the following contents in the ‘lib’-directory:

#include "create_hello.h"
 
std::string create_hello(const char* const addressee)
{
    return std::string("Hello, ") + addressee + "!";
}

Create lib/Makefile.am

The Automake file ‘Makefile.am’ in the ‘lib’-directory has the contents as shown below. It will be responsible for a library named ‘libfoobar’ against which the application can later link statically or dynamically:

1
2
3
4
5
6
7
8
9
10
11
# NH: Define the libraries that are to be build
lib_LTLIBRARIES = libfoobar.la
 
# NH: Compile flags for the library
libfoobar_la_CFLAGS = -Wall -Werror -pedantic -Wextra
 
# NH: The sources that make up the library.
# NH: Do not forget the header files!
libfoobar_la_SOURCES = create_hello.cpp create_hello.h
 
MAINTAINERCLEANFILES = Makefile.in

Change existing files

Several files need to be adjusted to allow the build environment to create the library and to let the application make use of it.

Adjust configure.ac

Just below the macro ‘AC_CONFIG_MACRO_DIR’ add the following macro:

32
33
34
dnl NH: Initialize Libtool providing us with the possibility to build
dnl NH: (shared) libraries more easily.
LT_INIT

The parameters to ‘AC_CONFIG_FILES’ should be extended with the location of the ‘Makefile’ in the ‘lib’-directory:

53
54
55
56
AC_CONFIG_FILES([
    Makefile
    lib/Makefile
    src/Makefile])

Adjust Makefile.am

The top ‘Makefile.am’ should let Automake know that a ‘Makefile.am’ is to be found in the ‘lib’-directory. Adjust the value for ‘SUBDIRS’ as follows:

6
SUBDIRS = lib src

Libtool leaves some cruft which should be removable when calling the ‘maintainer-clean’ target. So adjust the values

12
13
14
15
16
17
18
19
20
MAINTAINERCLEANFILES = \
    aclocal.m4 \
    configure \
    Makefile.in \
    m4/libtool.m4 \
    m4/lt~obsolete.m4 \
    m4/ltoptions.m4 \
    m4/ltsugar.m4 \
    m4/ltversion.m4

Adjust src/Makefile.am

The ‘Makefile.am’ in the ‘src’-directory should have the following contents:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# NH: Define the program to be build
bin_PROGRAMS = foobar
 
# NH: Define the sources that make up the program
foobar_SOURCES = main.cpp
 
# NH: Add the include path to the library to the preprocessor flags
foobar_CPPFLAGS = -I$(top_srcdir)/lib
 
# NH: Set the compile flags
foobar_CFLAGS  = -Wall -Werror -pedantic -Wextra
 
# NH: Let the linker know where taht we want to link to libfoobar
foobar_LDADD = $(top_srcdir)/lib/libfoobar.la
 
MAINTAINERCLEANFILES = Makefile.in

Adjust src/main.cpp

The ‘main.cpp’ file in the ‘src’-directory should look as follows now if we want to use the new library and the function it provides:

1
2
3
4
5
6
7
8
9
10
#include "create_hello.h"
 
#include <iostream>
 
int main()
{
    std::cout << create_hello("World") << std::endl;
 
    return 0;
}

Rebuild and test the current setup

autoreconf -ivf

The following steps will define the default link behaviour, which is most likely to use the dynamic link-library:

./configure && make

If a statically linked application is required just disable dynamic linking:

./configure --disable-shared && make

Run:

src/foobar

This finishes this second instalment. This is all there is to build and use libraries with the GNU Autotools.

Updates

2014-01-13

  • Fixed link to the initial instalment.
  • Fixed some spelling mistakes.
  • Changed the comment prefix to ‘dnl’ instead of ‘#’ as it should be in a M4-based file as configure.ac.

2014-01-14

  • Moved the code to C++ instead of plain C.

2014-01-15

  • Changed the library function to make it testable for the third instalment.