GNU Build System - Getting Started

Compiling meme

The aim of this article is to get you quickly started with the Autotools. We will learn how to install the necessary tools and the steps to setup a simple "Hello World" project.

Installing Autotools

There is multiple ways you can choose form in order to install Autotools. The easiest way though, is to use your distribution's packaging system.

In my case, I use Fedora 27. For me installing Autotools was as easy as installing two packages:


The command for doing so, was as follows:

# dnf install autoconf automake

If you are using Ubuntu, it's pretty much the same thing. Your command would look something like this.

# apt install autoconf automake

Note: If you encounter difficulties installing Autotools, feel free to send me an email. I will do my best to help you with that. This will also help me improve this article.

Setting up a simple project

Now, what I want you to do is to create a brand new directory, and jump into it. For me, I would like to call it hello-world.

$ mkdir hello-world
$ cd hello-world

And now go ahead and create three empty files inside the directory you just created:

In the main.c file we are going to write a simple "Hello World" program. This is the program I wrote, but you can write whatever your little heart desires.

#include <stdio.h>
#include <stdlib.h>

main (int argc, char** argv)
  printf("Hello world!\n");
  return (EXIT_SUCCESS);

Write your first Autoconf script

Now we will concentrate on how we can build this program using Autotools. We'll start by setting up a simple

AC_INIT([Hello World], [1.0])
AM_INIT_AUTOMAKE([foreign 1.11.1])

"Wow" you might say "what the heck is that!". Just relax, don't panic and let me explain. is essentially a shell script. But the commands above are macros. We'll later run commands that will expand these macros and generate an actual shell script.

  • The AC_INIT macro —as its name suggests— initializes Autoconf. The two parameters we have passed to it are the package name and the version. Other parameters can be passed such as the project email/mailing-list and the website url.

  • The AM_INIT_AUTOMAKE initializes Automake. The foreign option we passed as a parameter tells it to not check for files required in the GNU Coding Standards. If we don't do that it is gonna start yelling at us every time telling as that it didn't find those files. The 1.11.1 stands for the minimum version of Automake required to build the project.

  • AC_PROG_CC looks for a usable C compiler and sets it to a variable called CC that will be used later in the generated Makefile(s).

  • AC_CONFIG_FILES specifies where the generated files should be. In this case we tell it that the generated Makefile should be put in the current directory.

  • Finally the AC_OUTPUT concludes the script. It basically runs the final steps. This one should always be called at the very end.

For more details about these macros you can refer to Autoconf's documentation. Other macros that we didn't use in this example can be found there.

Write your first Automake script

Our first Automake script is as simple as two lines. In your go ahead and write this.

bin_PROGRAMS = hello
hello_SOURCES = main.c

The first line tells Automake that we want to build a program called hello. The second line tells it that the code for that program is in a file called main.c.

Now get back to your command line and if you have Autotools installed correctly, you should be able to call.

$ autoreconf -i

This will generate a bunch of files. One of them is a shell script called configure. Go ahead and run this script.

$ ./configure

Now you can build the project by running.

$ make

If everything went as expected you should have the program hello built in the current directory.

$ ls
aclocal.m4   config.log   Makefile
missing      autom4te.cache  config.status  depcomp  main.c          compile        configure
install-sh     hello
$ ./hello
Hello world!

This was a very basic setup. In other articles we will dig deeper into the GNU Build System.

In order to get the complete code, checkout the getting-started branch in the support repository.

Over and out,