Wednesday, October 14, 2015

Building C++ Application with Boost Library and Autotools in Linux

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:
  1. 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.
  2. 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.


Post a Comment

No comments: