If you eat and drink open source, chances are high that you might have downloaded an open source project code, only to see files like: aclocal.m4
, configure.ac
, Makefile.am
, Makefile.in
and what not. You might have also used commands like ./configure
, make
etc but what are these files? Does they really belong to the project you download? Do I need to understand them? In this blog post I look forward to answer all your question, as well as introduce you to not so popular Autotools – A GNU Build System.
Setting up Autotools on Debian?
Before we go ahead and understand what Autotools is, we will try building a HelloWorld package. Lets get started by setting up Autotools on debian machine.
- apt-get install build-essential
- gcc –version (verifying install)
- g++ –version (verifying install)
- apt-get install automake autoconf
You have your environment ready. Lets start packaging the HelloWorld package.
Hello World Source Code
Download full source code from here
We will need to create 5 files for our basic HelloWorld package. Start by creating a directory structure like this:
— HelloWorld
— configure.ac
— Makefile.am
— README
— src
— Makefile.am
— helloworld.c
src/helloworld.c
#include <config.h> #include <stdio.h> int main (void) { puts ("Hello World!"); puts ("This is " PACKAGE_STRING "."); return 0; }
Note we don’t have a config.h
file but still we include it here. In actual config.h
will be autogenerated by the autotools, when we build the package. Similarly, PACKAGE_STRING
will be a pre-defined variable inside config.h
.
src/Makefile.am
bin_PROGRAMS = helloworld hello_SOURCES = helloworld.c
Here we tell the build system to generate a binary named helloworld
using the sources defined below i.e. helloworld.c
Makefile.am
SUBDIRS=src dist_doc_DATA=README
Here we give information about the various sub-directory. For a bigger project you might have a man
directory, data
directory etc. Also we tell the build to package README
file with the build.
README
This is a demonstration HelloWorld package for GNU Automake. Type `info Automake' to read the Automake manual.
configure.ac
AC_INIT([helloworld], [1.0], [[email protected]]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([ Makefile src/Makefile ]) AC_OUTPUT
Don’t leave the post on seeing the above file. We will go through each and every one of them. configure.ac
contains a series of M4 macros that will expand to some shell code to finally generate the configure
script. Autotools have utilities like automake
and autoconf
(details below) which read this file to generate intermediate and final build files. The variables starting with AC_ are Autoconf macros and those starting with AM_ are Automake macros.
- AC_INIT: Initializes autoconf. It takes 3 input parameters: Name of the package, Version of the package and Contact address for bug reports
- AM_INIT_AUTOMAKE: Initializes automake. It can take a number of available input parameters.
-Wall
-Werror
specifically tells automake to turn on all warnings and report them as error. While development we will keep error reporting turned on.foreign
tells automake that this package doesn’t follow GNU standard. As per GNU standards we should also distribute files likeChangeLog
,AUTHORS
and at this stage we don’t want automake to complaint about them. - AC_PROG_CC: This line tells
configure
script to search available C compilers and define variableCC
with its name. Later on many intermediate files will use this variableCC
for building binary files. - AC_CONFIG_HEADERS: It tells the
configure
script to generate aconfig.h
file which is pre-included byhelloworld.c
. Generatedconfig.h
will have content like this:/* config.h. Generated from config.h.in by configure. */ /* config.h.in. Generated from configure.ac by autoheader. */ /* Name of package */ #define PACKAGE "helloworld" /* Define to the address where bug reports for this package should be sent. */ #define PACKAGE_BUGREPORT "[email protected]" /* Define to the full name of this package. */ #define PACKAGE_NAME "helloworld"
- AC_CONFIG_FILES: This tells
configure
script list of files from which it should generate it’s *.in templates. This variable is also used byautomake
utility to know list ofMakefile.am
it should process. (Note: Each directory should have a Makefile.am file and as you keep adding new directories keep adding them to AC_CONFIG_FILES, else build will not consider your new directories while building packages. - AC_OUTPUT: It is a closing command that actually produces the part of the script in charge of creating the files registered with AC_CONFIG_HEADERS and AC_CONFIG_FILES.
Building a Hello World package for distribution
Lets create our first package for distribution.
- cd path/to/helloworld/directory: Migrate to the project directory
- autoreconf –install: This command initiates the build system. You should see something like this as output:
configure.ac:2: installing `./missing' configure.ac:2: installing `./install-sh' src/Makefile.am: installing `./depcomp'
Also if you scan through the
HelloWorld
directory, you will find a lot of new files being generated by the build system. Particularly you will see aMakefile.in
being generated for eachMakefile.am
. Apart from these files of interest areconfigure
andconfig.h.in
. - ./configure: It utilizes *.in files generated by the previous step to build the
Makefile
,src/Makefile
andconfig.h
. You should see something like this on your console:checking for a BSD-compatible install... /usr/bin/install -c checking whether build environment is sane... yes checking for a thread-safe mkdir -p... /bin/mkdir -p checking for gawk... no checking for mawk... mawk checking whether make sets $(MAKE)... yes checking for gcc... gcc
- make
- src/helloworld: This will output this on the console.
Hello World! This is helloworld 1.0.
- make distcheck: This utility finally creates the helloworld-1.0.tar.gz package for distribution. You should see this on your console on running this utility:
================================================ helloworld-1.0 archives ready for distribution: helloworld-1.0.tar.gz ================================================
Installing distributed HelloWorld package
- Copy the generated package into your temp directory and then issue the following commands
- tar -xzvf helloworld-1.0.tar.gz
- cd helloworld-1.0
- ./configure
- make
- make install
make install
will copy the helloworld
binary into the /usr/local/bin
directory. Try running helloworld
from command line and you should see a similar output, as we saw above while building the package. Further it also copies the README
file under /usr/local/share/doc/helloworld
directory. If your built package includes the man
directory, it gets copied to /usr/local/share/man
automatically.
What is Autotools?
Autotools is a build system developed by GNU which helps you distribute your source code across various Unix systems. The files you are wondering about are auto generated by the Autotools.
Autotools is a combination of several utilities made available by GNU, including:
- Autoconf
- Automake
There are many others which can be listed above, but for this blog post we will restrict ourselves to Automake and Autoconf only.
Autoconf
autoconf process files like configure.in
to generate a configure
script. When we run the configure
script, it reads other template files like Makefile.in
to generate a final output file, in this case Makefile
Automake
It reads all Makefile.am
and generate corresponding Makefile.in
, used by the configure
script as described above.
Happy Packaging!
Pingback: GopoDebian » Blog Archive » Getting started with Autotools – GNU Build System on Debian
Your command:
autoreconf –install
SHOULD BE:
autoreconf –i
….cause that’s the one that works!?
Where you have ‘autoreconf -install’
It should really be ‘autoreconf –install’, or as the user below states: ‘autoreconf -i’.