Using Autotools to Configure, Make, and Install a Program

6 minute read     Updated:

Kasper Siig %     Kasper Siig

Autotools is one of the most widely adopted code packaging and shipping tools available to developers on Linux. While there are alternatives, such as CMake, SCons, and BJam, they don’t quite match Autotools in ease of use, power, and versability.

At its base, Autotools can help make your application more portable, give it the versatility to be installed on many different systems, and can automatically procure scripts to check where elements are, like the compiler for your program. In this article, you will learn how to use Autotools to package up an application and ship it.

Components of Autotools

Autotools is made up of three unique components:

  • autoconf
  • automake
  • aclocal

Using these tools, you will create two files, configure and These files are present in any project shipped using Autotools and are usually quite large and complex. Luckily, you don’t have to write them yourself—instead you’ll be writing the files and, which will automatically generate the files you need.


Autoconf is written in M4sh, using m4 macros. If you’ve heard of this before, then great! If you haven’t, no worries. m4sh provides some macros you can use when creating your script and are part of why you can generate a massive configure script without having to write too much actual code.

The way it works is that you create a script in which you define various settings like release name, version, which compiler to use, and where it should output files. Once you’ve written your script, you run it through autoconf to create your final configure script. The purpose of autoconf is to collect information from your system to populate the template, which is created using automake.


The script creates The principles behind this are the same as with write a simple script in order to create a complex file. Automake is the component you’ll use to create the Makefile, a template that can then be populated with autoconf.

Automake does so using variables and primaries. An example of such a primary is bin_PROGRAMS = helloworld, where the primary is the _PROGRAMS suffix. This primary gives automake some knowledge about your program, like where you want the produced binary to be installed.

In this case, you’re telling automake to install the helloworld binary in the path defined by the bindir. You may notice we didn’t define a bindir variable, because that variable is built into automake and is typically the default binary directory of your system.

Other examples of primaries are _SCRIPTS, which you can use when you want a script, rather than a binary to be installed somewhere, and _DATA, when you have extra data files you want included in your installation. There are many more that you will find once you start using Autotools and figure out what your needs are.

One last thing to mention is that although is special in that it contains all of these primaries, it’s still a regular Makefile. Meaning you can write your own custom make targets if you want. For example, if you want to have a custom clean target that deletes specific files, you can do so easily.


This is the smallest component in the Autotools suite, but it’s very important. You learned in the previous section that autoconf uses m4 macros to be configured. But where do these m4 macros come from? They’re generated by running the aclocal command. Simple as that. If you don’t run aclocal before running autoconf, you’ll get an error complaining about missing macros.

Using Autotools

Now that you know the basic principles of how the Autotools suite is put together, it’s time to see it all in action and create a small C program that you can compile and ship.

Writing the Source Program

The first thing you need is the program you want to compile and ship. Autotools is compatible with many different projects and languages, but for this example you’ll be working in C, which is most commonly used. If you’re not familiar with C, don’t worry, it’s very simple. Here’s your sample code:

#include <stdio.h>

main(int argc, char* argv[])
  printf("Hello World\n");
  return 0;

As you can see, it simply includes a standard in/standard out library and then prints Hello World\n. Let’s start withautoconf to configure this project.


When writing your file, there are a lot of options to choose from. You can get very specific about how you want your script to be configured, but some configurations need to be set. The first of these is AC_INIT. This tells autoconf what the name of your application is, what version it is, and who’s the maintainer. For this example, you’ll write:

AC_INIT([helloworld], [0.1], [])

While autoconf is generally used alongside automake, it’s not necessary, so you need to initialize that by writing:


Now that the generic options are initialized, you can get more specific with what you want. You need to specify what compiler you want the configure script to use. You do this by writing:


This will tell the configure script to look for a C compiler. For other applications, you may need more dependencies to build your program. By using the AC_PATH_PROG macro, you can make autoconf look for specific programs in a user’s PATH. At this point, there are only two steps needed to finish your basic script:


AC_CONFIG_FILES tells autoconf that it should find a file called and replace placeholders according to what we’ve specified. This can be things like version or maintainer. AC_OUTPUT is the last thing you want to put in your script, as it tells autoconf to output the final configure script. In the end, your file should contain the following:

AC_INIT([helloworld], [0.1], [])

Making the Makefile

When using automake, you’ll have to adhere to a set of standards. One of these is that source files for a project are located in the src folder. In this project, you have a single main.c file in our root directory, so you need to tell automake that:


You need to tell automake what you want your compiled binary to be called. In this case, you want it to be called helloworld, so write the following:

bin_PROGRAMS = helloworld

Only one thing left, and that is to tell automake what files are needed to compile your application. Do this by writing:

helloworld_SOURCES = main.c

Notice how the first part is the name of your application followed by the SOURCES primary. Now automake knows all that it needs to know, and your is ready to use.

Creating Final Scripts

Once you’ve written your and, it’s relatively straightforward to distribute your application. Remember to start by running aclocal so you can run autoconf. Once you’ve run autoconf, you can run automake --add-missing to build your

The reason for the --add-missing flag is to tell automake to automatically generate all of the additional files required, as usually you need more than just and would have to manually enter in the other files.

At this point, you have all you need to distribute your program. Before moving on on, here’s a short recap showing the commands you should’ve run by now:

automake --add-missing

Distributing the Program

Distributing your application can seem like a daunting task, but Autotools makes it super easy. All you have to do is run make dist after you’ve run the configure scripts above. This will produce a tarball, which you can then ship to your customers.


Now you’re able to use Autotools to compile and distribute your application, and you’re able to do it in a way that ensures it’s portable across a variety of systems. From here, you can start looking into automating this procedure and other ways to integrate Autotools directly into your daily development.

The great advantage of using something like Autotools is that you’ll be using a system that has been in place for many years, is well-documented, and widely used. Many developers are comfortable installing applications using what Autotools produces, so it can make your application much more familiar and accessible.

If your project becomes more complex and autotools maintenance becomes a burden, earthly is a great solution for containerized builds.

Kasper Siig %

Kasper Siig

As a DevOps engineer, Kasper Siig is used to working with a variety of exciting technologies, from automating simple tasks to CI/CD to Docker.