In this post, I'm going to present the steps required to build C++ application which uses Boost library in Linux (x86_64) with the help of GNU autotools. Mind you that I'm using Arch Linux distribution. Therefore, please adjust the prerequisites according to your environment.
Prerequisites
- The usual GCC tools, i.e. g++ compiler, ld linker, etc.
- GNU autotools: autoconf, automake, etc.
- autoconf-archive. This is a set of autoconf macros that will help building Boost applications. In Arch Linux, I used pacman to install it. You need to carry-out similar step in your Unix/Linux installation.
Initializing The Build System
I assume that the source code directory entries look like this:
.
├── configure.ac
├── m4
├── Makefile.am
└── src
├── main.cpp
└── Makefile.am
m4 is an empty directory, configure.ac, Makefile.am, and src/Makefile.am are the boiler-plate code required to initialize the autotools build system. The next section shows you contents of the files. Use autoscan and autoreconf to initialize the autotools build system like so:
- Run autoscan (in the root source code directory) to create configure.scan template file. You need to copy/rename this file to configure.ac and edit it accordingly.
- Run autoreconf to create files required by GNU build tools (GNU make and gcc/g++). The following is how you would run autoreconf to create the files.
$ autoreconf -fvi
Dealing with Boost Modules
Every boost module requires separate dependency library, autoconf macro (in configure.ac) and automake "library entry" (in Makefile.am). Now let's start with configure.ac. Contents of
<ROOT_DIR>/configure.ac is as follows:
# configure.ac
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ([2.69])
AC_INIT([boost_test], [0.0.1], [me@bug.com])
AC_CONFIG_SRCDIR([config.h.in])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
m4_ifdef([AM_SILENT_RULES],
[AM_SILENT_RULES([yes])
])
# Checks for programs.
AC_PROG_CC
AC_PROG_CXX
# Checks for libraries.
AX_BOOST_BASE([1.48],, [AC_MSG_ERROR([This program needs Boost, but it was not found in your system])])
AX_BOOST_SYSTEM
AX_BOOST_DATE_TIME
AX_BOOST_THREAD
# Checks for header files.
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile
src/Makefile])
AC_OUTPUT
TODO: Explain the lines that have something to do with Boost (AX_BOOST_*) in configure.ac
Contents of
<ROOT_DIR>/Makefile.am is as follows:
ACLOCAL_AMFLAGS = -I m4
EXTRA_DIST = bootstrap
SUBDIRS = src
<ROOT_DIR>/src/Makefile.am is as follows:
bin_PROGRAMS = boost_test
AM_CPPFLAGS = $(BOOST_CPPFLAGS)
AM_LDFLAGS = $(BOOST_LDFLAGS)
boost_test_SOURCES = main.cpp
boost_test_LDADD = $(BOOST_SYSTEM_LIB) $(BOOST_THREAD_LIB) $(BOOST_DATE_TIME_LIB)
TODO: Explain the lines that have something to do with Boost in src/Makefile.am -- $(BOOST_CPPFLAGS) $(BOOST_LDFLAGS) $(BOOST_*_LIB)
Contents of
<ROOT_DIR>/src/main.cpp is as follows:
#include <iostream>
#include <boost/thread.hpp>
#include <boost/date_time.hpp>
void workerFunc()
{
boost::posix_time::seconds workTime(3);
std::cout << "Worker: running" << std::endl;
// Pretend to do something useful...
boost::this_thread::sleep(workTime);
std::cout << "Worker: finished" << std::endl;
}
int main(int argc, char *argv[])
{
std::cout << "main: startup" << std::endl;
boost::thread workerThread(workerFunc);
std::cout << "main: waiting for thread" << std::endl;
workerThread.join();
std::cout << "main: done" << std::endl;
return 0;
}
Pay attention that each Boost module is represented by a single header file which also requires autoconf entry in configure.ac and corresponding library dependency in src/Makefile.am
END NOTE: This post is still incomplete. It's published solely for the benefit of those who can understand it quite well from the source code itself.