Autotools Tutorial Part 1 of 3

When using Linux software, it is quite common to compile source code in the classical 3 phases : configure, make and make install. This process relies on GNU autotools.

If you develop a Linux software, you must be aware that users who want to recompile this software will certainly not have the same development environment as yours. They might have a different distribution, different versions of tools and libraries.

So the Makefile delivered with the software must make no assumptions at all that it will run in the same environment as yours. To deal with these potential discrepencies between developer and user, Makefile will be dynamically built by the configuration phase run by configure.

When configure runs, a lot of controls are performed on the current environment, to check if the software will be able to successfully compile in this environment. The configuration phase also detects includes and libraries locations, in order to dynamically build the Makefile that will be adapted to the current environment.

Makefile is built by configure from a Makefile template : Makefile.am.

As a developer you write the Makefile.am template, and let the user generate the final Makefile during the configuration phase. Of course if you are the developer, you generate the Makefile using the same mechanism. The only difference is that this Makefile and the Makefile from another user can be different, each one adapted to its particular situation.

As Makefile is built from Makefile.am, configure is a very complex script automatically built from a configuration template called configure.ac. configure.ac is written by the developer to define what control must be performed, and what variables must be defined in accordance with the local environment.

Let’s take an example : we will make a little Hello World program with autotools.

First let’s make a working directory, and a subdirectory src for sources :

~$ mkdir -p ~/autohello/src
~$ cd ~/autohello/src

The first version of the source code autohello.c is quite classic :

~/autohello/src$ cat autohello.c

/**
 * @file autohello.c
 *
 * This file implements simple hello world program.
 *
 * @author Xxx Yyy 
 */
#include 
#include 
#include "config.h"
#include "autohello-version.h"
int main(int argc, char **argv)
{
    printf("Hello world version %s\n", AUTOHELLO_VERSION_STRING);
    exit(0);
}

Now let us write the Makefile template Makefile.am in ~/autohello/src :

~/autohello/src$ cat Makefile.am

bin_PROGRAMS = autohello
autohello_SOURCES = autohello.c
CLEANFILES = *~
AM_CPPFLAGS = -D_GNU_SOURCE
AM_CFLAGS = -Wall -Werror

and Makefile.am in ~/autohello :

~/autohello/src$ cd ~/autohello
~/autohello$ cat Makefile.am

SUBDIRS = src

Now we have Makefile templates in base directory and in src subdirectory. We need to create the template for configure script, configure.ac :

~/autohello$ cat configure.ac

# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
# Define version major, minor and micro number
m4_define([autohello_version_major], [1])
m4_define([autohello_version_minor], [0])
m4_define([autohello_version_micro], [0])
m4_define([autohello_version],
        [autohello_version_major.autohello_version_minor.autohello_version_micro])
AC_PREREQ([2.63])
AC_INIT([autohello], [autohello_version], [xxx dot yyy at company dot com])
AC_CONFIG_SRCDIR([src/autohello.c])
AC_CONFIG_HEADERS([config.h])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign])
AUTOHELLO_VERSION_MAJOR=autohello_version_major
AUTOHELLO_VERSION_MINOR=autohello_version_minor
AUTOHELLO_VERSION_MICRO=autohello_version_micro
AUTOHELLO_VERSION=autohello_version
AC_SUBST(AUTOHELLO_VERSION_MAJOR)
AC_SUBST(AUTOHELLO_VERSION_MINOR)
AC_SUBST(AUTOHELLO_VERSION_MICRO)
AC_SUBST(AUTOHELLO_VERSION)
# Checks for programs.
AC_PROG_CC
# Checks for header files.
AC_CHECK_HEADERS([stdio.h stdlib.h])
# Generate files
AC_CONFIG_FILES([Makefile
    src/Makefile
    src/autohello-version.h])
AC_OUTPUT

The file ~/autohello/src/autohello-version.h is automatically generated during configuration, based on a template called autohello-version.h.in. Its role is to automatically define the software version in various ways useable in C source code, from versionning numbers specified in configure.ac .

~/autohello$ cd ~/autohello/src
~/autohello/src$ cat autohello-version.h.in :

/**
 * @file autohello-version.h
 * 
 * This header files defines parts if the software version.
 * 
 * @author Xxx Yyy 
 */
  
#ifndef _AUTOHELLO_VERSION_H_
#define _AUTOHELLO_VERSION_H_
/** The major version, (1, if %AUTOHELLO_VERSION is 1.2.3) */
#define AUTOHELLO_VERSION_MAJOR (@AUTOHELLO_VERSION_MAJOR@)
/** The minor version (2, if %AUTOHELLO_VERSION is 1.2.3) */
#define AUTOHELLO_VERSION_MINOR (@AUTOHELLO_VERSION_MINOR@)
/** The micro version (3, if %AUTOHELLO_VERSION is 1.2.3) */
#define AUTOHELLO_VERSION_MICRO (@AUTOHELLO_VERSION_MICRO@)
/** The full version, like 1.2.3 */
#define AUTOHELLO_VERSION        @AUTOHELLO_VERSION@
/** The full version, in string form (suited for string concatenation)
 */
#define AUTOHELLO_VERSION_STRING "@AUTOHELLO_VERSION@"
/** Numerically encoded version, like 0x010203 */
#define AUTOHELLO_VERSION_HEX ((AUTOHELLO_MAJOR_VERSION << 24) |        \
                               (AUTOHELLO_MINOR_VERSION << 16) |        \
                               (AUTOHELLO_MICRO_VERSION << 8)) /** Evaluates to True if the version is greater than @major, @minor and @micro */ #define AUTOHELLO_VERSION_CHECK(major,minor,micro) \ (AUTOHELLO_VERSION_MAJOR > (major) ||               \
     (AUTOHELLO_VERSION_MAJOR == (major) &&             \
      AUTOHELLO_VERSION_MINOR > (minor)) ||             \
     (AUTOHELLO_VERSION_MAJOR == (major) &&             \
      AUTOHELLO_VERSION_MINOR == (minor) &&             \
      AUTOHELLO_VERSION_MICRO >= (micro)))
#endif /* _AUTOHELLO_VERSION_H_ */

The following table summarizes the files we have written, and their role :

DirectoryFileRole
autohelloconfigure.acTemplate for configure script
 Makefile.amTemplate for Makefile (mainly relay to src)
autohello/srcMakefile.amTemplate for Makefile
 autohello-version.h.inTemplate for version definition header
 autohello.cC source code

In the next article we will configure and compile the software.

 

Partager cet article

Partager sur facebook
Partager sur twitter
Partager sur linkedin
Partager sur pinterest
Partager sur print
Partager sur email

UN BLOG DE

CIO Systèmes Embarqués – 1 Rue de la Presse, 42 000 Saint-Étienne – contact@ciose.fr – 04 77 93 34 32 

CIO  Systèmes Embarqués est le nom commercial de la SAS CIO Informatique Industrielle 

CIO Informatique Industrielle © 1991-2020 v3.0

Mentions Légales