Translate:

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], [emailid@provider.com]) 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-Werrorspecifically tells automake to turn on all warnings and report them as error. While development we will keep error reporting turned on.foreigntells automake that this package doesn’t follow GNU standard. As per GNU standards we should also distribute files likeChangeLog,AUTHORSand at this stage we don’t want automake to complaint about them. - AC_PROG_CC: This line tells
configurescript to search available C compilers and define variableCCwith its name. Later on many intermediate files will use this variableCCfor building binary files. - AC_CONFIG_HEADERS: It tells the
configurescript to generate aconfig.hfile which is pre-included byhelloworld.c. Generatedconfig.hwill 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 "emailid@provider.com" /* Define to the full name of this package. */ #define PACKAGE_NAME "helloworld"
- AC_CONFIG_FILES: This tells
configurescript list of files from which it should generate it’s *.in templates. This variable is also used byautomakeutility to know list ofMakefile.amit 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
HelloWorlddirectory, you will find a lot of new files being generated by the build system. Particularly you will see aMakefile.inbeing generated for eachMakefile.am. Apart from these files of interest areconfigureandconfig.h.in. - ./configure: It utilizes *.in files generated by the previous step to build the
Makefile,src/Makefileandconfig.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!
Abhi's Weblog is a collection of blog articles written by
[...] not. You might have also used commands like ./configure, make etc but what are these files? More hereDoes they really belong to the project you download? Do I need to understand them? In this blog post [...]